From 0300ce05d5e7af4584f73115aa590530af0a7655 Mon Sep 17 00:00:00 2001 From: Michael Teeuw Date: Sun, 1 Jan 2023 18:09:08 +0100 Subject: [PATCH] Release 2.22.0 (#2983) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## [2.22.0] - 2023-01-01 Thanks to: @angeldeejay, @buxxi, @dariom, @dWoolridge, @KristjanESPERANTO, @MagMar94, @naveensrinivasan, @retroflex, @SkySails and @Tom. Special thanks to @khassel, @rejas and @sdetweil for taking over most (if not all) of the work on this release as project collaborators. This version would not be there without their effort. Thank you! ### Added - Added test for remoteFile option in compliments module - Added hourlyWeather functionality to Weather.gov weather provider - Removed weatherEndpoint definition from weathergov.js (not used) - Added css class names "today" and "tomorrow" for default calendar - Added Collaboration.md - Added new github action for dependency review (#2862) - Added a WeatherProvider for Open-Meteo - Added Yr as a weather provider - Added config options "ignoreXOriginHeader" and "ignoreContentSecurityPolicy" ### Removed - Removed usage of internal fetch function of node until it is more stable ### Updated - Cleaned up test directory (#2937) and jest config (#2959) - Wait for all modules to start before declaring the system ready (#2487) - Updated e2e tests (moved `done()` in helper functions) and use es6 syntax in all tests - Updated da translation - Rework weather module - Make sure smhi provider api only gets a maximum of 6 digits coordinates (#2955) - Use fetch instead of XMLHttpRequest in weatherprovider (#2935) - Reworked how weatherproviders handle units (#2849) - Use unix() method for parsing times, fix suntimes on the way (#2950) - Refactor conversion functions into utils class (#2958) - The `cors`-method in `server.js` now supports sending and recieving HTTP headers - Replace `…` by `…` - Cleanup compliments module - Updated dependencies including electron to v22 (#2903) ### Fixed - Correctly show apparent temperature in SMHI weather provider - Ensure updatenotification module isn't shown when local is _ahead_ of remote - Handle node_helper errors during startup (#2944) - Possibility to change FontAwesome class in calendar, so icons like `fab fa-facebook-square` works. - Fix cors problems with newsfeed articles (as far as possible), allow disabling cors per feed with option `useCorsProxy: false` (#2840) - Tests not waiting for the application to start and stop before starting the next test - Fix electron tests failing sometimes in github workflow - Fixed gap in clock module when displayed on the left side with displayType=digital - Fixed playwright issue by upgrading to v1.29.1 (#2969) Signed-off-by: naveen <172697+naveensrinivasan@users.noreply.github.com> Co-authored-by: Karsten Hassel Co-authored-by: Malte Hallström <46646495+SkySails@users.noreply.github.com> Co-authored-by: Veeck Co-authored-by: veeck Co-authored-by: dWoolridge Co-authored-by: Johan Co-authored-by: Dario Mratovich Co-authored-by: Dario Mratovich Co-authored-by: Magnus <34011212+MagMar94@users.noreply.github.com> Co-authored-by: Naveen <172697+naveensrinivasan@users.noreply.github.com> Co-authored-by: buxxi Co-authored-by: Thomas Hirschberger <47733292+Tom-Hirschberger@users.noreply.github.com> Co-authored-by: Kristjan ESPERANTO <35647502+KristjanESPERANTO@users.noreply.github.com> Co-authored-by: Andrés Vanegas Jiménez <142350+angeldeejay@users.noreply.github.com> --- .github/workflows/depsreview.yaml | 14 + .gitignore | 1 - .prettierignore | 1 - CHANGELOG.md | 72 +- Collaboration.md | 12 + jest.config.js | 32 + js/app.js | 39 +- js/electron.js | 14 + js/fetch.js | 30 +- js/main.js | 2 +- js/server.js | 182 +- js/server_functions.js | 127 + modules/default/calendar/calendar.js | 58 +- modules/default/clock/clock.js | 12 +- modules/default/compliments/compliments.js | 81 +- modules/default/newsfeed/newsfeed.js | 17 +- modules/default/newsfeed/newsfeedfetcher.js | 6 +- modules/default/newsfeed/node_helper.js | 4 +- .../default/updatenotification/git_helper.js | 20 +- modules/default/utils.js | 147 + modules/default/weather/current.njk | 10 +- modules/default/weather/providers/darksky.js | 18 +- .../default/weather/providers/envcanada.js | 79 +- .../default/weather/providers/openmeteo.js | 537 ++ .../weather/providers/openweathermap.js | 78 +- modules/default/weather/providers/smhi.js | 27 +- .../default/weather/providers/ukmetoffice.js | 63 +- .../weather/providers/ukmetofficedatahub.js | 66 +- .../default/weather/providers/weatherbit.js | 14 +- .../default/weather/providers/weatherflow.js | 49 +- .../default/weather/providers/weathergov.js | 134 +- modules/default/weather/providers/yr.js | 626 ++ modules/default/weather/weather.js | 21 +- modules/default/weather/weatherobject.js | 44 +- modules/default/weather/weatherprovider.js | 56 +- modules/default/weather/weatherutils.js | 98 + package-lock.json | 5373 +++++++---------- package.json | 86 +- tests/configs/data/en.json | 33 - tests/configs/default.js | 2 +- .../configs/modules/calendar/auth-default.js | 2 +- tests/configs/modules/calendar/basic-auth.js | 2 +- .../configs/modules/calendar/changed-port.js | 2 +- tests/configs/modules/calendar/custom.js | 2 +- tests/configs/modules/calendar/default.js | 2 +- .../modules/calendar/fail-basic-auth.js | 2 +- .../modules/calendar/old-basic-auth.js | 2 +- tests/configs/modules/calendar/recurring.js | 2 +- .../modules/compliments/compliments_date.js | 1 - .../modules/compliments/compliments_remote.js | 21 + tests/configs/modules/newsfeed/default.js | 2 +- .../configs/modules/newsfeed/ignore_items.js | 2 +- .../modules/newsfeed/prohibited_words.js | 2 +- tests/configs/modules/positions.js | 2 +- .../modules/weather/currentweather_options.js | 2 +- tests/e2e/env_spec.js | 35 +- tests/e2e/{fonts.js => fonts_spec.js} | 19 +- tests/e2e/{modules => helpers}/basic-auth.js | 10 +- tests/e2e/{ => helpers}/global-setup.js | 52 +- tests/e2e/{ => helpers}/mock-console.js | 4 +- tests/e2e/helpers/weather-functions.js | 29 + tests/e2e/ipWhitelist_spec.js | 37 +- tests/e2e/modules/alert_spec.js | 18 +- tests/e2e/modules/calendar_spec.js | 147 +- tests/e2e/modules/clock_es_spec.js | 58 +- tests/e2e/modules/clock_spec.js | 103 +- tests/e2e/modules/compliments_spec.js | 103 +- tests/e2e/modules/helloworld_spec.js | 34 +- tests/e2e/modules/mocks/index.js | 4 - tests/e2e/modules/mocks/weather_current.js | 64 - tests/e2e/modules/newsfeed_spec.js | 96 +- tests/e2e/modules/weather_current_spec.js | 84 + tests/e2e/modules/weather_forecast_spec.js | 96 + tests/e2e/modules/weather_spec.js | 273 - tests/e2e/modules_display_spec.js | 30 +- tests/e2e/modules_empty_spec.js | 23 + tests/e2e/modules_position_spec.js | 18 +- tests/e2e/port_config.js | 36 - tests/e2e/port_spec.js | 31 + tests/e2e/translations_spec.js | 58 +- tests/e2e/vendor_spec.js | 29 +- tests/e2e/without_modules.js | 27 - tests/electron/env_spec.js | 44 +- tests/electron/helpers/global-setup.js | 46 + tests/electron/helpers/weather-setup.js | 29 + tests/electron/modules/calendar_spec.js | 32 + tests/electron/modules/compliments_spec.js | 45 + tests/electron/modules/weather_spec.js | 28 + .../{configs/data => mocks}/calendar_test.ics | 0 .../data => mocks}/calendar_test_icons.ics | 0 .../calendar_test_recurring.ics | 0 tests/mocks/compliments_test.json | 3 + .../newsfeed_test.xml} | 0 .../translation_test.json} | 2 +- .../weather_test.js} | 67 +- tests/unit/classes/class_spec.js | 34 +- tests/unit/classes/deprecated_spec.js | 6 +- tests/unit/classes/translator_spec.js | 120 +- tests/unit/classes/utils_spec.js | 14 +- tests/unit/functions/calendar_spec.js | 50 +- tests/unit/functions/cmp_versions_spec.js | 14 +- tests/unit/functions/newsfeed_spec.js | 15 - tests/unit/functions/server_functions_spec.js | 149 + .../unit/functions/updatenotification_spec.js | 24 +- tests/unit/functions/weather_object_spec.js | 27 +- .../unit/global_vars/defaults_modules_spec.js | 4 +- tests/unit/global_vars/root_path_spec.js | 10 +- tests/unit/modules/default/utils_spec.js | 111 + translations/af.json | 2 +- translations/bg.json | 2 +- translations/ca.json | 2 +- translations/cs.json | 2 +- translations/cv.json | 2 +- translations/cy.json | 2 +- translations/da.json | 4 +- translations/el.json | 2 +- translations/en.json | 2 +- translations/es.json | 2 +- translations/et.json | 2 +- translations/fi.json | 2 +- translations/fr.json | 2 +- translations/fy.json | 2 +- translations/gl.json | 2 +- translations/gu.json | 2 +- translations/hi.json | 2 +- translations/hr.json | 2 +- translations/hu.json | 2 +- translations/id.json | 2 +- translations/is.json | 2 +- translations/it.json | 2 +- translations/ja.json | 2 +- translations/ko.json | 2 +- translations/lt.json | 2 +- translations/ms-my.json | 2 +- translations/nb.json | 2 +- translations/nl.json | 2 +- translations/nn.json | 2 +- translations/pl.json | 2 +- translations/pt-br.json | 2 +- translations/pt.json | 2 +- translations/ro.json | 2 +- translations/ru.json | 2 +- translations/sk.json | 2 +- translations/sv.json | 2 +- translations/tlh.json | 2 +- translations/tr.json | 2 +- translations/uk.json | 2 +- translations/zh-cn.json | 2 +- translations/zh-tw.json | 2 +- vendor/package-lock.json | 36 +- vendor/package.json | 4 +- 151 files changed, 5895 insertions(+), 4954 deletions(-) create mode 100644 .github/workflows/depsreview.yaml create mode 100644 Collaboration.md create mode 100644 jest.config.js create mode 100644 js/server_functions.js create mode 100644 modules/default/utils.js create mode 100644 modules/default/weather/providers/openmeteo.js create mode 100644 modules/default/weather/providers/yr.js create mode 100644 modules/default/weather/weatherutils.js delete mode 100644 tests/configs/data/en.json create mode 100644 tests/configs/modules/compliments/compliments_remote.js rename tests/e2e/{fonts.js => fonts_spec.js} (67%) rename tests/e2e/{modules => helpers}/basic-auth.js (72%) rename tests/e2e/{ => helpers}/global-setup.js (55%) rename tests/e2e/{ => helpers}/mock-console.js (93%) create mode 100644 tests/e2e/helpers/weather-functions.js delete mode 100644 tests/e2e/modules/mocks/index.js delete mode 100644 tests/e2e/modules/mocks/weather_current.js create mode 100644 tests/e2e/modules/weather_current_spec.js create mode 100644 tests/e2e/modules/weather_forecast_spec.js delete mode 100644 tests/e2e/modules/weather_spec.js create mode 100644 tests/e2e/modules_empty_spec.js delete mode 100644 tests/e2e/port_config.js create mode 100644 tests/e2e/port_spec.js delete mode 100644 tests/e2e/without_modules.js create mode 100644 tests/electron/helpers/global-setup.js create mode 100644 tests/electron/helpers/weather-setup.js create mode 100644 tests/electron/modules/calendar_spec.js create mode 100644 tests/electron/modules/compliments_spec.js create mode 100644 tests/electron/modules/weather_spec.js rename tests/{configs/data => mocks}/calendar_test.ics (100%) rename tests/{configs/data => mocks}/calendar_test_icons.ics (100%) rename tests/{configs/data => mocks}/calendar_test_recurring.ics (100%) create mode 100644 tests/mocks/compliments_test.json rename tests/{configs/data/feed_test_rodrigoramirez.xml => mocks/newsfeed_test.xml} (100%) rename tests/{configs/data/TranslationTest.json => mocks/translation_test.json} (95%) rename tests/{e2e/modules/mocks/weather_forecast.js => mocks/weather_test.js} (72%) delete mode 100644 tests/unit/functions/newsfeed_spec.js create mode 100644 tests/unit/functions/server_functions_spec.js create mode 100644 tests/unit/modules/default/utils_spec.js diff --git a/.github/workflows/depsreview.yaml b/.github/workflows/depsreview.yaml new file mode 100644 index 0000000000..745f4c5eee --- /dev/null +++ b/.github/workflows/depsreview.yaml @@ -0,0 +1,14 @@ +name: "Dependency Review" +on: [pull_request] + +permissions: + contents: read + +jobs: + dependency-review: + runs-on: ubuntu-latest + steps: + - name: "Checkout Repository" + uses: actions/checkout@v3 + - name: "Dependency Review" + uses: actions/dependency-review-action@v2 diff --git a/.gitignore b/.gitignore index a01770258f..861213ce73 100644 --- a/.gitignore +++ b/.gitignore @@ -16,7 +16,6 @@ vendor/node_modules/**/* jspm_modules .npm .node_repl_history -.nyc_output/ # Visual Studio Code ignoramuses. .vscode/ diff --git a/.prettierignore b/.prettierignore index c092da9b22..b92f216692 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,3 @@ /config /coverage -.nyc_output package-lock.json diff --git a/CHANGELOG.md b/CHANGELOG.md index 137453d0d3..54d38a5783 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,30 +5,82 @@ 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.22.0] - 2023-01-01 + +Thanks to: @angeldeejay, @buxxi, @dariom, @dWoolridge, @KristjanESPERANTO, @MagMar94, @naveensrinivasan, @retroflex, @SkySails and @Tom. + +Special thanks to @khassel, @rejas and @sdetweil for taking over most (if not all) of the work on this release as project collaborators. This version would not be there without their effort. Thank you! + +### Added + +- Added test for remoteFile option in compliments module +- Added hourlyWeather functionality to Weather.gov weather provider +- Removed weatherEndpoint definition from weathergov.js (not used) +- Added css class names "today" and "tomorrow" for default calendar +- Added Collaboration.md +- Added new github action for dependency review (#2862) +- Added a WeatherProvider for Open-Meteo +- Added Yr as a weather provider +- Added config options "ignoreXOriginHeader" and "ignoreContentSecurityPolicy" + +### Removed + +- Removed usage of internal fetch function of node until it is more stable + +### Updated + +- Cleaned up test directory (#2937) and jest config (#2959) +- Wait for all modules to start before declaring the system ready (#2487) +- Updated e2e tests (moved `done()` in helper functions) and use es6 syntax in all tests +- Updated da translation +- Rework weather module + - Make sure smhi provider api only gets a maximum of 6 digits coordinates (#2955) + - Use fetch instead of XMLHttpRequest in weatherprovider (#2935) + - Reworked how weatherproviders handle units (#2849) + - Use unix() method for parsing times, fix suntimes on the way (#2950) + - Refactor conversion functions into utils class (#2958) +- The `cors`-method in `server.js` now supports sending and recieving HTTP headers +- Replace `…` by `…` +- Cleanup compliments module +- Updated dependencies including electron to v22 (#2903) + +### Fixed + +- Correctly show apparent temperature in SMHI weather provider +- Ensure updatenotification module isn't shown when local is _ahead_ of remote +- Handle node_helper errors during startup (#2944) +- Possibility to change FontAwesome class in calendar, so icons like `fab fa-facebook-square` works. +- Fix cors problems with newsfeed articles (as far as possible), allow disabling cors per feed with option `useCorsProxy: false` (#2840) +- Tests not waiting for the application to start and stop before starting the next test +- Fix electron tests failing sometimes in github workflow +- Fixed gap in clock module when displayed on the left side with displayType=digital +- Fixed playwright issue by upgrading to v1.29.1 (#2969) + ## [2.21.0] - 2022-10-01 Special thanks to: @BKeyport, @buxxi, @davide125, @khassel, @kolbyjack, @krukle, @MikeBishop, @rejas, @sdetweil, @SkySails and @veeck -## Added +### Added -- Possibility to fetch calendars through socket notifications. +- Added possibility to fetch calendars through socket notifications. - New scripts `install-mm` (and `install-mm:dev`) for simplifying mm installation (now: `npm run install-mm`) and adding params `--no-audit --no-fund --no-update-notifier` for less noise. - New `showTimeToday` option in calendar module shows time for current-day events even if `timeFormat` is `"relative"`. -- Add hourly forecasts, apparent temperature & custom location name to SMHI weather provider. +- Added hourly forecasts, apparent temperature & custom location name to SMHI weather provider. +- Added new electron tests for calendar and moved some compliments tests from `e2e` to `electron` because of date mocking, removed mock stuff from compliments module. -## Removed +### Removed -- Old weather deprecated modules `currentweather` and `weatherforecast`. +- Removed old and deprecated weather modules `currentweather` and `weatherforecast`. +- Removed `DAYAFTERTOMORROW` from English. -## Updated +### Updated -- Removed `DAYAFTERTOMORROW` from English. -- Update dependencies. +- Updated dependencies. - Updated jsdoc. -- Updated font tree to use variables consistantly. +- Updated font tree to use variables consistently. - Removed deprecated Docker Repository from issue template. -## Fixed +### Fixed - Broadcast all calendar events while still honoring global and per-calendar maximumEntries. - Respect rss ttl provided by newsfeed (#2883). diff --git a/Collaboration.md b/Collaboration.md new file mode 100644 index 0000000000..6be3fecb2a --- /dev/null +++ b/Collaboration.md @@ -0,0 +1,12 @@ +This document describes how collaborators of this repository should work together. + +## Pull Requests + +- never merge your own PR's +- never merge without someone having approved (approving and merging from same person is allowed) +- wait for all approvals requested (or the author decides something different in the comments) + +## Issues + +- "real" Issues are closed if the problem is solved and the fix is released +- unrelated Issues (e.g. related to a foreign module) are closed immediately with a comment to open an issue in the module repository or to discuss this further in the forum or discord diff --git a/jest.config.js b/jest.config.js new file mode 100644 index 0000000000..a36db006fc --- /dev/null +++ b/jest.config.js @@ -0,0 +1,32 @@ +module.exports = async () => { + return { + verbose: true, + testTimeout: 20000, + testSequencer: "/tests/configs/test_sequencer.js", + projects: [ + { + displayName: "unit", + moduleNameMapper: { + logger: "/js/logger.js" + }, + testMatch: ["**/tests/unit/**/*.[jt]s?(x)"], + testPathIgnorePatterns: ["/tests/unit/mocks"] + }, + { + displayName: "electron", + testMatch: ["**/tests/electron/**/*.[jt]s?(x)"], + testPathIgnorePatterns: ["/tests/electron/helpers/"] + }, + { + displayName: "e2e", + setupFilesAfterEnv: ["/tests/e2e/helpers/mock-console.js"], + testMatch: ["**/tests/e2e/**/*.[jt]s?(x)"], + modulePaths: ["/js/"], + testPathIgnorePatterns: ["/tests/e2e/helpers/", "/tests/e2e/mocks"] + } + ], + collectCoverageFrom: ["./clientonly/**/*.js", "./js/**/*.js", "./modules/**/*.js", "./serveronly/**/*.js"], + coverageReporters: ["lcov", "text"], + coverageProvider: "v8" + }; +}; diff --git a/js/app.js b/js/app.js index c3d6b214de..ae2d76f4df 100644 --- a/js/app.js +++ b/js/app.js @@ -222,18 +222,33 @@ function App() { } } - loadModules(modules, function () { - httpServer = new Server(config, function (app, io) { - Log.log("Server started ..."); - - for (let nodeHelper of nodeHelpers) { - nodeHelper.setExpressApp(app); - nodeHelper.setSocketIO(io); - nodeHelper.start(); + loadModules(modules, async function () { + httpServer = new Server(config); + const { app, io } = await httpServer.open(); + Log.log("Server started ..."); + + const nodePromises = []; + for (let nodeHelper of nodeHelpers) { + nodeHelper.setExpressApp(app); + nodeHelper.setSocketIO(io); + + try { + nodePromises.push(nodeHelper.start()); + } catch (error) { + Log.error(`Error when starting node_helper for module ${nodeHelper.name}:`); + Log.error(error); } + } - Log.log("Sockets connected & modules started ..."); + Promise.allSettled(nodePromises).then((results) => { + // Log errors that happened during async node_helper startup + results.forEach((result) => { + if (result.status === "rejected") { + Log.error(result.reason); + } + }); + Log.log("Sockets connected & modules started ..."); if (typeof callback === "function") { callback(config); } @@ -247,14 +262,16 @@ function App() { * exists. * * Added to fix #1056 + * + * @param {Function} callback Function to be called after the app has stopped */ - this.stop = function () { + this.stop = function (callback) { for (const nodeHelper of nodeHelpers) { if (typeof nodeHelper.stop === "function") { nodeHelper.stop(); } } - httpServer.close(); + httpServer.close().then(callback); }; /** diff --git a/js/electron.js b/js/electron.js index ffa48e6a74..ac58657c30 100644 --- a/js/electron.js +++ b/js/electron.js @@ -103,6 +103,20 @@ function createWindow() { }, 1000); }); } + + //remove response headers that prevent sites of being embedded into iframes if configured + mainWindow.webContents.session.webRequest.onHeadersReceived((details, callback) => { + let curHeaders = details.responseHeaders; + if (config["ignoreXOriginHeader"] || false) { + curHeaders = Object.fromEntries(Object.entries(curHeaders).filter((header) => !/x-frame-options/i.test(header[0]))); + } + + if (config["ignoreContentSecurityPolicy"] || false) { + curHeaders = Object.fromEntries(Object.entries(curHeaders).filter((header) => !/content-security-policy/i.test(header[0]))); + } + + callback({ responseHeaders: curHeaders }); + }); } // This method will be called when Electron has finished diff --git a/js/fetch.js b/js/fetch.js index fb855f2ac2..3ae874c813 100644 --- a/js/fetch.js +++ b/js/fetch.js @@ -1,20 +1,28 @@ /** - * fetch + * Helper class to provide either third party fetch library or (if node >= 18) + * return internal node fetch implementation. * + * Attention: After some discussion we always return the third party + * implementation until the node implementation is stable and more tested + * + * @see https://github.com/MichMich/MagicMirror/pull/2952 + * @see https://github.com/MichMich/MagicMirror/issues/2649 * @param {string} url to be fetched * @param {object} options object e.g. for headers * @class */ -async function fetch(url, options) { - const nodeVersion = process.version.match(/^v(\d+)\.*/)[1]; - if (nodeVersion >= 18) { - // node version >= 18 - return global.fetch(url, options); - } else { - // node version < 18 - const nodefetch = require("node-fetch"); - return nodefetch(url, options); - } +async function fetch(url, options = {}) { + // const nodeVersion = process.version.match(/^v(\d+)\.*/)[1]; + // if (nodeVersion >= 18) { + // // node version >= 18 + // return global.fetch(url, options); + // } else { + // // node version < 18 + // const nodefetch = require("node-fetch"); + // return nodefetch(url, options); + // } + const nodefetch = require("node-fetch"); + return nodefetch(url, options); } module.exports = fetch; diff --git a/js/main.js b/js/main.js index 9d3a50b36b..3eed494bff 100644 --- a/js/main.js +++ b/js/main.js @@ -70,7 +70,7 @@ const MM = (function () { * Select the wrapper dom object for a specific position. * * @param {string} position The name of the position. - * @returns {HTMLElement} the wrapper element + * @returns {HTMLElement | void} the wrapper element */ const selectWrapper = function (position) { const classes = position.replace("_", " "); diff --git a/js/server.js b/js/server.js index 27d1caef1c..3aa246b5c1 100644 --- a/js/server.js +++ b/js/server.js @@ -5,136 +5,114 @@ * MIT Licensed. */ const express = require("express"); -const app = require("express")(); const path = require("path"); const ipfilter = require("express-ipfilter").IpFilter; const fs = require("fs"); const helmet = require("helmet"); -const fetch = require("fetch"); const Log = require("logger"); const Utils = require("./utils.js"); +const { cors, getConfig, getHtml, getVersion } = require("./server_functions.js"); /** * Server * * @param {object} config The MM config - * @param {Function} callback Function called when done. * @class */ -function Server(config, callback) { +function Server(config) { + const app = express(); const port = process.env.MM_PORT || config.port; const serverSockets = new Set(); - let server = null; - if (config.useHttps) { - const options = { - key: fs.readFileSync(config.httpsPrivateKey), - cert: fs.readFileSync(config.httpsCertificate) - }; - server = require("https").Server(options, app); - } else { - server = require("http").Server(app); - } - const io = require("socket.io")(server, { - cors: { - origin: /.*$/, - credentials: true - }, - 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"); - - if (config.ipWhitelist instanceof Array && config.ipWhitelist.length === 0) { - Log.warn(Utils.colors.warn("You're using a full whitelist configuration to allow for all IPs")); - } - - app.use(function (req, res, next) { - ipfilter(config.ipWhitelist, { mode: config.ipWhitelist.length === 0 ? "deny" : "allow", log: false })(req, res, function (err) { - if (err === undefined) { - res.header("Access-Control-Allow-Origin", "*"); - return next(); - } - Log.log(err.message); - res.status(403).send("This device is not allowed to access your mirror.
Please check your config.js or config.js.sample to change this."); - }); - }); - app.use(helmet(config.httpHeaders)); - - app.use("/js", express.static(__dirname)); - const directories = ["/config", "/css", "/fonts", "/modules", "/vendor", "/translations", "/tests/configs"]; - for (const directory of directories) { - app.use(directory, express.static(path.resolve(global.root_path + directory))); - } - - app.get("/cors", async function (req, res) { - // example: http://localhost:8080/cors?url=https://google.de - - try { - const reg = "^/cors.+url=(.*)"; - let url = ""; - - let match = new RegExp(reg, "g").exec(req.url); - if (!match) { - url = "invalid url: " + req.url; - Log.error(url); - res.send(url); + /** + * Opens the server for incoming connections + * + * @returns {Promise} A promise that is resolved when the server listens to connections + */ + this.open = function () { + return new Promise((resolve) => { + if (config.useHttps) { + const options = { + key: fs.readFileSync(config.httpsPrivateKey), + cert: fs.readFileSync(config.httpsCertificate) + }; + server = require("https").Server(options, app); } else { - url = match[1]; - Log.log("cors url: " + url); - const response = await fetch(url, { headers: { "User-Agent": "Mozilla/5.0 MagicMirror/" + global.version } }); - const header = response.headers.get("Content-Type"); - const data = await response.text(); - if (header) res.set("Content-Type", header); - res.send(data); + server = require("http").Server(app); + } + const io = require("socket.io")(server, { + cors: { + origin: /.*$/, + credentials: true + }, + 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"); + + if (config.ipWhitelist instanceof Array && config.ipWhitelist.length === 0) { + Log.warn(Utils.colors.warn("You're using a full whitelist configuration to allow for all IPs")); } - } catch (error) { - Log.error(error); - res.send(error); - } - }); - app.get("/version", function (req, res) { - res.send(global.version); - }); + app.use(function (req, res, next) { + ipfilter(config.ipWhitelist, { mode: config.ipWhitelist.length === 0 ? "deny" : "allow", log: false })(req, res, function (err) { + if (err === undefined) { + res.header("Access-Control-Allow-Origin", "*"); + return next(); + } + Log.log(err.message); + res.status(403).send("This device is not allowed to access your mirror.
Please check your config.js or config.js.sample to change this."); + }); + }); + + app.use(helmet(config.httpHeaders)); + app.use("/js", express.static(__dirname)); + + // TODO add tests directory only when running tests? + const directories = ["/config", "/css", "/fonts", "/modules", "/vendor", "/translations", "/tests/configs", "/tests/mocks"]; + for (const directory of directories) { + app.use(directory, express.static(path.resolve(global.root_path + directory))); + } - app.get("/config", function (req, res) { - res.send(config); - }); + app.get("/cors", async (req, res) => await cors(req, res)); - app.get("/", function (req, res) { - let html = fs.readFileSync(path.resolve(`${global.root_path}/index.html`), { encoding: "utf8" }); - html = html.replace("#VERSION#", global.version); + app.get("/version", (req, res) => getVersion(req, res)); - let configFile = "config/config.js"; - if (typeof global.configuration_file !== "undefined") { - configFile = global.configuration_file; - } - html = html.replace("#CONFIG_FILE#", configFile); + app.get("/config", (req, res) => getConfig(req, res)); - res.send(html); - }); + app.get("/", (req, res) => getHtml(req, res)); - if (typeof callback === "function") { - callback(app, io); - } + server.on("listening", () => { + resolve({ + app, + io + }); + }); + }); + }; + /** + * Closes the server and destroys all lingering connections to it. + * + * @returns {Promise} A promise that resolves when server has successfully shut down + */ this.close = function () { - for (const socket of serverSockets.values()) { - socket.destroy(); - } - server.close(); + return new Promise((resolve) => { + for (const socket of serverSockets.values()) { + socket.destroy(); + } + server.close(resolve); + }); }; } diff --git a/js/server_functions.js b/js/server_functions.js new file mode 100644 index 0000000000..f210a8b848 --- /dev/null +++ b/js/server_functions.js @@ -0,0 +1,127 @@ +const fetch = require("./fetch"); +const fs = require("fs"); +const path = require("path"); +const Log = require("logger"); + +/** + * Gets the config. + * + * @param {Request} req - the request + * @param {Response} res - the result + */ +function getConfig(req, res) { + res.send(config); +} + +/** + * A method that forewards HTTP Get-methods to the internet to avoid CORS-errors. + * + * Example input request url: /cors?sendheaders=header1:value1,header2:value2&expectedheaders=header1,header2&url=http://www.test.com/path?param1=value1 + * + * Only the url-param of the input request url is required. It must be the last parameter. + * + * @param {Request} req - the request + * @param {Response} res - the result + */ +async function cors(req, res) { + try { + const urlRegEx = "url=(.+?)$"; + let url = ""; + + const match = new RegExp(urlRegEx, "g").exec(req.url); + if (!match) { + url = "invalid url: " + req.url; + Log.error(url); + res.send(url); + } else { + url = match[1]; + + const headersToSend = getHeadersToSend(req.url); + const expectedRecievedHeaders = geExpectedRecievedHeaders(req.url); + + Log.log("cors url: " + url); + const response = await fetch(url, { headers: headersToSend }); + + for (const header of expectedRecievedHeaders) { + const headerValue = response.headers.get(header); + if (header) res.set(header, headerValue); + } + const data = await response.text(); + res.send(data); + } + } catch (error) { + Log.error(error); + res.send(error); + } +} + +/** + * Gets headers and values to attatch to the web request. + * + * @param {string} url - The url containing the headers and values to send. + * @returns {object} An object specifying name and value of the headers. + */ +function getHeadersToSend(url) { + const headersToSend = { "User-Agent": "Mozilla/5.0 MagicMirror/" + global.version }; + const headersToSendMatch = new RegExp("sendheaders=(.+?)(&|$)", "g").exec(url); + if (headersToSendMatch) { + const headers = headersToSendMatch[1].split(","); + for (const header of headers) { + const keyValue = header.split(":"); + if (keyValue.length !== 2) { + throw new Error(`Invalid format for header ${header}`); + } + headersToSend[keyValue[0]] = decodeURIComponent(keyValue[1]); + } + } + return headersToSend; +} + +/** + * Gets the headers expected from the response. + * + * @param {string} url - The url containing the expected headers from the response. + * @returns {string[]} headers - The name of the expected headers. + */ +function geExpectedRecievedHeaders(url) { + const expectedRecievedHeaders = ["Content-Type"]; + const expectedRecievedHeadersMatch = new RegExp("expectedheaders=(.+?)(&|$)", "g").exec(url); + if (expectedRecievedHeadersMatch) { + const headers = expectedRecievedHeadersMatch[1].split(","); + for (const header of headers) { + expectedRecievedHeaders.push(header); + } + } + return expectedRecievedHeaders; +} + +/** + * Gets the HTML to display the magic mirror. + * + * @param {Request} req - the request + * @param {Response} res - the result + */ +function getHtml(req, res) { + let html = fs.readFileSync(path.resolve(`${global.root_path}/index.html`), { encoding: "utf8" }); + html = html.replace("#VERSION#", global.version); + + let configFile = "config/config.js"; + if (typeof global.configuration_file !== "undefined") { + configFile = global.configuration_file; + } + html = html.replace("#CONFIG_FILE#", configFile); + + res.send(html); +} + +/** + * Gets the MagicMirror version. + * + * @param {Request} req - the request + * @param {Response} res - the result + */ +function getVersion(req, res) { + res.send(global.version); +} + +module.exports = { cors, getConfig, getHtml, getVersion }; diff --git a/modules/default/calendar/calendar.js b/modules/default/calendar/calendar.js index 134a84ce58..cecf80ea12 100644 --- a/modules/default/calendar/calendar.js +++ b/modules/default/calendar/calendar.js @@ -14,6 +14,7 @@ Module.register("calendar", { limitDays: 0, // Limit the number of days shown, 0 = no limit displaySymbol: true, defaultSymbol: "calendar-alt", // Fontawesome Symbol see https://fontawesome.com/cheatsheet?from=io + defaultSymbolClassName: "fas fa-fw fa-", showLocation: false, displayRepeatingCountTitle: false, defaultRepeatingCountTitle: "", @@ -163,11 +164,10 @@ Module.register("calendar", { // Override dom generator. getDom: function () { - // Define second, minute, hour, and day constants - const oneSecond = 1000; // 1,000 milliseconds - const oneMinute = oneSecond * 60; - const oneHour = oneMinute * 60; - const oneDay = oneHour * 24; + const ONE_SECOND = 1000; // 1,000 milliseconds + const ONE_MINUTE = ONE_SECOND * 60; + const ONE_HOUR = ONE_MINUTE * 60; + const ONE_DAY = ONE_HOUR * 24; const events = this.createEventList(true); const wrapper = document.createElement("table"); @@ -205,6 +205,8 @@ Module.register("calendar", { if (lastSeenDate !== dateAsString) { const dateRow = document.createElement("tr"); dateRow.className = "normal"; + if (event.today) dateRow.className += " today"; + else if (event.tomorrow) dateRow.className += " tomorrow"; const dateCell = document.createElement("td"); dateCell.colSpan = "3"; @@ -230,6 +232,8 @@ Module.register("calendar", { } eventWrapper.className = "normal event"; + if (event.today) eventWrapper.className += " today"; + else if (event.tomorrow) eventWrapper.className += " tomorrow"; const symbolWrapper = document.createElement("td"); @@ -244,7 +248,7 @@ Module.register("calendar", { const symbols = this.symbolsForEvent(event); symbols.forEach((s, index) => { const symbol = document.createElement("span"); - symbol.className = "fas fa-fw fa-" + s; + symbol.className = s; if (index > 0) { symbol.style.paddingLeft = "5px"; } @@ -338,7 +342,7 @@ Module.register("calendar", { // For full day events we use the fullDayEventDateFormat if (event.fullDayEvent) { //subtract one second so that fullDayEvents end at 23:59:59, and not at 0:00:00 one the next day - event.endDate -= oneSecond; + event.endDate -= ONE_SECOND; timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").format(this.config.fullDayEventDateFormat)); } else if (this.config.getRelative > 0 && event.startDate < now) { // Ongoing and getRelative is set @@ -348,7 +352,7 @@ Module.register("calendar", { timeUntilEnd: moment(event.endDate, "x").fromNow(true) }) ); - } else if (this.config.urgency > 0 && event.startDate - now < this.config.urgency * oneDay) { + } else if (this.config.urgency > 0 && event.startDate - now < this.config.urgency * ONE_DAY) { // Within urgency days timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow()); } @@ -356,9 +360,9 @@ Module.register("calendar", { // Full days events within the next two days if (event.today) { timeWrapper.innerHTML = this.capFirst(this.translate("TODAY")); - } else if (event.startDate - now < oneDay && event.startDate - now > 0) { + } else if (event.startDate - now < ONE_DAY && event.startDate - now > 0) { timeWrapper.innerHTML = this.capFirst(this.translate("TOMORROW")); - } else if (event.startDate - now < 2 * oneDay && event.startDate - now > 0) { + } else if (event.startDate - now < 2 * ONE_DAY && event.startDate - now > 0) { if (this.translate("DAYAFTERTOMORROW") !== "DAYAFTERTOMORROW") { timeWrapper.innerHTML = this.capFirst(this.translate("DAYAFTERTOMORROW")); } @@ -367,7 +371,7 @@ Module.register("calendar", { } else { // Show relative times if (event.startDate >= now || (event.fullDayEvent && event.today)) { - // Use relative time + // Use relative time if (!this.config.hideTime && !event.fullDayEvent) { timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").calendar(null, { sameElse: this.config.dateFormat })); } else { @@ -384,14 +388,14 @@ Module.register("calendar", { // Full days events within the next two days if (event.today) { timeWrapper.innerHTML = this.capFirst(this.translate("TODAY")); - } else if (event.startDate - now < oneDay && event.startDate - now > 0) { + } else if (event.startDate - now < ONE_DAY && event.startDate - now > 0) { timeWrapper.innerHTML = this.capFirst(this.translate("TOMORROW")); - } else if (event.startDate - now < 2 * oneDay && event.startDate - now > 0) { + } else if (event.startDate - now < 2 * ONE_DAY && event.startDate - now > 0) { if (this.translate("DAYAFTERTOMORROW") !== "DAYAFTERTOMORROW") { timeWrapper.innerHTML = this.capFirst(this.translate("DAYAFTERTOMORROW")); } } - } else if (event.startDate - now < this.config.getRelative * oneHour) { + } else if (event.startDate - now < this.config.getRelative * ONE_HOUR) { // If event is within getRelative hours, display 'in xxx' time format or moment.fromNow() timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").fromNow()); } @@ -421,6 +425,8 @@ Module.register("calendar", { if (event.location !== false) { const locationRow = document.createElement("tr"); locationRow.className = "normal xsmall light"; + if (event.today) locationRow.className += " today"; + else if (event.tomorrow) locationRow.className += " tomorrow"; if (this.config.displaySymbol) { const symbolCell = document.createElement("td"); @@ -491,6 +497,11 @@ Module.register("calendar", { * @returns {object[]} Array with events. */ createEventList: function (limitNumberOfEntries) { + const ONE_SECOND = 1000; // 1,000 milliseconds + const ONE_MINUTE = ONE_SECOND * 60; + const ONE_HOUR = ONE_MINUTE * 60; + const ONE_DAY = ONE_HOUR * 24; + const now = new Date(); const today = moment().startOf("day"); const future = moment().startOf("day").add(this.config.maximumNumberOfDays, "days").toDate(); @@ -521,19 +532,21 @@ Module.register("calendar", { } } event.url = calendarUrl; - event.today = event.startDate >= today && event.startDate < today + 24 * 60 * 60 * 1000; + event.today = event.startDate >= today && event.startDate < today + ONE_DAY; + event.tomorrow = !event.today && event.startDate >= today + ONE_DAY && event.startDate < today + 2 * ONE_DAY; /* if sliceMultiDayEvents is set to true, multiday events (events exceeding at least one midnight) are sliced into days, * otherwise, esp. in dateheaders mode it is not clear how long these events are. */ - const maxCount = Math.ceil((event.endDate - 1 - moment(event.startDate, "x").endOf("day").format("x")) / (1000 * 60 * 60 * 24)) + 1; + const maxCount = Math.ceil((event.endDate - 1 - moment(event.startDate, "x").endOf("day").format("x")) / ONE_DAY) + 1; if (this.config.sliceMultiDayEvents && maxCount > 1) { const splitEvents = []; let midnight = moment(event.startDate, "x").clone().startOf("day").add(1, "day").format("x"); let count = 1; while (event.endDate > midnight) { const thisEvent = JSON.parse(JSON.stringify(event)); // clone object - thisEvent.today = thisEvent.startDate >= today && thisEvent.startDate < today + 24 * 60 * 60 * 1000; + thisEvent.today = thisEvent.startDate >= today && thisEvent.startDate < today + ONE_DAY; + thisEvent.tomorrow = !thisEvent.today && thisEvent.startDate >= today + ONE_DAY && thisEvent.startDate < today + 2 * ONE_DAY; thisEvent.endDate = midnight; thisEvent.title += " (" + count + "/" + maxCount + ")"; splitEvents.push(thisEvent); @@ -544,6 +557,8 @@ Module.register("calendar", { } // Last day event.title += " (" + count + "/" + maxCount + ")"; + event.today += event.startDate >= today && event.startDate < today + ONE_DAY; + event.tomorrow = !event.today && event.startDate >= today + ONE_DAY && event.startDate < today + 2 * ONE_DAY; splitEvents.push(event); for (let splitEvent of splitEvents) { @@ -757,6 +772,11 @@ Module.register("calendar", { getCalendarPropertyAsArray: function (url, property, defaultValue) { let p = this.getCalendarProperty(url, property, defaultValue); + if (property === "symbol" || property === "recurringSymbol" || property === "fullDaySymbol") { + const className = this.getCalendarProperty(url, "symbolClassName", this.config.defaultSymbolClassName); + p = className + p; + } + if (!(p instanceof Array)) p = [p]; return p; }, @@ -794,7 +814,7 @@ Module.register("calendar", { line++; if (line > maxTitleLines - 1) { if (i < words.length) { - currentLine += "…"; + currentLine += "…"; } break; } @@ -811,7 +831,7 @@ Module.register("calendar", { return (temp + currentLine).trim(); } else { if (maxLength && typeof maxLength === "number" && string.length > maxLength) { - return string.trim().slice(0, maxLength) + "…"; + return string.trim().slice(0, maxLength) + "…"; } else { return string.trim(); } diff --git a/modules/default/clock/clock.js b/modules/default/clock/clock.js index 7c9310f008..31922a5809 100644 --- a/modules/default/clock/clock.js +++ b/modules/default/clock/clock.js @@ -303,7 +303,7 @@ Module.register("clock", { } /******************************************* - * Update placement, respect old analogShowDate even if its not needed anymore + * Update placement, respect old analogShowDate even if it's not needed anymore */ if (this.config.displayType === "analog") { // Display only an analog clock @@ -311,16 +311,16 @@ Module.register("clock", { wrapper.classList.add("clockGrid--bottom"); } else if (this.config.analogShowDate === "bottom") { wrapper.classList.add("clockGrid--top"); - } else { - //analogWrapper.style.gridArea = "center"; } + wrapper.appendChild(analogWrapper); + } else if (this.config.displayType === "digital") { + wrapper.appendChild(digitalWrapper); } else if (this.config.displayType === "both") { wrapper.classList.add("clockGrid--" + this.config.analogPlacement); + wrapper.appendChild(analogWrapper); + wrapper.appendChild(digitalWrapper); } - wrapper.appendChild(analogWrapper); - wrapper.appendChild(digitalWrapper); - // Return the wrapper to the dom. return wrapper; } diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index c116829534..a1fffb8455 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -21,8 +21,7 @@ Module.register("compliments", { morningEndTime: 12, afternoonStartTime: 12, afternoonEndTime: 17, - random: true, - mockDate: null + random: true }, lastIndexUsed: -1, // Set currentweather from module @@ -40,7 +39,7 @@ Module.register("compliments", { this.lastComplimentIndex = -1; if (this.config.remoteFile !== null) { - this.complimentFile((response) => { + this.loadComplimentFile().then((response) => { this.config.compliments = JSON.parse(response); this.updateDom(); }); @@ -85,30 +84,30 @@ Module.register("compliments", { */ complimentArray: function () { const hour = moment().hour(); - const date = this.config.mockDate ? this.config.mockDate : moment().format("YYYY-MM-DD"); - let compliments; + const date = moment().format("YYYY-MM-DD"); + let compliments = []; + // Add time of day compliments if (hour >= this.config.morningStartTime && hour < this.config.morningEndTime && this.config.compliments.hasOwnProperty("morning")) { - compliments = this.config.compliments.morning.slice(0); + compliments = [...this.config.compliments.morning]; } else if (hour >= this.config.afternoonStartTime && hour < this.config.afternoonEndTime && this.config.compliments.hasOwnProperty("afternoon")) { - compliments = this.config.compliments.afternoon.slice(0); + compliments = [...this.config.compliments.afternoon]; } else if (this.config.compliments.hasOwnProperty("evening")) { - compliments = this.config.compliments.evening.slice(0); - } - - if (typeof compliments === "undefined") { - compliments = []; + compliments = [...this.config.compliments.evening]; } + // Add compliments based on weather if (this.currentWeatherType in this.config.compliments) { - compliments.push.apply(compliments, this.config.compliments[this.currentWeatherType]); + Array.prototype.push.apply(compliments, this.config.compliments[this.currentWeatherType]); } - compliments.push.apply(compliments, this.config.compliments.anytime); + // Add compliments for anytime + Array.prototype.push.apply(compliments, this.config.compliments.anytime); + // Add compliments for special days for (let entry in this.config.compliments) { if (new RegExp(entry).test(date)) { - compliments.push.apply(compliments, this.config.compliments[entry]); + Array.prototype.push.apply(compliments, this.config.compliments[entry]); } } @@ -118,20 +117,13 @@ Module.register("compliments", { /** * Retrieve a file from the local filesystem * - * @param {Function} callback Called when the file is retrieved. + * @returns {Promise} Resolved when the file is loaded */ - complimentFile: function (callback) { - const xobj = new XMLHttpRequest(), - isRemote = this.config.remoteFile.indexOf("http://") === 0 || this.config.remoteFile.indexOf("https://") === 0, - path = isRemote ? this.config.remoteFile : this.file(this.config.remoteFile); - xobj.overrideMimeType("application/json"); - xobj.open("GET", path, true); - xobj.onreadystatechange = function () { - if (xobj.readyState === 4 && xobj.status === 200) { - callback(xobj.responseText); - } - }; - xobj.send(null); + loadComplimentFile: async function () { + const isRemote = this.config.remoteFile.indexOf("http://") === 0 || this.config.remoteFile.indexOf("https://") === 0, + url = isRemote ? this.config.remoteFile : this.file(this.config.remoteFile); + const response = await fetch(url); + return await response.text(); }, /** @@ -139,7 +131,7 @@ Module.register("compliments", { * * @returns {string} a compliment */ - randomCompliment: function () { + getRandomCompliment: function () { // get the current time of day compliments list const compliments = this.complimentArray(); // variable for index to next message to display @@ -162,34 +154,33 @@ Module.register("compliments", { const wrapper = document.createElement("div"); wrapper.className = this.config.classes ? this.config.classes : "thin xlarge bright pre-line"; // get the compliment text - const complimentText = this.randomCompliment(); + const complimentText = this.getRandomCompliment(); // split it into parts on newline text const parts = complimentText.split("\n"); - // create a span to hold it all + // create a span to hold the compliment const compliment = document.createElement("span"); // process all the parts of the compliment text for (const part of parts) { - // create a text element for each part - compliment.appendChild(document.createTextNode(part)); - // add a break ` - compliment.appendChild(document.createElement("BR")); + if (part !== "") { + // create a text element for each part + compliment.appendChild(document.createTextNode(part)); + // add a break + compliment.appendChild(document.createElement("BR")); + } + } + // only add compliment to wrapper if there is actual text in there + if (compliment.children.length > 0) { + // remove the last break + compliment.lastElementChild.remove(); + wrapper.appendChild(compliment); } - // remove the last break - compliment.lastElementChild.remove(); - wrapper.appendChild(compliment); - return wrapper; }, - // From data currentweather set weather type - setCurrentWeatherType: function (type) { - this.currentWeatherType = type; - }, - // Override notification handler. notificationReceived: function (notification, payload, sender) { if (notification === "CURRENTWEATHER_TYPE") { - this.setCurrentWeatherType(payload.type); + this.currentWeatherType = payload.type; } } }); diff --git a/modules/default/newsfeed/newsfeed.js b/modules/default/newsfeed/newsfeed.js index 67eb63bfcb..6b3bba7d29 100644 --- a/modules/default/newsfeed/newsfeed.js +++ b/modules/default/newsfeed/newsfeed.js @@ -42,6 +42,14 @@ Module.register("newsfeed", { dangerouslyDisableAutoEscaping: false }, + getUrlPrefix: function (item) { + if (item.useCorsProxy) { + return location.protocol + "//" + location.host + "/cors?url="; + } else { + return ""; + } + }, + // Define required scripts. getScripts: function () { return ["moment.js"]; @@ -142,14 +150,19 @@ Module.register("newsfeed", { sourceTitle: item.sourceTitle, publishDate: moment(new Date(item.pubdate)).fromNow(), title: item.title, - url: item.url, + url: this.getUrlPrefix(item) + item.url, description: item.description, items: items }; }, getActiveItemURL: function () { - return typeof this.newsItems[this.activeItem].url === "string" ? this.newsItems[this.activeItem].url : this.newsItems[this.activeItem].url.href; + const item = this.newsItems[this.activeItem]; + if (item) { + return typeof item.url === "string" ? this.getUrlPrefix(item) + item.url : this.getUrlPrefix(item) + item.url.href; + } else { + return ""; + } }, /** diff --git a/modules/default/newsfeed/newsfeedfetcher.js b/modules/default/newsfeed/newsfeedfetcher.js index 85a2136d26..be979b9311 100644 --- a/modules/default/newsfeed/newsfeedfetcher.js +++ b/modules/default/newsfeed/newsfeedfetcher.js @@ -18,9 +18,10 @@ const stream = require("stream"); * @param {number} reloadInterval Reload interval in milliseconds. * @param {string} encoding Encoding of the feed. * @param {boolean} logFeedWarnings If true log warnings when there is an error parsing a news article. + * @param {boolean} useCorsProxy If true cors proxy is used for article url's. * @class */ -const NewsfeedFetcher = function (url, reloadInterval, encoding, logFeedWarnings) { +const NewsfeedFetcher = function (url, reloadInterval, encoding, logFeedWarnings, useCorsProxy) { let reloadTimer = null; let items = []; @@ -57,7 +58,8 @@ const NewsfeedFetcher = function (url, reloadInterval, encoding, logFeedWarnings title: title, description: description, pubdate: pubdate, - url: url + url: url, + useCorsProxy: useCorsProxy }); } else if (logFeedWarnings) { Log.warn("Can't parse feed item:"); diff --git a/modules/default/newsfeed/node_helper.js b/modules/default/newsfeed/node_helper.js index e8816b83c3..13b0f94aa2 100644 --- a/modules/default/newsfeed/node_helper.js +++ b/modules/default/newsfeed/node_helper.js @@ -34,6 +34,8 @@ module.exports = NodeHelper.create({ const url = feed.url || ""; const encoding = feed.encoding || "UTF-8"; const reloadInterval = feed.reloadInterval || config.reloadInterval || 5 * 60 * 1000; + let useCorsProxy = feed.useCorsProxy; + if (useCorsProxy === undefined) useCorsProxy = true; try { new URL(url); @@ -46,7 +48,7 @@ module.exports = NodeHelper.create({ let fetcher; if (typeof this.fetchers[url] === "undefined") { Log.log("Create new newsfetcher for url: " + url + " - Interval: " + reloadInterval); - fetcher = new NewsfeedFetcher(url, reloadInterval, encoding, config.logFeedWarnings); + fetcher = new NewsfeedFetcher(url, reloadInterval, encoding, config.logFeedWarnings, useCorsProxy); fetcher.onReceive(() => { this.broadcastFeeds(); diff --git a/modules/default/updatenotification/git_helper.js b/modules/default/updatenotification/git_helper.js index b42b7d5cc1..80cb75320a 100644 --- a/modules/default/updatenotification/git_helper.js +++ b/modules/default/updatenotification/git_helper.js @@ -92,20 +92,18 @@ class GitHelper { // examples for status: // ## develop...origin/develop // ## master...origin/master [behind 8] - status = status.match(/(?![.#])([^.]*)/g); + // ## master...origin/master [ahead 8, behind 1] + status = status.match(/## (.*)\.\.\.([^ ]*)(?: .*behind (\d+))?/); // 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(); + // [ '## develop...origin/develop', 'develop', 'origin/develop' ] + // [ '## master...origin/master [behind 8]', 'master', 'origin/master', '8' ] + // [ '## master...origin/master [ahead 8, behind 1]', 'master', 'origin/master', '1' ] + gitInfo.current = status[1]; + gitInfo.tracking = status[2]; - if (status[2]) { + if (status[3]) { // 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.behind = parseInt(status[3]); gitInfo.isBehindInStatus = true; } diff --git a/modules/default/utils.js b/modules/default/utils.js new file mode 100644 index 0000000000..fb2cab8f31 --- /dev/null +++ b/modules/default/utils.js @@ -0,0 +1,147 @@ +/** + * A function to make HTTP requests via the server to avoid CORS-errors. + * + * @param {string} url the url to fetch from + * @param {string} type what contenttype to expect in the response, can be "json" or "xml" + * @param {boolean} useCorsProxy A flag to indicate + * @param {Array.<{name: string, value:string}>} requestHeaders the HTTP headers to send + * @param {Array.} expectedResponseHeaders the expected HTTP headers to recieve + * @returns {Promise} resolved when the fetch is done. The response headers is placed in a headers-property (provided the response does not allready contain a headers-property). + */ +async function performWebRequest(url, type = "json", useCorsProxy = false, requestHeaders = undefined, expectedResponseHeaders = undefined) { + const request = {}; + if (useCorsProxy) { + url = getCorsUrl(url, requestHeaders, expectedResponseHeaders); + } else { + request.headers = getHeadersToSend(requestHeaders); + } + const response = await fetch(url, request); + const data = await response.text(); + + if (type === "xml") { + return new DOMParser().parseFromString(data, "text/html"); + } else { + if (!data || !data.length > 0) return undefined; + + const dataResponse = JSON.parse(data); + if (!dataResponse.headers) { + dataResponse.headers = getHeadersFromResponse(expectedResponseHeaders, response); + } + return dataResponse; + } +} + +/** + * Gets a URL that will be used when calling the CORS-method on the server. + * + * @param {string} url the url to fetch from + * @param {Array.<{name: string, value:string}>} requestHeaders the HTTP headers to send + * @param {Array.} expectedResponseHeaders the expected HTTP headers to recieve + * @returns {string} to be used as URL when calling CORS-method on server. + */ +const getCorsUrl = function (url, requestHeaders, expectedResponseHeaders) { + if (!url || url.length < 1) { + throw new Error(`Invalid URL: ${url}`); + } else { + let corsUrl = `${location.protocol}//${location.host}/cors?`; + + const requestHeaderString = getRequestHeaderString(requestHeaders); + if (requestHeaderString) corsUrl = `${corsUrl}sendheaders=${requestHeaderString}`; + + const expectedResponseHeadersString = getExpectedResponseHeadersString(expectedResponseHeaders); + if (requestHeaderString && expectedResponseHeadersString) { + corsUrl = `${corsUrl}&expectedheaders=${expectedResponseHeadersString}`; + } else if (expectedResponseHeadersString) { + corsUrl = `${corsUrl}expectedheaders=${expectedResponseHeadersString}`; + } + + if (requestHeaderString || expectedResponseHeadersString) { + return `${corsUrl}&url=${url}`; + } + return `${corsUrl}url=${url}`; + } +}; + +/** + * Gets the part of the CORS URL that represents the HTTP headers to send. + * + * @param {Array.<{name: string, value:string}>} requestHeaders the HTTP headers to send + * @returns {string} to be used as request-headers component in CORS URL. + */ +const getRequestHeaderString = function (requestHeaders) { + let requestHeaderString = ""; + if (requestHeaders) { + for (const header of requestHeaders) { + if (requestHeaderString.length === 0) { + requestHeaderString = `${header.name}:${encodeURIComponent(header.value)}`; + } else { + requestHeaderString = `${requestHeaderString},${header.name}:${encodeURIComponent(header.value)}`; + } + } + return requestHeaderString; + } + return undefined; +}; + +/** + * Gets headers and values to attatch to the web request. + * + * @param {Array.<{name: string, value:string}>} requestHeaders the HTTP headers to send + * @returns {object} An object specifying name and value of the headers. + */ +const getHeadersToSend = (requestHeaders) => { + const headersToSend = {}; + if (requestHeaders) { + for (const header of requestHeaders) { + headersToSend[header.name] = header.value; + } + } + + return headersToSend; +}; + +/** + * Gets the part of the CORS URL that represents the expected HTTP headers to recieve. + * + * @param {Array.} expectedResponseHeaders the expected HTTP headers to recieve + * @returns {string} to be used as the expected HTTP-headers component in CORS URL. + */ +const getExpectedResponseHeadersString = function (expectedResponseHeaders) { + let expectedResponseHeadersString = ""; + if (expectedResponseHeaders) { + for (const header of expectedResponseHeaders) { + if (expectedResponseHeadersString.length === 0) { + expectedResponseHeadersString = `${header}`; + } else { + expectedResponseHeadersString = `${expectedResponseHeadersString},${header}`; + } + } + return expectedResponseHeaders; + } + return undefined; +}; + +/** + * Gets the values for the expected headers from the response. + * + * @param {Array.} expectedResponseHeaders the expected HTTP headers to recieve + * @param {Response} response the HTTP response + * @returns {string} to be used as the expected HTTP-headers component in CORS URL. + */ +const getHeadersFromResponse = (expectedResponseHeaders, response) => { + const responseHeaders = []; + + if (expectedResponseHeaders) { + for (const header of expectedResponseHeaders) { + const headerValue = response.headers.get(header); + responseHeaders.push({ name: header, value: headerValue }); + } + } + + return responseHeaders; +}; + +if (typeof module !== "undefined") + module.exports = { + performWebRequest + }; diff --git a/modules/default/weather/current.njk b/modules/default/weather/current.njk index bfeb0b8f13..ae542caa9a 100644 --- a/modules/default/weather/current.njk +++ b/modules/default/weather/current.njk @@ -3,15 +3,7 @@
- {% if config.useBeaufort %} - {{ current.beaufortWindSpeed() | round }} - {% else %} - {% if config.useKmh %} - {{ current.kmhWindSpeed() | round }} - {% else %} - {{ current.windSpeed | round }} - {% endif %} - {% endif %} + {{ current.windSpeed | unit("wind") | round }} {% if config.showWindDirection %} {% if config.showWindDirectionAsArrow %} diff --git a/modules/default/weather/providers/darksky.js b/modules/default/weather/providers/darksky.js index a248bc54ae..aa48a12bd8 100644 --- a/modules/default/weather/providers/darksky.js +++ b/modules/default/weather/providers/darksky.js @@ -26,11 +26,6 @@ WeatherProvider.register("darksky", { lon: 0 }, - units: { - imperial: "us", - metric: "si" - }, - fetchCurrentWeather() { this.fetchData(this.getUrl()) .then((data) => { @@ -67,13 +62,12 @@ WeatherProvider.register("darksky", { // Create a URL from the config and base URL. getUrl() { - const units = this.units[this.config.units] || "auto"; - return `${this.config.apiBase}${this.config.weatherEndpoint}/${this.config.apiKey}/${this.config.lat},${this.config.lon}?units=${units}&lang=${this.config.lang}`; + return `${this.config.apiBase}${this.config.weatherEndpoint}/${this.config.apiKey}/${this.config.lat},${this.config.lon}?units=si&lang=${this.config.lang}`; }, // Implement WeatherDay generator. generateWeatherDayFromCurrentWeather(currentWeatherData) { - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const currentWeather = new WeatherObject(); currentWeather.date = moment(); currentWeather.humidity = parseFloat(currentWeatherData.currently.humidity); @@ -81,8 +75,8 @@ WeatherProvider.register("darksky", { currentWeather.windSpeed = parseFloat(currentWeatherData.currently.windSpeed); currentWeather.windDirection = currentWeatherData.currently.windBearing; currentWeather.weatherType = this.convertWeatherType(currentWeatherData.currently.icon); - currentWeather.sunrise = moment(currentWeatherData.daily.data[0].sunriseTime, "X"); - currentWeather.sunset = moment(currentWeatherData.daily.data[0].sunsetTime, "X"); + currentWeather.sunrise = moment.unix(currentWeatherData.daily.data[0].sunriseTime); + currentWeather.sunset = moment.unix(currentWeatherData.daily.data[0].sunsetTime); return currentWeather; }, @@ -91,9 +85,9 @@ WeatherProvider.register("darksky", { const days = []; for (const forecast of forecasts) { - const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const weather = new WeatherObject(); - weather.date = moment(forecast.time, "X"); + weather.date = moment.unix(forecast.time); weather.minTemperature = forecast.temperatureMin; weather.maxTemperature = forecast.temperatureMax; weather.weatherType = this.convertWeatherType(forecast.icon); diff --git a/modules/default/weather/providers/envcanada.js b/modules/default/weather/providers/envcanada.js index 589cec6ec0..4842446be6 100644 --- a/modules/default/weather/providers/envcanada.js +++ b/modules/default/weather/providers/envcanada.js @@ -1,4 +1,4 @@ -/* global WeatherProvider, WeatherObject */ +/* global WeatherProvider, WeatherObject, WeatherUtils */ /* MagicMirror² * Module: Weather @@ -11,13 +11,13 @@ * https://dd.weather.gc.ca/citypage_weather/schema/ * https://eccc-msc.github.io/open-data/msc-datamart/readme_en/ * - * This module supports Canadian locations only and requires 2 additional config parms: + * This module supports Canadian locations only and requires 2 additional config parameters: * * siteCode - the city/town unique identifier for which weather is to be displayed. Format is 's0000000'. * * provCode - the 2-character province code for the selected city/town. * - * Example: for Toronto, Ontario, the following parms would be used + * Example: for Toronto, Ontario, the following parameters would be used * * siteCode: 's0000458', * provCode: 'ON' @@ -64,17 +64,13 @@ WeatherProvider.register("envcanada", { start: function () { Log.info(`Weather provider: ${this.providerName} started.`); this.setFetchedLocation(this.config.location); - - // Ensure kmH are ignored since these are custom-handled by this Provider - - this.config.useKmh = false; }, // // Override the fetchCurrentWeather method to query EC and construct a Current weather object // fetchCurrentWeather() { - this.fetchData(this.getUrl(), "GET", "xml") + this.fetchData(this.getUrl(), "xml") .then((data) => { if (!data) { // Did not receive usable new data. @@ -94,7 +90,7 @@ WeatherProvider.register("envcanada", { // Override the fetchWeatherForecast method to query EC and construct Forecast weather objects // fetchWeatherForecast() { - this.fetchData(this.getUrl(), "GET", "xml") + this.fetchData(this.getUrl(), "xml") .then((data) => { if (!data) { // Did not receive usable new data. @@ -114,7 +110,7 @@ WeatherProvider.register("envcanada", { // Override the fetchWeatherHourly method to query EC and construct Forecast weather objects // fetchWeatherHourly() { - this.fetchData(this.getUrl(), "GET", "xml") + this.fetchData(this.getUrl(), "xml") .then((data) => { if (!data) { // Did not receive usable new data. @@ -137,8 +133,8 @@ WeatherProvider.register("envcanada", { ////////////////////////////////////////////////////////////////////////////////// // - // Build the EC URL based on the Site Code and Province Code specified in the config parms. Note that the - // URL defaults to the Englsih version simply because there is no language dependancy in the data + // Build the EC URL based on the Site Code and Province Code specified in the config params. Note that the + // URL defaults to the English version simply because there is no language dependency in the data // being accessed. This is only pertinent when using the EC data elements that contain a textual forecast. // getUrl() { @@ -150,7 +146,7 @@ WeatherProvider.register("envcanada", { // generateWeatherObjectFromCurrentWeather(ECdoc) { - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const currentWeather = new WeatherObject(); // There are instances where EC will update weather data and current temperature will not be // provided. While this is a defect in the EC systems, we need to accommodate to avoid a current temp @@ -161,13 +157,13 @@ WeatherProvider.register("envcanada", { // EC finds no current temp. In this scenario, MM will end up displaying a current temp of null; if (ECdoc.querySelector("siteData currentConditions temperature").textContent) { - currentWeather.temperature = this.convertTemp(ECdoc.querySelector("siteData currentConditions temperature").textContent); + currentWeather.temperature = ECdoc.querySelector("siteData currentConditions temperature").textContent; this.cacheCurrentTemp = currentWeather.temperature; } else { currentWeather.temperature = this.cacheCurrentTemp; } - currentWeather.windSpeed = this.convertWind(ECdoc.querySelector("siteData currentConditions wind speed").textContent); + currentWeather.windSpeed = WeatherUtils.convertWindToMs(ECdoc.querySelector("siteData currentConditions wind speed").textContent); currentWeather.windDirection = ECdoc.querySelector("siteData currentConditions wind bearing").textContent; @@ -190,11 +186,11 @@ WeatherProvider.register("envcanada", { currentWeather.feelsLikeTemp = currentWeather.temperature; if (ECdoc.querySelector("siteData currentConditions windChill")) { - currentWeather.feelsLikeTemp = this.convertTemp(ECdoc.querySelector("siteData currentConditions windChill").textContent); + currentWeather.feelsLikeTemp = ECdoc.querySelector("siteData currentConditions windChill").textContent; } if (ECdoc.querySelector("siteData currentConditions humidex")) { - currentWeather.feelsLikeTemp = this.convertTemp(ECdoc.querySelector("siteData currentConditions humidex").textContent); + currentWeather.feelsLikeTemp = ECdoc.querySelector("siteData currentConditions humidex").textContent; } } @@ -225,7 +221,7 @@ WeatherProvider.register("envcanada", { const days = []; - const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const weather = new WeatherObject(); const foreBaseDates = ECdoc.querySelectorAll("siteData forecastGroup dateTime"); const baseDate = foreBaseDates[1].querySelector("timeStamp").textContent; @@ -326,7 +322,7 @@ WeatherProvider.register("envcanada", { days.push(weather); // - // Now do the the rest of the forecast starting at nextDay. We will process each day using 2 EC + // Now do the rest of the forecast starting at nextDay. We will process each day using 2 EC // forecast Elements. This will address the fact that the EC forecast always includes Today and // Tonight for each day. This is why we iterate through the forecast by a a count of 2, with each // iteration looking at the current Element and the next Element. @@ -335,12 +331,12 @@ WeatherProvider.register("envcanada", { let lastDate = moment(baseDate, "YYYYMMDDhhmmss"); for (let stepDay = nextDay; stepDay < lastDay; stepDay += 2) { - let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + let weather = new WeatherObject(); // Add 1 to the date to reflect the current forecast day we are building lastDate = lastDate.add(1, "day"); - weather.date = moment(lastDate, "X"); + weather.date = moment.unix(lastDate); // Capture the temperatures for the current Element and the next Element in order to set // the Min and Max temperatures for the forecast @@ -389,17 +385,17 @@ WeatherProvider.register("envcanada", { const hourGroup = ECdoc.querySelectorAll("siteData hourlyForecastGroup hourlyForecast"); for (let stepHour = 0; stepHour < 24; stepHour += 1) { - const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const weather = new WeatherObject(); // Determine local time by applying UTC offset to the forecast timestamp const foreTime = moment(hourGroup[stepHour].getAttribute("dateTimeUTC"), "YYYYMMDDhhmmss"); const currTime = foreTime.add(hourOffset, "hours"); - weather.date = moment(currTime, "X"); + weather.date = moment.unix(currTime); // Capture the temperature - weather.temperature = this.convertTemp(hourGroup[stepHour].querySelector("temperature").textContent); + weather.temperature = hourGroup[stepHour].querySelector("temperature").textContent; // Capture Likelihood of Precipitation (LOP) and unit-of-measure values @@ -450,7 +446,7 @@ WeatherProvider.register("envcanada", { weather.minTemperature = this.todayTempCacheMin; weather.maxTemperature = this.todayTempCacheMax; } else { - weather.minTemperature = this.convertTemp(currentTemp); + weather.minTemperature = currentTemp; weather.maxTemperature = weather.minTemperature; } } @@ -463,14 +459,14 @@ WeatherProvider.register("envcanada", { // if (todayClass === "low") { - weather.minTemperature = this.convertTemp(todayTemp); + weather.minTemperature = todayTemp; if (today === 0 && fullDay === true) { this.todayTempCacheMin = weather.minTemperature; } } if (todayClass === "high") { - weather.maxTemperature = this.convertTemp(todayTemp); + weather.maxTemperature = todayTemp; if (today === 0 && fullDay === true) { this.todayTempCacheMax = weather.maxTemperature; } @@ -482,11 +478,11 @@ WeatherProvider.register("envcanada", { if (fullDay === true) { if (nextClass === "low") { - weather.minTemperature = this.convertTemp(nextTemp); + weather.minTemperature = nextTemp; } if (nextClass === "high") { - weather.maxTemperature = this.convertTemp(nextTemp); + weather.maxTemperature = nextTemp; } } }, @@ -536,31 +532,6 @@ WeatherProvider.register("envcanada", { } }, - // - // Unit conversions - // - // - // Convert C to F temps - // - convertTemp(temp) { - if (this.config.tempUnits === "imperial") { - return 1.8 * temp + 32; - } else { - return temp; - } - }, - - // - // Convert km/h to mph - // - convertWind(kilo) { - if (this.config.windUnits === "imperial") { - return kilo / 1.609344; - } else { - return kilo; - } - }, - // // Convert the icons to a more usable name. // diff --git a/modules/default/weather/providers/openmeteo.js b/modules/default/weather/providers/openmeteo.js new file mode 100644 index 0000000000..83583d5cee --- /dev/null +++ b/modules/default/weather/providers/openmeteo.js @@ -0,0 +1,537 @@ +/* global WeatherProvider, WeatherObject */ + +/* MagicMirror² + * Module: Weather + * Provider: Open-Meteo + * + * By Andrés Vanegas + * MIT Licensed + * + * This class is a provider for Open-Meteo, based on Andrew Pometti's class + * for Weatherbit. + */ +// https://www.bigdatacloud.com/docs/api/free-reverse-geocode-to-city-api +const GEOCODE_BASE = "https://api.bigdatacloud.net/data/reverse-geocode-client"; +const OPEN_METEO_BASE = "https://api.open-meteo.com/v1"; + +WeatherProvider.register("openmeteo", { + // Set the name of the provider. + // Not strictly required, but helps for debugging. + providerName: "Open-Meteo", + + // Set the default config properties that is specific to this provider + defaults: { + apiBase: OPEN_METEO_BASE, + lat: 0, + lon: 0, + past_days: 0, + type: "current" + }, + + // https://open-meteo.com/en/docs + hourlyParams: [ + // Air temperature at 2 meters above ground + "temperature_2m", + // Relative humidity at 2 meters above ground + "relativehumidity_2m", + // Dew point temperature at 2 meters above ground + "dewpoint_2m", + // Apparent temperature is the perceived feels-like temperature combining wind chill factor, relative humidity and solar radiation + "apparent_temperature", + // Atmospheric air pressure reduced to mean sea level (msl) or pressure at surface. Typically pressure on mean sea level is used in meteorology. Surface pressure gets lower with increasing elevation. + "pressure_msl", + "surface_pressure", + // Total cloud cover as an area fraction + "cloudcover", + // Low level clouds and fog up to 3 km altitude + "cloudcover_low", + // Mid level clouds from 3 to 8 km altitude + "cloudcover_mid", + // High level clouds from 8 km altitude + "cloudcover_high", + // Wind speed at 10, 80, 120 or 180 meters above ground. Wind speed on 10 meters is the standard level. + "windspeed_10m", + "windspeed_80m", + "windspeed_120m", + "windspeed_180m", + // Wind direction at 10, 80, 120 or 180 meters above ground + "winddirection_10m", + "winddirection_80m", + "winddirection_120m", + "winddirection_180m", + // Gusts at 10 meters above ground as a maximum of the preceding hour + "windgusts_10m", + // Shortwave solar radiation as average of the preceding hour. This is equal to the total global horizontal irradiation + "shortwave_radiation", + // Direct solar radiation as average of the preceding hour on the horizontal plane and the normal plane (perpendicular to the sun) + "direct_radiation", + "direct_normal_irradiance", + // Diffuse solar radiation as average of the preceding hour + "diffuse_radiation", + // Vapor Pressure Deificit (VPD) in kilopascal (kPa). For high VPD (>1.6), water transpiration of plants increases. For low VPD (<0.4), transpiration decreases + "vapor_pressure_deficit", + // Evapotranspration from land surface and plants that weather models assumes for this location. Available soil water is considered. 1 mm evapotranspiration per hour equals 1 liter of water per spare meter. + "evapotranspiration", + // ET₀ Reference Evapotranspiration of a well watered grass field. Based on FAO-56 Penman-Monteith equations ET₀ is calculated from temperature, wind speed, humidity and solar radiation. Unlimited soil water is assumed. ET₀ is commonly used to estimate the required irrigation for plants. + "et0_fao_evapotranspiration", + // Total precipitation (rain, showers, snow) sum of the preceding hour + "precipitation", + // Snowfall amount of the preceding hour in centimeters. For the water equivalent in millimeter, divide by 7. E.g. 7 cm snow = 10 mm precipitation water equivalent + "snowfall", + // Rain from large scale weather systems of the preceding hour in millimeter + "rain", + // Showers from convective precipitation in millimeters from the preceding hour + "showers", + // Weather condition as a numeric code. Follow WMO weather interpretation codes. + "weathercode", + // Snow depth on the ground + "snow_depth", + // Altitude above sea level of the 0°C level + "freezinglevel_height", + // Temperature in the soil at 0, 6, 18 and 54 cm depths. 0 cm is the surface temperature on land or water surface temperature on water. + "soil_temperature_0cm", + "soil_temperature_6cm", + "soil_temperature_18cm", + "soil_temperature_54cm", + // Average soil water content as volumetric mixing ratio at 0-1, 1-3, 3-9, 9-27 and 27-81 cm depths. + "soil_moisture_0_1cm", + "soil_moisture_1_3cm", + "soil_moisture_3_9cm", + "soil_moisture_9_27cm", + "soil_moisture_27_81cm" + ], + + dailyParams: [ + // Maximum and minimum daily air temperature at 2 meters above ground + "temperature_2m_max", + "temperature_2m_min", + // Maximum and minimum daily apparent temperature + "apparent_temperature_min", + "apparent_temperature_max", + // Sum of daily precipitation (including rain, showers and snowfall) + "precipitation_sum", + // Sum of daily rain + "rain_sum", + // Sum of daily showers + "showers_sum", + // Sum of daily snowfall + "snowfall_sum", + // The number of hours with rain + "precipitation_hours", + // The most severe weather condition on a given day + "weathercode", + // Sun rise and set times + "sunrise", + "sunset", + // Maximum wind speed and gusts on a day + "windspeed_10m_max", + "windgusts_10m_max", + // Dominant wind direction + "winddirection_10m_dominant", + // The sum of solar radiation on a given day in Megajoules + "shortwave_radiation_sum", + // Daily sum of ET₀ Reference Evapotranspiration of a well watered grass field + "et0_fao_evapotranspiration" + ], + + fetchedLocation: function () { + return this.fetchedLocationName || ""; + }, + + fetchCurrentWeather() { + this.fetchData(this.getUrl()) + .then((data) => this.parseWeatherApiResponse(data)) + .then((parsedData) => { + if (!parsedData) { + // No usable data? + return; + } + + const currentWeather = this.generateWeatherDayFromCurrentWeather(parsedData); + this.setCurrentWeather(currentWeather); + }) + .catch(function (request) { + Log.error("Could not load data ... ", request); + }) + .finally(() => this.updateAvailable()); + }, + + fetchWeatherForecast() { + this.fetchData(this.getUrl()) + .then((data) => this.parseWeatherApiResponse(data)) + .then((parsedData) => { + if (!parsedData) { + // No usable data? + return; + } + + const dailyForecast = this.generateWeatherObjectsFromForecast(parsedData); + this.setWeatherForecast(dailyForecast); + }) + .catch(function (request) { + Log.error("Could not load data ... ", request); + }) + .finally(() => this.updateAvailable()); + }, + + fetchWeatherHourly() { + this.fetchData(this.getUrl()) + .then((data) => this.parseWeatherApiResponse(data)) + .then((parsedData) => { + if (!parsedData) { + // No usable data? + return; + } + + const hourlyForecast = this.generateWeatherObjectsFromHourly(parsedData); + this.setWeatherHourly(hourlyForecast); + }) + .catch(function (request) { + Log.error("Could not load data ... ", request); + }) + .finally(() => this.updateAvailable()); + }, + + /** + * Overrides method for setting config to check if endpoint is correct for hourly + * + * @param {object} config The configuration object + */ + setConfig(config) { + this.config = { + lang: config.lang ?? "en", + ...this.defaults, + ...config + }; + + // Set properly maxNumberOfDays and max Entries properties according to config and value ranges allowed in the documentation + const maxEntriesLimit = ["daily", "forecast"].includes(this.config.type) ? 7 : this.config.type === "hourly" ? 48 : 0; + if (this.config.hasOwnProperty("maxNumberOfDays") && !isNaN(parseFloat(this.config.maxNumberOfDays))) { + const daysFactor = ["daily", "forecast"].includes(this.config.type) ? 1 : this.config.type === "hourly" ? 24 : 0; + this.config.maxEntries = Math.max(1, Math.min(Math.round(parseFloat(this.config.maxNumberOfDays)) * daysFactor, maxEntriesLimit)); + this.config.maxNumberOfDays = Math.ceil(this.config.maxEntries / Math.max(1, daysFactor)); + } + this.config.maxEntries = Math.max(1, Math.min(this.config.maxEntries, maxEntriesLimit)); + + if (!this.config.type) { + Log.error("type not configured and could not resolve it"); + } + + this.fetchLocation(); + }, + + // Generate valid query params to perform the request + getQueryParameters() { + let params = { + latitude: this.config.lat, + longitude: this.config.lon, + timeformat: "unixtime", + timezone: "auto", + past_days: this.config.past_days ?? 0, + daily: this.dailyParams, + hourly: this.hourlyParams, + // Fixed units as metric + temperature_unit: "celsius", + windspeed_unit: "kmh", + precipitation_unit: "mm" + }; + + const startDate = moment().startOf("day"); + const endDate = moment(startDate) + .add(Math.max(0, Math.min(7, this.config.maxNumberOfDays)), "days") + .endOf("day"); + + params["start_date"] = startDate.format("YYYY-MM-DD"); + + switch (this.config.type) { + case "hourly": + case "daily": + case "forecast": + params["end_date"] = endDate.format("YYYY-MM-DD"); + break; + case "current": + params["current_weather"] = true; + params["end_date"] = params["start_date"]; + break; + default: + // Failsafe + return ""; + } + + return Object.keys(params) + .filter((key) => (params[key] ? true : false)) + .map((key) => { + switch (key) { + case "hourly": + case "daily": + return encodeURIComponent(key) + "=" + params[key].join(","); + default: + return encodeURIComponent(key) + "=" + encodeURIComponent(params[key]); + } + }) + .join("&"); + }, + + // Create a URL from the config and base URL. + getUrl() { + return `${this.config.apiBase}/forecast?${this.getQueryParameters()}`; + }, + + // Transpose hourly and daily data matrices + transposeDataMatrix(data) { + return data.time.map((_, index) => + Object.keys(data).reduce((row, key) => { + return { + ...row, + // Parse time values as momentjs instances + [key]: ["time", "sunrise", "sunset"].includes(key) ? moment.unix(data[key][index]) : data[key][index] + }; + }, {}) + ); + }, + + // Sanitize and validate API response + parseWeatherApiResponse(data) { + const validByType = { + current: data.current_weather && data.current_weather.time, + hourly: data.hourly && data.hourly.time && Array.isArray(data.hourly.time) && data.hourly.time.length > 0, + daily: data.daily && data.daily.time && Array.isArray(data.daily.time) && data.daily.time.length > 0 + }; + // backwards compatibility + const type = ["daily", "forecast"].includes(this.config.type) ? "daily" : this.config.type; + + if (!validByType[type]) return; + + switch (type) { + case "current": + if (!validByType.daily && !validByType.hourly) { + return; + } + break; + case "hourly": + case "daily": + break; + default: + return; + } + + for (const key of ["hourly", "daily"]) { + if (typeof data[key] === "object") { + data[key] = this.transposeDataMatrix(data[key]); + } + } + + if (data.current_weather) { + data.current_weather.time = moment.unix(data.current_weather.time); + } + + return data; + }, + + // Reverse geocoding from latitude and longitude provided + fetchLocation() { + this.fetchData(`${GEOCODE_BASE}?latitude=${this.config.lat}&longitude=${this.config.lon}&localityLanguage=${this.config.lang}`) + .then((data) => { + if (!data || !data.city) { + // No usable data? + return; + } + this.fetchedLocationName = `${data.city}, ${data.principalSubdivisionCode}`; + }) + .catch((request) => { + Log.error("Could not load data ... ", request); + }); + }, + + // Implement WeatherDay generator. + generateWeatherDayFromCurrentWeather(weather) { + /** + * Since some units comes from API response "splitted" into daily, hourly and current_weather + * every time you request it, you have to ensure to get the data from the right place every time. + * For the current weather case, the response have the following structure (after transposing): + * ``` + * { + * current_weather: { ... }, + * hourly: [ + * 0: {... }, + * 1: {... }, + * ... + * ], + * daily: [ + * {... }, + * ] + * } + * ``` + * Some data should be returned from `hourly` array data when the index matches the current hour, + * some data from the first and only one object received in `daily` array and some from the + * `current_weather` object. + */ + const h = moment().hour(); + const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + + currentWeather.date = weather.current_weather.time; + currentWeather.windSpeed = weather.current_weather.windspeed; + currentWeather.windDirection = weather.current_weather.winddirection; + currentWeather.sunrise = weather.daily[0].sunrise; + currentWeather.sunset = weather.daily[0].sunset; + currentWeather.temperature = parseFloat(weather.current_weather.temperature); + currentWeather.minTemperature = parseFloat(weather.daily[0].temperature_2m_min); + currentWeather.maxTemperature = parseFloat(weather.daily[0].temperature_2m_max); + currentWeather.weatherType = this.convertWeatherType(weather.current_weather.weathercode, currentWeather.isDayTime()); + currentWeather.humidity = parseFloat(weather.hourly[h].relativehumidity_2m); + currentWeather.rain = parseFloat(weather.hourly[h].rain); + currentWeather.snow = parseFloat(weather.hourly[h].snowfall * 10); + currentWeather.precipitation = parseFloat(weather.hourly[h].precipitation); + + return currentWeather; + }, + + // Implement WeatherForecast generator. + generateWeatherObjectsFromForecast(weathers) { + const days = []; + + weathers.daily.forEach((weather, i) => { + const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + + currentWeather.date = weather.time; + currentWeather.windSpeed = weather.windspeed_10m_max; + currentWeather.windDirection = weather.winddirection_10m_dominant; + currentWeather.sunrise = weather.sunrise; + currentWeather.sunset = weather.sunset; + currentWeather.temperature = parseFloat((weather.apparent_temperature_max + weather.apparent_temperature_min) / 2); + currentWeather.minTemperature = parseFloat(weather.apparent_temperature_min); + currentWeather.maxTemperature = parseFloat(weather.apparent_temperature_max); + currentWeather.weatherType = this.convertWeatherType(weather.weathercode, currentWeather.isDayTime()); + currentWeather.rain = parseFloat(weather.rain_sum); + currentWeather.snow = parseFloat(weather.snowfall_sum * 10); + currentWeather.precipitation = parseFloat(weather.precipitation_sum); + + days.push(currentWeather); + }); + + return days; + }, + + // Implement WeatherHourly generator. + generateWeatherObjectsFromHourly(weathers) { + const hours = []; + const now = moment(); + + weathers.hourly.forEach((weather, i) => { + if ((hours.length === 0 && weather.time.hour() <= now.hour()) || hours.length >= this.config.maxEntries) { + return; + } + + const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const h = Math.ceil((i + 1) / 24) - 1; + + currentWeather.date = weather.time; + currentWeather.windSpeed = weather.windspeed_10m; + currentWeather.windDirection = weather.winddirection_10m; + currentWeather.sunrise = weathers.daily[h].sunrise; + currentWeather.sunset = weathers.daily[h].sunset; + currentWeather.temperature = parseFloat(weather.apparent_temperature); + currentWeather.minTemperature = parseFloat(weathers.daily[h].apparent_temperature_min); + currentWeather.maxTemperature = parseFloat(weathers.daily[h].apparent_temperature_max); + currentWeather.weatherType = this.convertWeatherType(weather.weathercode, currentWeather.isDayTime()); + currentWeather.humidity = parseFloat(weather.relativehumidity_2m); + currentWeather.rain = parseFloat(weather.rain); + currentWeather.snow = parseFloat(weather.snowfall * 10); + currentWeather.precipitation = parseFloat(weather.precipitation); + + hours.push(currentWeather); + }); + + return hours; + }, + + // Map icons from Dark Sky to our icons. + convertWeatherType(weathercode, isDayTime) { + const weatherConditions = { + 0: "clear", + 1: "mainly-clear", + 2: "partly-cloudy", + 3: "overcast", + 45: "fog", + 48: "depositing-rime-fog", + 51: "drizzle-light-intensity", + 53: "drizzle-moderate-intensity", + 55: "drizzle-dense-intensity", + 56: "freezing-drizzle-light-intensity", + 57: "freezing-drizzle-dense-intensity", + 61: "rain-slight-intensity", + 63: "rain-moderate-intensity", + 65: "rain-heavy-intensity", + 66: "freezing-rain-light-heavy-intensity", + 67: "freezing-rain-heavy-intensity", + 71: "snow-fall-slight-intensity", + 73: "snow-fall-moderate-intensity", + 75: "snow-fall-heavy-intensity", + 77: "snow-grains", + 80: "rain-showers-slight", + 81: "rain-showers-moderate", + 82: "rain-showers-violent", + 85: "snow-showers-slight", + 86: "snow-showers-heavy", + 95: "thunderstorm", + 96: "thunderstorm-slight-hail", + 99: "thunderstorm-heavy-hail" + }; + + if (!Object.keys(weatherConditions).includes(`${weathercode}`)) return null; + + switch (weatherConditions[`${weathercode}`]) { + case "clear": + return isDayTime ? "day-sunny" : "night-clear"; + case "mainly-clear": + case "partly-cloudy": + return isDayTime ? "day-cloudy" : "night-alt-cloudy"; + case "overcast": + return isDayTime ? "day-sunny-overcast" : "night-alt-partly-cloudy"; + case "fog": + case "depositing-rime-fog": + return isDayTime ? "day-fog" : "night-fog"; + case "drizzle-light-intensity": + case "rain-slight-intensity": + case "rain-showers-slight": + return isDayTime ? "day-sprinkle" : "night-sprinkle"; + case "drizzle-moderate-intensity": + case "rain-moderate-intensity": + case "rain-showers-moderate": + return isDayTime ? "day-showers" : "night-showers"; + case "drizzle-dense-intensity": + case "rain-heavy-intensity": + case "rain-showers-violent": + return isDayTime ? "day-thunderstorm" : "night-thunderstorm"; + case "freezing-rain-light-intensity": + return isDayTime ? "day-rain-mix" : "night-rain-mix"; + case "freezing-drizzle-light-intensity": + case "freezing-drizzle-dense-intensity": + return "snowflake-cold"; + case "snow-grains": + return isDayTime ? "day-sleet" : "night-sleet"; + case "snow-fall-slight-intensity": + case "snow-fall-moderate-intensity": + return isDayTime ? "day-snow-wind" : "night-snow-wind"; + case "snow-fall-heavy-intensity": + case "freezing-rain-heavy-intensity": + return isDayTime ? "day-snow-thunderstorm" : "night-snow-thunderstorm"; + case "snow-showers-slight": + case "snow-showers-heavy": + return isDayTime ? "day-rain-mix" : "night-rain-mix"; + case "thunderstorm": + return isDayTime ? "day-thunderstorm" : "night-thunderstorm"; + case "thunderstorm-slight-hail": + return isDayTime ? "day-sleet" : "night-sleet"; + case "thunderstorm-heavy-hail": + return isDayTime ? "day-sleet-storm" : "night-sleet-storm"; + default: + return "na"; + } + }, + + // Define required scripts. + getScripts: function () { + return ["moment.js"]; + } +}); diff --git a/modules/default/weather/providers/openweathermap.js b/modules/default/weather/providers/openweathermap.js index b0f5eedf9e..f5f786fa01 100644 --- a/modules/default/weather/providers/openweathermap.js +++ b/modules/default/weather/providers/openweathermap.js @@ -21,7 +21,7 @@ WeatherProvider.register("openweathermap", { weatherEndpoint: "", // can be "onecall", "forecast" or "weather" (for current) locationID: false, location: false, - lat: 0, // the onecall endpoint needs lat / lon values, it doesn'T support the locationId + lat: 0, // the onecall endpoint needs lat / lon values, it doesn't support the locationId lon: 0, apiKey: "" }, @@ -30,14 +30,14 @@ WeatherProvider.register("openweathermap", { fetchCurrentWeather() { this.fetchData(this.getUrl()) .then((data) => { + let currentWeather; if (this.config.weatherEndpoint === "/onecall") { - const weatherData = this.generateWeatherObjectsFromOnecall(data); - this.setCurrentWeather(weatherData.current); + currentWeather = this.generateWeatherObjectsFromOnecall(data).current; this.setFetchedLocation(`${data.timezone}`); } else { - const currentWeather = this.generateWeatherObjectFromCurrentWeather(data); - this.setCurrentWeather(currentWeather); + currentWeather = this.generateWeatherObjectFromCurrentWeather(data); } + this.setCurrentWeather(currentWeather); }) .catch(function (request) { Log.error("Could not load data ... ", request); @@ -49,15 +49,17 @@ WeatherProvider.register("openweathermap", { fetchWeatherForecast() { this.fetchData(this.getUrl()) .then((data) => { + let forecast; + let location; if (this.config.weatherEndpoint === "/onecall") { - const weatherData = this.generateWeatherObjectsFromOnecall(data); - this.setWeatherForecast(weatherData.days); - this.setFetchedLocation(`${data.timezone}`); + forecast = this.generateWeatherObjectsFromOnecall(data).days; + location = `${data.timezone}`; } else { - const forecast = this.generateWeatherObjectsFromForecast(data.list); - this.setWeatherForecast(forecast); - this.setFetchedLocation(`${data.city.name}, ${data.city.country}`); + forecast = this.generateWeatherObjectsFromForecast(data.list); + location = `${data.city.name}, ${data.city.country}`; } + this.setWeatherForecast(forecast); + this.setFetchedLocation(location); }) .catch(function (request) { Log.error("Could not load data ... ", request); @@ -123,16 +125,17 @@ WeatherProvider.register("openweathermap", { * Generate a WeatherObject based on currentWeatherInformation */ generateWeatherObjectFromCurrentWeather(currentWeatherData) { - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const currentWeather = new WeatherObject(); + currentWeather.date = moment.unix(currentWeatherData.dt); currentWeather.humidity = currentWeatherData.main.humidity; currentWeather.temperature = currentWeatherData.main.temp; currentWeather.feelsLikeTemp = currentWeatherData.main.feels_like; currentWeather.windSpeed = currentWeatherData.wind.speed; currentWeather.windDirection = currentWeatherData.wind.deg; currentWeather.weatherType = this.convertWeatherType(currentWeatherData.weather[0].icon); - currentWeather.sunrise = moment(currentWeatherData.sys.sunrise, "X"); - currentWeather.sunset = moment(currentWeatherData.sys.sunset, "X"); + currentWeather.sunrise = moment.unix(currentWeatherData.sys.sunrise); + currentWeather.sunset = moment.unix(currentWeatherData.sys.sunset); return currentWeather; }, @@ -147,8 +150,7 @@ WeatherProvider.register("openweathermap", { return this.fetchForecastDaily(forecasts); } // if weatherEndpoint does not match forecast or forecast/daily, what should be returned? - const days = [new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh)]; - return days; + return [new WeatherObject()]; }, /* @@ -159,8 +161,7 @@ WeatherProvider.register("openweathermap", { return this.fetchOnecall(data); } // if weatherEndpoint does not match onecall, what should be returned? - const weatherData = { current: new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh), hours: [], days: [] }; - return weatherData; + return { current: new WeatherObject(), hours: [], days: [] }; }, /* @@ -176,10 +177,10 @@ WeatherProvider.register("openweathermap", { let snow = 0; // variable for date let date = ""; - let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + let weather = new WeatherObject(); for (const forecast of forecasts) { - if (date !== moment(forecast.dt, "X").format("YYYY-MM-DD")) { + if (date !== moment.unix(forecast.dt).format("YYYY-MM-DD")) { // calculate minimum/maximum temperature, specify rain amount weather.minTemperature = Math.min.apply(null, minTemp); weather.maxTemperature = Math.max.apply(null, maxTemp); @@ -189,7 +190,7 @@ WeatherProvider.register("openweathermap", { // push weather information to days array days.push(weather); // create new weather-object - weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + weather = new WeatherObject(); minTemp = []; maxTemp = []; @@ -197,16 +198,16 @@ WeatherProvider.register("openweathermap", { snow = 0; // set new date - date = moment(forecast.dt, "X").format("YYYY-MM-DD"); + date = moment.unix(forecast.dt).format("YYYY-MM-DD"); // specify date - weather.date = moment(forecast.dt, "X"); + weather.date = moment.unix(forecast.dt); // If the first value of today is later than 17:00, we have an icon at least! weather.weatherType = this.convertWeatherType(forecast.weather[0].icon); } - if (moment(forecast.dt, "X").format("H") >= 8 && moment(forecast.dt, "X").format("H") <= 17) { + if (moment.unix(forecast.dt).format("H") >= 8 && moment.unix(forecast.dt).format("H") <= 17) { weather.weatherType = this.convertWeatherType(forecast.weather[0].icon); } @@ -252,9 +253,9 @@ WeatherProvider.register("openweathermap", { const days = []; for (const forecast of forecasts) { - const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const weather = new WeatherObject(); - weather.date = moment(forecast.dt, "X"); + weather.date = moment.unix(forecast.dt); weather.minTemperature = forecast.temp.min; weather.maxTemperature = forecast.temp.max; weather.weatherType = this.convertWeatherType(forecast.weather[0].icon); @@ -298,13 +299,13 @@ WeatherProvider.register("openweathermap", { let precip = false; // get current weather, if requested - const current = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const current = new WeatherObject(); if (data.hasOwnProperty("current")) { - current.date = moment(data.current.dt, "X").utcOffset(data.timezone_offset / 60); + current.date = moment.unix(data.current.dt).utcOffset(data.timezone_offset / 60); current.windSpeed = data.current.wind_speed; current.windDirection = data.current.wind_deg; - current.sunrise = moment(data.current.sunrise, "X").utcOffset(data.timezone_offset / 60); - current.sunset = moment(data.current.sunset, "X").utcOffset(data.timezone_offset / 60); + current.sunrise = moment.unix(data.current.sunrise).utcOffset(data.timezone_offset / 60); + current.sunset = moment.unix(data.current.sunset).utcOffset(data.timezone_offset / 60); current.temperature = data.current.temp; current.weatherType = this.convertWeatherType(data.current.weather[0].icon); current.humidity = data.current.humidity; @@ -330,14 +331,13 @@ WeatherProvider.register("openweathermap", { current.feelsLikeTemp = data.current.feels_like; } - let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + let weather = new WeatherObject(); // get hourly weather, if requested const hours = []; if (data.hasOwnProperty("hourly")) { for (const hour of data.hourly) { - weather.date = moment(hour.dt, "X").utcOffset(data.timezone_offset / 60); - // weather.date = moment(hour.dt, "X").utcOffset(data.timezone_offset/60).format(onecallDailyFormat+","+onecallHourlyFormat); + weather.date = moment.unix(hour.dt).utcOffset(data.timezone_offset / 60); weather.temperature = hour.temp; weather.feelsLikeTemp = hour.feels_like; weather.humidity = hour.humidity; @@ -366,7 +366,7 @@ WeatherProvider.register("openweathermap", { } hours.push(weather); - weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + weather = new WeatherObject(); } } @@ -374,9 +374,9 @@ WeatherProvider.register("openweathermap", { const days = []; if (data.hasOwnProperty("daily")) { for (const day of data.daily) { - weather.date = moment(day.dt, "X").utcOffset(data.timezone_offset / 60); - weather.sunrise = moment(day.sunrise, "X").utcOffset(data.timezone_offset / 60); - weather.sunset = moment(day.sunset, "X").utcOffset(data.timezone_offset / 60); + weather.date = moment.unix(day.dt).utcOffset(data.timezone_offset / 60); + weather.sunrise = moment.unix(day.sunrise).utcOffset(data.timezone_offset / 60); + weather.sunset = moment.unix(day.sunset).utcOffset(data.timezone_offset / 60); weather.minTemperature = day.temp.min; weather.maxTemperature = day.temp.max; weather.humidity = day.humidity; @@ -405,7 +405,7 @@ WeatherProvider.register("openweathermap", { } days.push(weather); - weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + weather = new WeatherObject(); } } @@ -474,7 +474,7 @@ WeatherProvider.register("openweathermap", { return; } - params += "&units=" + this.config.units; + params += "&units=metric"; // WeatherProviders should use metric internally and use the units only for when displaying data params += "&lang=" + this.config.lang; params += "&APPID=" + this.config.apiKey; diff --git a/modules/default/weather/providers/smhi.js b/modules/default/weather/providers/smhi.js index 5e1ef4a3db..c3f51498a0 100644 --- a/modules/default/weather/providers/smhi.js +++ b/modules/default/weather/providers/smhi.js @@ -15,8 +15,8 @@ WeatherProvider.register("smhi", { // Set the default config properties that is specific to this provider defaults: { - lat: 0, - lon: 0, + lat: 0, // Cant have more than 6 digits + lon: 0, // Cant have more than 6 digits precipitationValue: "pmedian", location: false }, @@ -75,7 +75,7 @@ WeatherProvider.register("smhi", { setConfig(config) { this.config = config; if (!config.precipitationValue || ["pmin", "pmean", "pmedian", "pmax"].indexOf(config.precipitationValue) === -1) { - console.log("invalid or not set: " + config.precipitationValue); + Log.log("invalid or not set: " + config.precipitationValue); config.precipitationValue = this.defaults.precipitationValue; } }, @@ -104,8 +104,12 @@ WeatherProvider.register("smhi", { * @returns {string} the url for the specified coordinates */ getURL() { - let lon = this.config.lon; - let lat = this.config.lat; + const formatter = new Intl.NumberFormat("en-US", { + minimumFractionDigits: 6, + maximumFractionDigits: 6 + }); + const lon = formatter.format(this.config.lon); + const lat = formatter.format(this.config.lat); return `https://opendata-download-metfcst.smhi.se/api/category/pmp3g/version/2/geotype/point/lon/${lon}/lat/${lat}/data.json`; }, @@ -134,8 +138,7 @@ WeatherProvider.register("smhi", { * @returns {WeatherObject} The converted weatherdata at the specified location */ convertWeatherDataToObject(weatherData, coordinates) { - // Weather data is only for Sweden and nobody in Sweden would use imperial - let currentWeather = new WeatherObject("metric", "metric", "metric"); + let currentWeather = new WeatherObject(); currentWeather.date = moment(weatherData.validTime); currentWeather.updateSunTime(coordinates.lat, coordinates.lon); @@ -144,7 +147,7 @@ WeatherProvider.register("smhi", { currentWeather.windSpeed = this.paramValue(weatherData, "ws"); currentWeather.windDirection = this.paramValue(weatherData, "wd"); currentWeather.weatherType = this.convertWeatherType(this.paramValue(weatherData, "Wsymb2"), currentWeather.isDayTime()); - currentWeather.feelsLikeTemp = this.calculateAT(weatherData); + currentWeather.feelsLikeTemp = this.calculateApparentTemperature(weatherData); // Determine the precipitation amount and category and update the // weatherObject with it, the valuetype to use can be configured or uses @@ -174,7 +177,7 @@ WeatherProvider.register("smhi", { }, /** - * Takes all of the data points and converts it to one WeatherObject per day. + * Takes all the data points and converts it to one WeatherObject per day. * * @param {object[]} allWeatherData Array of weatherdata * @param {object} coordinates Coordinates of the locations of the weather @@ -191,7 +194,7 @@ WeatherProvider.register("smhi", { for (const weatherObject of allWeatherObjects) { //If its the first object or if a day/hour change we need to reset the summary object if (!currentWeather || !currentWeather.date.isSame(weatherObject.date, groupBy)) { - currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + currentWeather = new WeatherObject(); dayWeatherTypes = []; currentWeather.temperature = weatherObject.temperature; currentWeather.date = weatherObject.date; @@ -203,7 +206,7 @@ WeatherProvider.register("smhi", { result.push(currentWeather); } - //Keep track of what icons has been used for each hour of daytime and use the middle one for the forecast + //Keep track of what icons have been used for each hour of daytime and use the middle one for the forecast if (weatherObject.isDayTime()) { dayWeatherTypes.push(weatherObject.weatherType); } @@ -271,7 +274,7 @@ WeatherProvider.register("smhi", { /** * Map the icon value from SMHI to an icon that MagicMirror² understands. - * Uses different icons depending if its daytime or nighttime. + * Uses different icons depending on if its daytime or nighttime. * SMHI's description of what the numeric value means is the comment after the case. * * @param {number} input The SMHI icon value diff --git a/modules/default/weather/providers/ukmetoffice.js b/modules/default/weather/providers/ukmetoffice.js index 23ec29bfdb..d572e53eba 100644 --- a/modules/default/weather/providers/ukmetoffice.js +++ b/modules/default/weather/providers/ukmetoffice.js @@ -1,4 +1,4 @@ -/* global WeatherProvider, WeatherObject */ +/* global WeatherProvider, WeatherObject, WeatherUtils */ /* MagicMirror² * Module: Weather @@ -21,11 +21,6 @@ WeatherProvider.register("ukmetoffice", { apiKey: "" }, - units: { - imperial: "us", - metric: "si" - }, - // Overwrite the fetchCurrentWeather method. fetchCurrentWeather() { this.fetchData(this.getUrl("3hourly")) @@ -80,7 +75,7 @@ WeatherProvider.register("ukmetoffice", { * Generate a WeatherObject based on currentWeatherInformation */ generateWeatherObjectFromCurrentWeather(currentWeatherData) { - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const currentWeather = new WeatherObject(); const location = currentWeatherData.SiteRep.DV.Location; // data times are always UTC @@ -103,11 +98,11 @@ WeatherProvider.register("ukmetoffice", { if (timeInMins >= p && timeInMins - 180 < p) { // finally got the one we want, so populate weather object currentWeather.humidity = rep.H; - currentWeather.temperature = this.convertTemp(rep.T); - currentWeather.feelsLikeTemp = this.convertTemp(rep.F); + currentWeather.temperature = rep.T; + currentWeather.feelsLikeTemp = rep.F; currentWeather.precipitation = parseInt(rep.Pp); - currentWeather.windSpeed = this.convertWindSpeed(rep.S); - currentWeather.windDirection = this.convertWindDirection(rep.D); + currentWeather.windSpeed = WeatherUtils.convertWindToMetric(rep.S); + currentWeather.windDirection = WeatherUtils.convertWindDirection(rep.D); currentWeather.weatherType = this.convertWeatherType(rep.W); } } @@ -130,7 +125,7 @@ WeatherProvider.register("ukmetoffice", { // loop round the (5) periods getting the data // for each period array, Day is [0], Night is [1] for (const period of forecasts.SiteRep.DV.Location.Period) { - const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const weather = new WeatherObject(); // data times are always UTC const dateStr = period.value; @@ -140,8 +135,8 @@ WeatherProvider.register("ukmetoffice", { if (periodDate.isSameOrAfter(moment.utc().startOf("day"))) { // populate the weather object weather.date = moment.utc(dateStr.substr(0, 10), "YYYY-MM-DD"); - weather.minTemperature = this.convertTemp(period.Rep[1].Nm); - weather.maxTemperature = this.convertTemp(period.Rep[0].Dm); + weather.minTemperature = period.Rep[1].Nm; + weather.maxTemperature = period.Rep[0].Dm; weather.weatherType = this.convertWeatherType(period.Rep[0].W); weather.precipitation = parseInt(period.Rep[0].PPd); @@ -192,46 +187,6 @@ WeatherProvider.register("ukmetoffice", { return weatherTypes.hasOwnProperty(weatherType) ? weatherTypes[weatherType] : null; }, - /* - * Convert temp (from degrees C) if required - */ - convertTemp(tempInC) { - return this.tempUnits === "imperial" ? (tempInC * 9) / 5 + 32 : tempInC; - }, - - /* - * Convert wind speed (from mph to m/s or km/h) if required - */ - convertWindSpeed(windInMph) { - return this.windUnits === "metric" ? (this.useKmh ? windInMph * 1.60934 : windInMph / 2.23694) : windInMph; - }, - - /* - * Convert the wind direction cardinal to value - */ - convertWindDirection(windDirection) { - const windCardinals = { - N: 0, - NNE: 22, - NE: 45, - ENE: 67, - E: 90, - ESE: 112, - SE: 135, - SSE: 157, - S: 180, - SSW: 202, - SW: 225, - WSW: 247, - W: 270, - WNW: 292, - NW: 315, - NNW: 337 - }; - - return windCardinals.hasOwnProperty(windDirection) ? windCardinals[windDirection] : null; - }, - /** * Generates an url with api parameters based on the config. * diff --git a/modules/default/weather/providers/ukmetofficedatahub.js b/modules/default/weather/providers/ukmetofficedatahub.js index 216f661978..049f9c4da3 100644 --- a/modules/default/weather/providers/ukmetofficedatahub.js +++ b/modules/default/weather/providers/ukmetofficedatahub.js @@ -20,11 +20,9 @@ * weatherProvider: "ukmetofficedatahub", * apiBase: "https://api-metoffice.apiconnect.ibmcloud.com/metoffice/production/v0/forecasts/point/", * apiKey: "[YOUR API KEY]", - * apiSecret: "[YOUR API SECRET]]", + * apiSecret: "[YOUR API SECRET]", * lat: [LATITUDE (DECIMAL)], - * lon: [LONGITUDE (DECIMAL)], - * windUnits: "mps" | "kph" | "mph" (default) - * tempUnits: "imperial" | "metric" (default) + * lon: [LONGITUDE (DECIMAL)] * * At time of writing, free accounts are limited to 360 requests a day per service (hourly, 3hourly, daily); take this in mind when * setting your update intervals. For reference, 360 requests per day is once every 4 minutes. @@ -51,8 +49,7 @@ WeatherProvider.register("ukmetofficedatahub", { apiKey: "", apiSecret: "", lat: 0, - lon: 0, - windUnits: "mph" + lon: 0 }, // Build URL with query strings according to DataHub API (https://metoffice.apiconnect.ibmcloud.com/metoffice/production/api) @@ -89,7 +86,7 @@ WeatherProvider.register("ukmetofficedatahub", { fetchCurrentWeather() { this.fetchWeather(this.getUrl("hourly"), this.getHeaders()) .then((data) => { - // Check data is useable + // Check data is usable 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? @@ -109,13 +106,13 @@ WeatherProvider.register("ukmetofficedatahub", { // Catch any error(s) .catch((error) => Log.error("Could not load data: " + error.message)) - // Let the module know there're new data available + // Let the module know there is data available .finally(() => this.updateAvailable()); }, // Create a WeatherObject using current weather data (data for the current hour) generateWeatherObjectFromCurrentWeather(currentWeatherData) { - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const currentWeather = new WeatherObject(); // Extract the actual forecasts let forecastDataHours = currentWeatherData.features[0].properties.timeSeries; @@ -128,19 +125,19 @@ WeatherProvider.register("ukmetofficedatahub", { let forecastTime = moment.utc(forecastDataHours[hour].time); if (nowUtc.isSameOrAfter(forecastTime) && nowUtc.isBefore(moment(forecastTime.add(1, "h")))) { currentWeather.date = forecastTime; - currentWeather.windSpeed = this.convertWindSpeed(forecastDataHours[hour].windSpeed10m); + currentWeather.windSpeed = forecastDataHours[hour].windSpeed10m; currentWeather.windDirection = forecastDataHours[hour].windDirectionFrom10m; - currentWeather.temperature = this.convertTemp(forecastDataHours[hour].screenTemperature); - currentWeather.minTemperature = this.convertTemp(forecastDataHours[hour].minScreenAirTemp); - currentWeather.maxTemperature = this.convertTemp(forecastDataHours[hour].maxScreenAirTemp); + currentWeather.temperature = forecastDataHours[hour].screenTemperature; + currentWeather.minTemperature = forecastDataHours[hour].minScreenAirTemp; + currentWeather.maxTemperature = forecastDataHours[hour].maxScreenAirTemp; currentWeather.weatherType = this.convertWeatherType(forecastDataHours[hour].significantWeatherCode); currentWeather.humidity = forecastDataHours[hour].screenRelativeHumidity; currentWeather.rain = forecastDataHours[hour].totalPrecipAmount; currentWeather.snow = forecastDataHours[hour].totalSnowAmount; currentWeather.precipitation = forecastDataHours[hour].probOfPrecipitation; - currentWeather.feelsLikeTemp = this.convertTemp(forecastDataHours[hour].feelsLikeTemperature); + currentWeather.feelsLikeTemp = forecastDataHours[hour].feelsLikeTemperature; - // Pass on full details so they can be used in custom templates + // 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) currentWeather.rawData = forecastDataHours[hour]; } @@ -148,7 +145,7 @@ WeatherProvider.register("ukmetofficedatahub", { // Determine the sunrise/sunset times - (still) not supplied in UK Met Office data // Passes {longitude, latitude} to SunCalc, could pass height to, but - // SunCalc.getTimes doesnt take that into account + // SunCalc.getTimes doesn't take that into account currentWeather.updateSunTime(this.config.lat, this.config.lon); return currentWeather; @@ -158,7 +155,7 @@ WeatherProvider.register("ukmetofficedatahub", { fetchWeatherForecast() { this.fetchWeather(this.getUrl("daily"), this.getHeaders()) .then((data) => { - // Check data is useable + // Check data is usable 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? @@ -178,7 +175,7 @@ WeatherProvider.register("ukmetofficedatahub", { // Catch any error(s) .catch((error) => Log.error("Could not load data: " + error.message)) - // Let the module know there're new data available + // Let the module know there is new data available .finally(() => this.updateAvailable()); }, @@ -194,7 +191,7 @@ WeatherProvider.register("ukmetofficedatahub", { // Go through each day in the forecasts for (let day in forecastDataDays) { - const forecastWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const forecastWeather = new WeatherObject(); // Get date of forecast let forecastDate = moment.utc(forecastDataDays[day].time); @@ -202,11 +199,11 @@ WeatherProvider.register("ukmetofficedatahub", { // Check if forecast is for today or in the future (i.e., ignore yesterday's forecast) if (forecastDate.isSameOrAfter(today)) { forecastWeather.date = forecastDate; - forecastWeather.minTemperature = this.convertTemp(forecastDataDays[day].nightMinScreenTemperature); - forecastWeather.maxTemperature = this.convertTemp(forecastDataDays[day].dayMaxScreenTemperature); + forecastWeather.minTemperature = forecastDataDays[day].nightMinScreenTemperature; + forecastWeather.maxTemperature = forecastDataDays[day].dayMaxScreenTemperature; // Using daytime forecast values - forecastWeather.windSpeed = this.convertWindSpeed(forecastDataDays[day].midday10MWindSpeed); + forecastWeather.windSpeed = forecastDataDays[day].midday10MWindSpeed; forecastWeather.windDirection = forecastDataDays[day].midday10MWindDirection; forecastWeather.weatherType = this.convertWeatherType(forecastDataDays[day].daySignificantWeatherCode); forecastWeather.precipitation = forecastDataDays[day].dayProbabilityOfPrecipitation; @@ -214,9 +211,9 @@ WeatherProvider.register("ukmetofficedatahub", { forecastWeather.humidity = forecastDataDays[day].middayRelativeHumidity; forecastWeather.rain = forecastDataDays[day].dayProbabilityOfRain; forecastWeather.snow = forecastDataDays[day].dayProbabilityOfSnow; - forecastWeather.feelsLikeTemp = this.convertTemp(forecastDataDays[day].dayMaxFeelsLikeTemp); + forecastWeather.feelsLikeTemp = forecastDataDays[day].dayMaxFeelsLikeTemp; - // Pass on full details so they can be used in custom templates + // 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]; @@ -232,27 +229,6 @@ WeatherProvider.register("ukmetofficedatahub", { this.fetchedLocationName = name; }, - // Convert temperatures to Fahrenheit (from degrees C), if required - convertTemp(tempInC) { - return this.config.tempUnits === "imperial" ? (tempInC * 9) / 5 + 32 : tempInC; - }, - - // Convert wind speed from metres per second - // To keep the supplied metres per second units, use "mps" - // 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") { - return windInMpS; - } - - if (this.config.windUnits === "kph" || this.config.windUnits === "metric" || this.config.useKmh) { - return windInMpS * 3.6; - } - - return windInMpS * 2.23694; - }, - // Match the Met Office "significant weather code" to a weathericons.css icon // Use: https://metoffice.apiconnect.ibmcloud.com/metoffice/production/node/264 // and: https://erikflowers.github.io/weather-icons/ diff --git a/modules/default/weather/providers/weatherbit.js b/modules/default/weather/providers/weatherbit.js index 66d496a336..75f49a6984 100644 --- a/modules/default/weather/providers/weatherbit.js +++ b/modules/default/weather/providers/weatherbit.js @@ -23,11 +23,6 @@ WeatherProvider.register("weatherbit", { lon: 0 }, - units: { - imperial: "I", - metric: "M" - }, - fetchedLocation: function () { return this.fetchedLocationName || ""; }, @@ -95,8 +90,7 @@ WeatherProvider.register("weatherbit", { // Create a URL from the config and base URL. getUrl() { - const units = this.units[this.config.units] || "auto"; - return `${this.config.apiBase}${this.config.weatherEndpoint}?lat=${this.config.lat}&lon=${this.config.lon}&units=${units}&key=${this.config.apiKey}`; + return `${this.config.apiBase}${this.config.weatherEndpoint}?lat=${this.config.lat}&lon=${this.config.lon}&units=M&key=${this.config.apiKey}`; }, // Implement WeatherDay generator. @@ -106,9 +100,9 @@ WeatherProvider.register("weatherbit", { let tzOffset = d.getTimezoneOffset(); tzOffset = tzOffset * -1; - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const currentWeather = new WeatherObject(); - currentWeather.date = moment(currentWeatherData.data[0].ts, "X"); + currentWeather.date = moment.unix(currentWeatherData.data[0].ts); currentWeather.humidity = parseFloat(currentWeatherData.data[0].rh); currentWeather.temperature = parseFloat(currentWeatherData.data[0].temp); currentWeather.windSpeed = parseFloat(currentWeatherData.data[0].wind_spd); @@ -126,7 +120,7 @@ WeatherProvider.register("weatherbit", { const days = []; for (const forecast of forecasts) { - const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits); + const weather = new WeatherObject(); weather.date = moment(forecast.datetime, "YYYY-MM-DD"); weather.minTemperature = forecast.min_temp; diff --git a/modules/default/weather/providers/weatherflow.js b/modules/default/weather/providers/weatherflow.js index dc3dc19c66..d15023b5ab 100644 --- a/modules/default/weather/providers/weatherflow.js +++ b/modules/default/weather/providers/weatherflow.js @@ -1,4 +1,4 @@ -/* global WeatherProvider, WeatherObject */ +/* global WeatherProvider, WeatherObject, WeatherUtils */ /* MagicMirror² * Module: Weather @@ -23,36 +23,19 @@ WeatherProvider.register("weatherflow", { stationid: "" }, - units: { - imperial: { - temp: "f", - wind: "mph", - pressure: "hpa", - precip: "in", - distance: "mi" - }, - metric: { - temp: "c", - wind: "kph", - pressure: "mb", - precip: "mm", - distance: "km" - } - }, - fetchCurrentWeather() { this.fetchData(this.getUrl()) .then((data) => { - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const currentWeather = new WeatherObject(); currentWeather.date = moment(); currentWeather.humidity = data.current_conditions.relative_humidity; currentWeather.temperature = data.current_conditions.air_temperature; - currentWeather.windSpeed = data.current_conditions.wind_avg; + currentWeather.windSpeed = WeatherUtils.convertWindToMs(data.current_conditions.wind_avg); currentWeather.windDirection = data.current_conditions.wind_direction; currentWeather.weatherType = data.forecast.daily[0].icon; - currentWeather.sunrise = moment(data.forecast.daily[0].sunrise, "X"); - currentWeather.sunset = moment(data.forecast.daily[0].sunset, "X"); + currentWeather.sunrise = moment.unix(data.forecast.daily[0].sunrise); + currentWeather.sunset = moment.unix(data.forecast.daily[0].sunset); this.setCurrentWeather(currentWeather); }) .catch(function (request) { @@ -67,9 +50,9 @@ WeatherProvider.register("weatherflow", { const days = []; for (const forecast of data.forecast.daily) { - const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const weather = new WeatherObject(); - weather.date = moment(forecast.day_start_local, "X"); + weather.date = moment.unix(forecast.day_start_local); weather.minTemperature = forecast.air_temp_low; weather.maxTemperature = forecast.air_temp_high; weather.weatherType = forecast.icon; @@ -88,22 +71,6 @@ WeatherProvider.register("weatherflow", { // Create a URL from the config and base URL. getUrl() { - return ( - this.config.apiBase + - "better_forecast?station_id=" + - this.config.stationid + - "&units_temp=" + - this.units[this.config.units].temp + - "&units_wind=" + - this.units[this.config.units].wind + - "&units_pressure=" + - this.units[this.config.units].pressure + - "&units_precip=" + - this.units[this.config.units].precip + - "&units_distance=" + - this.units[this.config.units].distance + - "&token=" + - this.config.token - ); + return `${this.config.apiBase}better_forecast?station_id=${this.config.stationid}&units_temp=c&units_wind=kph&units_pressure=mb&units_precip=mm&units_distance=km&token=${this.config.token}`; } }); diff --git a/modules/default/weather/providers/weathergov.js b/modules/default/weather/providers/weathergov.js index 8205992423..19ce22e313 100644 --- a/modules/default/weather/providers/weathergov.js +++ b/modules/default/weather/providers/weathergov.js @@ -1,4 +1,4 @@ -/* global WeatherProvider, WeatherObject */ +/* global WeatherProvider, WeatherObject, WeatherUtils */ /* MagicMirror² * Module: Weather @@ -22,7 +22,6 @@ WeatherProvider.register("weathergov", { // Set the default config properties that is specific to this provider defaults: { apiBase: "https://api.weather.gov/points/", - weatherEndpoint: "/forecast", lat: 0, lon: 0 }, @@ -57,7 +56,7 @@ WeatherProvider.register("weathergov", { // Overwrite the fetchCurrentWeather method. fetchCurrentWeather() { if (!this.configURLs) { - Log.info("fetch wx waiting on config URLs"); + Log.info("fetchCurrentWeather: fetch wx waiting on config URLs"); return; } this.fetchData(this.stationObsURL) @@ -78,7 +77,7 @@ WeatherProvider.register("weathergov", { // Overwrite the fetchWeatherForecast method. fetchWeatherForecast() { if (!this.configURLs) { - Log.info("fetch wx waiting on config URLs"); + Log.info("fetchWeatherForecast: fetch wx waiting on config URLs"); return; } this.fetchData(this.forecastURL) @@ -96,6 +95,28 @@ WeatherProvider.register("weathergov", { .finally(() => this.updateAvailable()); }, + // Overwrite the fetchWeatherHourly method. + fetchWeatherHourly() { + if (!this.configURLs) { + Log.info("fetchWeatherHourly: fetch wx waiting on config URLs"); + return; + } + this.fetchData(this.forecastHourlyURL) + .then((data) => { + if (!data) { + // Did not receive usable new data. + // Maybe this needs a better check? + return; + } + const hourly = this.generateWeatherObjectsFromHourly(data.properties.periods); + this.setWeatherHourly(hourly); + }) + .catch(function (request) { + Log.error("Could not load data ... ", request); + }) + .finally(() => this.updateAvailable()); + }, + /** Weather.gov Specific Methods - These are not part of the default provider methods */ /* @@ -110,8 +131,8 @@ WeatherProvider.register("weathergov", { } this.fetchedLocationName = data.properties.relativeLocation.properties.city + ", " + data.properties.relativeLocation.properties.state; Log.log("Forecast location is " + this.fetchedLocationName); - this.forecastURL = data.properties.forecast; - this.forecastHourlyURL = data.properties.forecastHourly; + this.forecastURL = data.properties.forecast + "?units=si"; + this.forecastHourlyURL = data.properties.forecastHourly + "?units=si"; this.forecastGridDataURL = data.properties.forecastGridData; this.observationStationsURL = data.properties.observationStations; // with this URL, we chain another promise for the station obs URL @@ -130,14 +151,49 @@ WeatherProvider.register("weathergov", { .finally(() => { // excellent, let's fetch some actual wx data this.configURLs = true; + // handle 'forecast' config, fall back to 'current' if (config.type === "forecast") { this.fetchWeatherForecast(); + } else if (config.type === "hourly") { + this.fetchWeatherHourly(); } else { this.fetchCurrentWeather(); } }); }, + /* + * Generate a WeatherObject based on hourlyWeatherInformation + * Weather.gov API uses specific units; API does not include choice of units + * ... object needs data in units based on config! + */ + generateWeatherObjectsFromHourly(forecasts) { + const days = []; + + // variable for date + let weather = new WeatherObject(); + for (const forecast of forecasts) { + weather.date = moment(forecast.startTime.slice(0, 19)); + if (forecast.windSpeed.search(" ") < 0) { + weather.windSpeed = forecast.windSpeed; + } else { + weather.windSpeed = forecast.windSpeed.slice(0, forecast.windSpeed.search(" ")); + } + weather.windDirection = this.convertWindDirection(forecast.windDirection); + weather.temperature = forecast.temperature; + weather.tempUnits = forecast.temperatureUnit; + // use the forecast isDayTime attribute to help build the weatherType label + weather.weatherType = this.convertWeatherType(forecast.shortForecast, forecast.isDaytime); + + days.push(weather); + + weather = new WeatherObject(); + } + + // push weather information to days array + days.push(weather); + return days; + }, /* * Generate a WeatherObject based on currentWeatherInformation @@ -145,24 +201,24 @@ WeatherProvider.register("weathergov", { * ... object needs data in units based on config! */ generateWeatherObjectFromCurrentWeather(currentWeatherData) { - const currentWeather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const currentWeather = new WeatherObject(); currentWeather.date = moment(currentWeatherData.timestamp); - currentWeather.temperature = this.convertTemp(currentWeatherData.temperature.value); - currentWeather.windSpeed = this.convertSpeed(currentWeatherData.windSpeed.value); + currentWeather.temperature = currentWeatherData.temperature.value; + currentWeather.windSpeed = WeatherUtils.convertWindToMs(currentWeatherData.windSpeed.value); currentWeather.windDirection = currentWeatherData.windDirection.value; - currentWeather.minTemperature = this.convertTemp(currentWeatherData.minTemperatureLast24Hours.value); - currentWeather.maxTemperature = this.convertTemp(currentWeatherData.maxTemperatureLast24Hours.value); + currentWeather.minTemperature = currentWeatherData.minTemperatureLast24Hours.value; + currentWeather.maxTemperature = currentWeatherData.maxTemperatureLast24Hours.value; currentWeather.humidity = Math.round(currentWeatherData.relativeHumidity.value); currentWeather.rain = null; currentWeather.snow = null; currentWeather.precipitation = this.convertLength(currentWeatherData.precipitationLastHour.value); if (currentWeatherData.heatIndex.value !== null) { - currentWeather.feelsLikeTemp = this.convertTemp(currentWeatherData.heatIndex.value); + currentWeather.feelsLikeTemp = currentWeatherData.heatIndex.value; } else if (currentWeatherData.windChill.value !== null) { - currentWeather.feelsLikeTemp = this.convertTemp(currentWeatherData.windChill.value); + currentWeather.feelsLikeTemp = currentWeatherData.windChill.value; } else { - currentWeather.feelsLikeTemp = this.convertTemp(currentWeatherData.temperature.value); + currentWeather.feelsLikeTemp = currentWeatherData.temperature.value; } // determine the sunrise/sunset times - not supplied in weather.gov data currentWeather.updateSunTime(this.config.lat, this.config.lon); @@ -191,7 +247,7 @@ WeatherProvider.register("weathergov", { let maxTemp = []; // variable for date let date = ""; - let weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + let weather = new WeatherObject(); weather.precipitation = 0; for (const forecast of forecasts) { @@ -203,7 +259,7 @@ WeatherProvider.register("weathergov", { // push weather information to days array days.push(weather); // create new weather-object - weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + weather = new WeatherObject(); minTemp = []; maxTemp = []; @@ -242,26 +298,6 @@ WeatherProvider.register("weathergov", { /* * Unit conversions */ - // conversion to fahrenheit - convertTemp(temp) { - if (this.config.tempUnits === "imperial") { - return (9 / 5) * temp + 32; - } else { - return temp; - } - }, - // conversion to mph or kmh - convertSpeed(metSec) { - if (this.config.windUnits === "imperial") { - return metSec * 2.23694; - } else { - if (this.config.useKmh) { - return metSec * 3.6; - } else { - return metSec; - } - } - }, // conversion to inches convertLength(meters) { if (this.config.units === "imperial") { @@ -339,31 +375,5 @@ WeatherProvider.register("weathergov", { } return null; - }, - - /* - Convert the direction into Degrees - */ - convertWindDirection(windDirection) { - const windCardinals = { - N: 0, - NNE: 22, - NE: 45, - ENE: 67, - E: 90, - ESE: 112, - SE: 135, - SSE: 157, - S: 180, - SSW: 202, - SW: 225, - WSW: 247, - W: 270, - WNW: 292, - NW: 315, - NNW: 337 - }; - - return windCardinals.hasOwnProperty(windDirection) ? windCardinals[windDirection] : null; } }); diff --git a/modules/default/weather/providers/yr.js b/modules/default/weather/providers/yr.js new file mode 100644 index 0000000000..cc21611be3 --- /dev/null +++ b/modules/default/weather/providers/yr.js @@ -0,0 +1,626 @@ +/* global WeatherProvider, WeatherObject */ + +/* MagicMirror² + * Module: Weather + * Provider: Yr.no + * + * By Magnus Marthinsen + * MIT Licensed + * + * This class is a provider for Yr.no, a norwegian sweather service. + * + * Terms of service: https://developer.yr.no/doc/TermsOfService/ + */ +WeatherProvider.register("yr", { + providerName: "Yr", + + // Set the default config properties that is specific to this provider + defaults: { + useCorsProxy: true, + apiBase: "https://api.met.no/weatherapi", + altitude: 0, + currentForecastHours: 1 //1, 6 or 12 + }, + + start() { + if (typeof Storage === "undefined") { + //local storage unavailable + Log.error("The Yr weather provider requires local storage."); + throw new Error("Local storage not available"); + } + Log.info(`Weather provider: ${this.providerName} started.`); + }, + + fetchCurrentWeather() { + this.getCurrentWeather() + .then((currentWeather) => { + this.setCurrentWeather(currentWeather); + this.updateAvailable(); + }) + .catch((error) => { + Log.error(error); + throw new Error(error); + }); + }, + + async getCurrentWeather() { + const getRequests = [this.getWeatherData(), this.getStellarData()]; + const [weatherData, stellarData] = await Promise.all(getRequests); + if (!stellarData) { + Log.warn("No stelar data available."); + } + if (!weatherData.properties.timeseries || !weatherData.properties.timeseries[0]) { + Log.error("No weather data available."); + return; + } + const currentTime = moment(); + let forecast = weatherData.properties.timeseries[0]; + let closestTimeInPast = currentTime.diff(moment(forecast.time)); + for (const forecastTime of weatherData.properties.timeseries) { + const comparison = currentTime.diff(moment(forecastTime.time)); + if (0 < comparison && comparison < closestTimeInPast) { + closestTimeInPast = comparison; + forecast = forecastTime; + } + } + const forecastXHours = this.getForecastForXHoursFrom(forecast.data); + forecast.weatherType = this.convertWeatherType(forecastXHours.summary.symbol_code, forecast.time); + forecast.precipitation = forecastXHours.details?.precipitation_amount; + forecast.minTemperature = forecastXHours.details?.air_temperature_min; + forecast.maxTemperature = forecastXHours.details?.air_temperature_max; + return this.getWeatherDataFrom(forecast, stellarData, weatherData.properties.meta.units); + }, + + getWeatherData() { + return new Promise((resolve, reject) => { + // If a user has several Yr-modules, for instance one current and one forecast, the API calls must be synchronized across classes. + // This is to avoid multiple similar calls to the API. + let shouldWait = localStorage.getItem("yrIsFetchingWeatherData"); + if (shouldWait) { + const checkForGo = setInterval(function () { + shouldWait = localStorage.getItem("yrIsFetchingWeatherData"); + }, 100); + setTimeout(function () { + clearInterval(checkForGo); + shouldWait = false; + }, 5000); //Assume other fetch finished but failed to remove lock + const attemptFetchWeather = setInterval(() => { + if (!shouldWait) { + clearInterval(checkForGo); + clearInterval(attemptFetchWeather); + this.getWeatherDataFromYrOrCache(resolve, reject); + } + }, 100); + } else { + this.getWeatherDataFromYrOrCache(resolve, reject); + } + }); + }, + + getWeatherDataFromYrOrCache(resolve, reject) { + localStorage.setItem("yrIsFetchingWeatherData", "true"); + + let weatherData = this.getWeatherDataFromCache(); + if (this.weatherDataIsValid(weatherData)) { + localStorage.removeItem("yrIsFetchingWeatherData"); + Log.debug("Weather data found in cache."); + resolve(weatherData); + } else { + this.getWeatherDataFromYr(weatherData?.downloadedAt) + .then((weatherData) => { + Log.debug("Got weather data from yr."); + if (weatherData) { + this.cacheWeatherData(weatherData); + } else { + //Undefined if unchanged + weatherData = this.getWeatherDataFromCache(); + } + resolve(weatherData); + }) + .catch((err) => { + Log.error(err); + reject("Unable to get weather data from Yr."); + }) + .finally(() => { + localStorage.removeItem("yrIsFetchingWeatherData"); + }); + } + }, + + weatherDataIsValid(weatherData) { + return ( + weatherData && + weatherData.timeout && + 0 < moment(weatherData.timeout).diff(moment()) && + (!weatherData.geometry || !weatherData.geometry.coordinates || !weatherData.geometry.coordinates.length < 2 || (weatherData.geometry.coordinates[0] === this.config.lat && weatherData.geometry.coordinates[1] === this.config.lon)) + ); + }, + + getWeatherDataFromCache() { + const weatherData = localStorage.getItem("weatherData"); + if (weatherData) { + return JSON.parse(weatherData); + } else { + return undefined; + } + }, + + getWeatherDataFromYr(currentDataFetchedAt) { + const requestHeaders = [{ name: "Accept", value: "application/json" }]; + if (currentDataFetchedAt) { + requestHeaders.push({ name: "If-Modified-Since", value: currentDataFetchedAt }); + } + + const expectedResponseHeaders = ["expires", "date"]; + + return this.fetchData(this.getForecastUrl(), "json", requestHeaders, expectedResponseHeaders) + .then((data) => { + if (!data || !data.headers) return data; + data.timeout = data.headers.find((header) => header.name === "expires").value; + data.downloadedAt = data.headers.find((header) => header.name === "date").value; + data.headers = undefined; + return data; + }) + .catch((err) => { + Log.error("Could not load weather data.", err); + throw new Error(err); + }); + }, + + getForecastUrl() { + if (!this.config.lat) { + Log.error("Latitude not provided."); + throw new Error("Latitude not provided."); + } + if (!this.config.lon) { + Log.error("Longitude not provided."); + throw new Error("Longitude not provided."); + } + + let lat = this.config.lat.toString(); + let lon = this.config.lon.toString(); + const altitude = this.config.altitude ?? 0; + + if (lat.includes(".") && lat.split(".")[1].length > 4) { + Log.warn("Latitude is too specific for weather data. Do not use more than four decimals. Trimming to maximum length."); + const latParts = lat.split("."); + lat = `${latParts[0]}.${latParts[1].substring(0, 4)}`; + } + if (lon.includes(".") && lon.split(".")[1].length > 4) { + Log.warn("Longitude is too specific for weather data. Do not use more than four decimals. Trimming to maximum length."); + const lonParts = lon.split("."); + lon = `${lonParts[0]}.${lonParts[1].substring(0, 4)}`; + } + + return `${this.config.apiBase}/locationforecast/2.0/complete?&altitude=${altitude}&lat=${lat}&lon=${lon}`; + }, + + cacheWeatherData(weatherData) { + localStorage.setItem("weatherData", JSON.stringify(weatherData)); + }, + + getAuthenticationString() { + if (!this.config.authenticationEmail) throw new Error("Authentication email not provided."); + return `${this.config.applicaitionName} ${this.config.authenticationEmail}`; + }, + + getStellarData() { + // If a user has several Yr-modules, for instance one current and one forecast, the API calls must be synchronized across classes. + // This is to avoid multiple similar calls to the API. + return new Promise((resolve, reject) => { + let shouldWait = localStorage.getItem("yrIsFetchingStellarData"); + if (shouldWait) { + const checkForGo = setInterval(function () { + shouldWait = localStorage.getItem("yrIsFetchingStellarData"); + }, 100); + setTimeout(function () { + clearInterval(checkForGo); + shouldWait = false; + }, 5000); //Assume other fetch finished but failed to remove lock + const attemptFetchWeather = setInterval(() => { + if (!shouldWait) { + clearInterval(checkForGo); + clearInterval(attemptFetchWeather); + this.getStellarDataFromYrOrCache(resolve, reject); + } + }, 100); + } else { + this.getStellarDataFromYrOrCache(resolve, reject); + } + }); + }, + + getStellarDataFromYrOrCache(resolve, reject) { + localStorage.setItem("yrIsFetchingStellarData", "true"); + + let stellarData = this.getStellarDataFromCache(); + const today = moment().format("YYYY-MM-DD"); + const tomorrow = moment().add(1, "days").format("YYYY-MM-DD"); + if (stellarData && stellarData.today && stellarData.today.date === today && stellarData.tomorrow && stellarData.tomorrow.date === tomorrow) { + Log.debug("Stellar data found in cache."); + localStorage.removeItem("yrIsFetchingStellarData"); + resolve(stellarData); + } else if (stellarData && stellarData.tomorrow && stellarData.tomorrow.date === today) { + Log.debug("stellar data for today found in cache, but not for tomorrow."); + stellarData.today = stellarData.tomorrow; + this.getStellarDataFromYr(tomorrow) + .then((data) => { + if (data) { + data.date = tomorrow; + stellarData.tomorrow = data; + this.cacheStellarData(stellarData); + resolve(stellarData); + } else { + reject("No stellar data returned from Yr for " + tomorrow); + } + }) + .catch((err) => { + Log.error(err); + reject("Unable to get stellar data from Yr for " + tomorrow); + }) + .finally(() => { + localStorage.removeItem("yrIsFetchingStellarData"); + }); + } else { + this.getStellarDataFromYr(today, 2) + .then((stellarData) => { + if (stellarData) { + stellarData = { + today: stellarData + }; + stellarData.tomorrow = Object.assign({}, stellarData.today); + stellarData.today.date = today; + stellarData.tomorrow.date = tomorrow; + this.cacheStellarData(stellarData); + resolve(stellarData); + } else { + Log.error("Something went wrong when fetching stellar data. Responses: " + stellarData); + reject(stellarData); + } + }) + .catch((err) => { + Log.error(err); + reject("Unable to get stellar data from Yr."); + }) + .finally(() => { + localStorage.removeItem("yrIsFetchingStellarData"); + }); + } + }, + + getStellarDataFromCache() { + const stellarData = localStorage.getItem("stellarData"); + if (stellarData) { + return JSON.parse(stellarData); + } else { + return undefined; + } + }, + + getStellarDataFromYr(date, days = 1) { + const requestHeaders = [{ name: "Accept", value: "application/json" }]; + return this.fetchData(this.getStellarDatatUrl(date, days), "json", requestHeaders) + .then((data) => { + Log.debug("Got stellar data from yr."); + return data; + }) + .catch((err) => { + Log.error("Could not load weather data.", err); + throw new Error(err); + }); + }, + + getStellarDatatUrl(date, days) { + if (!this.config.lat) { + Log.error("Latitude not provided."); + throw new Error("Latitude not provided."); + } + if (!this.config.lon) { + Log.error("Longitude not provided."); + throw new Error("Longitude not provided."); + } + + let lat = this.config.lat.toString(); + let lon = this.config.lon.toString(); + const altitude = this.config.altitude ?? 0; + + if (lat.includes(".") && lat.split(".")[1].length > 4) { + Log.warn("Latitude is too specific for stellar data. Do not use more than four decimals. Trimming to maximum length."); + const latParts = lat.split("."); + lat = `${latParts[0]}.${latParts[1].substring(0, 4)}`; + } + if (lon.includes(".") && lon.split(".")[1].length > 4) { + Log.warn("Longitude is too specific for stellar data. Do not use more than four decimals. Trimming to maximum length."); + const lonParts = lon.split("."); + lon = `${lonParts[0]}.${lonParts[1].substring(0, 4)}`; + } + + let utcOffset = moment().utcOffset() / 60; + let utcOffsetPrefix = "%2B"; + if (utcOffset < 0) { + utcOffsetPrefix = "-"; + } + utcOffset = Math.abs(utcOffset); + let minutes = "00"; + if (utcOffset % 1 !== 0) { + minutes = "30"; + } + let hours = Math.floor(utcOffset).toString(); + if (hours.length < 2) { + hours = `0${hours}`; + } + + return `${this.config.apiBase}/sunrise/2.0/.json?date=${date}&days=${days}&height=${altitude}&lat=${lat}&lon=${lon}&offset=${utcOffsetPrefix}${hours}%3A${minutes}`; + }, + + cacheStellarData(data) { + localStorage.setItem("stellarData", JSON.stringify(data)); + }, + + getWeatherDataFrom(forecast, stellarData, units) { + const weather = new WeatherObject(this.config.units, this.config.tempUnits, this.config.windUnits, this.config.useKmh); + const stellarTimesToday = stellarData?.today ? this.getStellarTimesFrom(stellarData.today, moment().format("YYYY-MM-DD")) : undefined; + const stellarTimesTomorrow = stellarData?.tomorrow ? this.getStellarTimesFrom(stellarData.tomorrow, moment().add(1, "days").format("YYYY-MM-DD")) : undefined; + + weather.date = moment(forecast.time); + weather.windSpeed = forecast.data.instant.details.wind_speed; + weather.windDirection = (forecast.data.instant.details.wind_from_direction + 180) % 360; + weather.temperature = forecast.data.instant.details.air_temperature; + weather.minTemperature = forecast.minTemperature; + weather.maxTemperature = forecast.maxTemperature; + weather.weatherType = forecast.weatherType; + weather.humidity = forecast.data.instant.details.relative_humidity; + weather.precipitation = forecast.precipitation; + weather.precipitationUnits = units.precipitation_amount; + + if (stellarTimesToday) { + weather.sunset = moment(stellarTimesToday.sunset.time); + weather.sunrise = weather.sunset < moment() && stellarTimesTomorrow ? moment(stellarTimesTomorrow.sunrise.time) : moment(stellarTimesToday.sunrise.time); + } + + return weather; + }, + + convertWeatherType(weatherType, weatherTime) { + const weatherHour = moment(weatherTime).format("HH"); + + const weatherTypes = { + clearsky_day: "day-sunny", + clearsky_night: "night-clear", + clearsky_polartwilight: weatherHour < 14 ? "sunrise" : "sunset", + cloudy: "cloudy", + fair_day: "day-sunny-overcast", + fair_night: "night-alt-partly-cloudy", + fair_polartwilight: "day-sunny-overcast", + fog: "fog", + heavyrain: "rain", // Possibly raindrops or raindrop + heavyrainandthunder: "thunderstorm", + heavyrainshowers_day: "day-rain", + heavyrainshowers_night: "night-alt-rain", + heavyrainshowers_polartwilight: "day-rain", + heavyrainshowersandthunder_day: "day-thunderstorm", + heavyrainshowersandthunder_night: "night-alt-thunderstorm", + heavyrainshowersandthunder_polartwilight: "day-thunderstorm", + heavysleet: "sleet", + heavysleetandthunder: "day-sleet-storm", + heavysleetshowers_day: "day-sleet", + heavysleetshowers_night: "night-alt-sleet", + heavysleetshowers_polartwilight: "day-sleet", + heavysleetshowersandthunder_day: "day-sleet-storm", + heavysleetshowersandthunder_night: "night-alt-sleet-storm", + heavysleetshowersandthunder_polartwilight: "day-sleet-storm", + heavysnow: "snow-wind", + heavysnowandthunder: "day-snow-thunderstorm", + heavysnowshowers_day: "day-snow-wind", + heavysnowshowers_night: "night-alt-snow-wind", + heavysnowshowers_polartwilight: "day-snow-wind", + heavysnowshowersandthunder_day: "day-snow-thunderstorm", + heavysnowshowersandthunder_night: "night-alt-snow-thunderstorm", + heavysnowshowersandthunder_polartwilight: "day-snow-thunderstorm", + lightrain: "rain-mix", + lightrainandthunder: "thunderstorm", + lightrainshowers_day: "day-rain-mix", + lightrainshowers_night: "night-alt-rain-mix", + lightrainshowers_polartwilight: "day-rain-mix", + lightrainshowersandthunder_day: "thunderstorm", + lightrainshowersandthunder_night: "thunderstorm", + lightrainshowersandthunder_polartwilight: "thunderstorm", + lightsleet: "day-sleet", + lightsleetandthunder: "day-sleet-storm", + lightsleetshowers_day: "day-sleet", + lightsleetshowers_night: "night-alt-sleet", + lightsleetshowers_polartwilight: "day-sleet", + lightsnow: "snowflake-cold", + lightsnowandthunder: "day-snow-thunderstorm", + lightsnowshowers_day: "day-snow-wind", + lightsnowshowers_night: "night-alt-snow-wind", + lightsnowshowers_polartwilight: "day-snow-wind", + lightssleetshowersandthunder_day: "day-sleet-storm", + lightssleetshowersandthunder_night: "night-alt-sleet-storm", + lightssleetshowersandthunder_polartwilight: "day-sleet-storm", + lightssnowshowersandthunder_day: "day-snow-thunderstorm", + lightssnowshowersandthunder_night: "night-alt-snow-thunderstorm", + lightssnowshowersandthunder_polartwilight: "day-snow-thunderstorm", + partlycloudy_day: "day-cloudy", + partlycloudy_night: "night-alt-cloudy", + partlycloudy_polartwilight: "day-cloudy", + rain: "rain", + rainandthunder: "thunderstorm", + rainshowers_day: "day-rain", + rainshowers_night: "night-alt-rain", + rainshowers_polartwilight: "day-rain", + rainshowersandthunder_day: "thunderstorm", + rainshowersandthunder_night: "lightning", + rainshowersandthunder_polartwilight: "thunderstorm", + sleet: "sleet", + sleetandthunder: "day-sleet-storm", + sleetshowers_day: "day-sleet", + sleetshowers_night: "night-alt-sleet", + sleetshowers_polartwilight: "day-sleet", + sleetshowersandthunder_day: "day-sleet-storm", + sleetshowersandthunder_night: "night-alt-sleet-storm", + sleetshowersandthunder_polartwilight: "day-sleet-storm", + snow: "snowflake-cold", + snowandthunder: "lightning", + snowshowers_day: "day-snow-wind", + snowshowers_night: "night-alt-snow-wind", + snowshowers_polartwilight: "day-snow-wind", + snowshowersandthunder_day: "day-snow-thunderstorm", + snowshowersandthunder_night: "night-alt-snow-thunderstorm", + snowshowersandthunder_polartwilight: "day-snow-thunderstorm" + }; + + return weatherTypes.hasOwnProperty(weatherType) ? weatherTypes[weatherType] : null; + }, + + getStellarTimesFrom(stellarData, date) { + for (const time of stellarData.location.time) { + if (time.date === date) { + return time; + } + } + return undefined; + }, + + getForecastForXHoursFrom(weather) { + if (this.config.currentForecastHours === 1) { + if (weather.next_1_hours) { + return weather.next_1_hours; + } else if (weather.next_6_hours) { + return weather.next_6_hours; + } else { + return weather.next_12_hours; + } + } else if (this.config.currentForecastHours === 6) { + if (weather.next_6_hours) { + return weather.next_6_hours; + } else if (weather.next_12_hours) { + return weather.next_12_hours; + } else { + return weather.next_1_hours; + } + } else { + if (weather.next_12_hours) { + return weather.next_12_hours; + } else if (weather.next_6_hours) { + return weather.next_6_hours; + } else { + return weather.next_1_hours; + } + } + }, + + fetchWeatherHourly() { + this.getWeatherForecast("hourly") + .then((forecast) => { + this.setWeatherHourly(forecast); + this.updateAvailable(); + }) + .catch((error) => { + Log.error(error); + throw new Error(error); + }); + }, + + async getWeatherForecast(type) { + const getRequests = [this.getWeatherData(), this.getStellarData()]; + const [weatherData, stellarData] = await Promise.all(getRequests); + if (!weatherData.properties.timeseries || !weatherData.properties.timeseries[0]) { + Log.error("No weather data available."); + return; + } + if (!stellarData) { + Log.warn("No stelar data available."); + } + let forecasts; + switch (type) { + case "hourly": + forecasts = this.getHourlyForecastFrom(weatherData); + break; + case "daily": + default: + forecasts = this.getDailyForecastFrom(weatherData); + break; + } + const series = []; + for (const forecast of forecasts) { + series.push(this.getWeatherDataFrom(forecast, stellarData, weatherData.properties.meta.units)); + } + return series; + }, + + getHourlyForecastFrom(weatherData) { + const series = []; + + for (const forecast of weatherData.properties.timeseries) { + forecast.symbol = forecast.data.next_1_hours?.summary?.symbol_code; + forecast.precipitation = forecast.data.next_1_hours?.details?.precipitation_amount; + forecast.minTemperature = forecast.data.next_1_hours?.details?.air_temperature_min; + forecast.maxTemperature = forecast.data.next_1_hours?.details?.air_temperature_max; + forecast.weatherType = this.convertWeatherType(forecast.symbol, forecast.time); + series.push(forecast); + } + return series; + }, + + getDailyForecastFrom(weatherData) { + const series = []; + + const days = weatherData.properties.timeseries.reduce(function (days, forecast) { + const date = moment(forecast.time).format("YYYY-MM-DD"); + days[date] = days[date] || []; + days[date].push(forecast); + return days; + }, Object.create(null)); + + Object.keys(days).forEach(function (time, index) { + let minTemperature = undefined; + let maxTemperature = undefined; + + //Default to first entry + let forecast = days[time][0]; + forecast.symbol = forecast.data.next_12_hours?.summary?.symbol_code; + forecast.precipitation = forecast.data.next_12_hours?.details?.precipitation_amount; + + //Coming days + let forecastDiffToEight = undefined; + for (const timeseries of days[time]) { + if (!timeseries.data.next_6_hours) continue; //next_6_hours has the most data + + if (!minTemperature || timeseries.data.next_6_hours.details.air_temperature_min < minTemperature) minTemperature = timeseries.data.next_6_hours.details.air_temperature_min; + if (!maxTemperature || maxTemperature < timeseries.data.next_6_hours.details.air_temperature_max) maxTemperature = timeseries.data.next_6_hours.details.air_temperature_max; + + let closestTime = Math.abs(moment(timeseries.time).local().set({ hour: 8, minute: 0, second: 0, millisecond: 0 }).diff(moment(timeseries.time).local())); + if ((forecastDiffToEight === undefined || closestTime < forecastDiffToEight) && timeseries.data.next_12_hours) { + forecastDiffToEight = closestTime; + forecast = timeseries; + } + } + const forecastXHours = forecast.data.next_12_hours ?? forecast.data.next_6_hours ?? forecast.data.next_1_hours; + if (forecastXHours) { + forecast.symbol = forecastXHours.summary?.symbol_code; + forecast.precipitation = forecastXHours.details?.precipitation_amount; + forecast.minTemperature = minTemperature; + forecast.maxTemperature = maxTemperature; + + series.push(forecast); + } + }); + for (const forecast of series) { + forecast.weatherType = this.convertWeatherType(forecast.symbol, forecast.time); + } + return series; + }, + + fetchWeatherForecast() { + this.getWeatherForecast("daily") + .then((forecast) => { + this.setWeatherForecast(forecast); + this.updateAvailable(); + }) + .catch((error) => { + Log.error(error); + throw new Error(error); + }); + } +}); diff --git a/modules/default/weather/weather.js b/modules/default/weather/weather.js index 6a02d182f9..ab989f96ab 100644 --- a/modules/default/weather/weather.js +++ b/modules/default/weather/weather.js @@ -1,4 +1,4 @@ -/* global WeatherProvider */ +/* global WeatherProvider, WeatherUtils */ /* MagicMirror² * Module: Weather @@ -13,7 +13,6 @@ Module.register("weather", { roundTemp: false, type: "current", // current, forecast, daily (equivalent to forecast), hourly (only with OpenWeatherMap /onecall endpoint) units: config.units, - useKmh: false, tempUnits: config.units, windUnits: config.units, updateInterval: 10 * 60 * 1000, // every 10 minutes @@ -23,7 +22,6 @@ Module.register("weather", { showPeriodUpper: false, showWindDirection: true, showWindDirectionAsArrow: false, - useBeaufort: true, lang: config.language, showHumidity: false, showSun: true, @@ -60,7 +58,7 @@ Module.register("weather", { // Return the scripts that are necessary for the weather module. getScripts: function () { - return ["moment.js", "weatherprovider.js", "weatherobject.js", "suncalc.js", this.file("providers/" + this.config.weatherProvider.toLowerCase() + ".js")]; + return ["moment.js", this.file("../utils.js"), "weatherutils.js", "weatherprovider.js", "weatherobject.js", "suncalc.js", this.file("providers/" + this.config.weatherProvider.toLowerCase() + ".js")]; }, // Override getHeader method. @@ -77,6 +75,14 @@ Module.register("weather", { start: function () { moment.locale(this.config.lang); + if (this.config.useKmh) { + Log.warn("Your are using the deprecated config values 'useKmh'. Please switch to windUnits!"); + this.windUnits = "kmh"; + } else if (this.config.useBeaufort) { + Log.warn("Your are using the deprecated config values 'useBeaufort'. Please switch to windUnits!"); + this.windUnits = "beaufort"; + } + // Initialize the weather provider. this.weatherProvider = WeatherProvider.initialize(this.config.weatherProvider, this); @@ -221,9 +227,7 @@ Module.register("weather", { "unit", function (value, type) { if (type === "temperature") { - if (this.config.tempUnits === "metric" || this.config.tempUnits === "imperial") { - value += "°"; - } + value = this.roundValue(WeatherUtils.convertTemp(value, this.config.tempUnits)) + "°"; if (this.config.degreeLabel) { if (this.config.tempUnits === "metric") { value += "C"; @@ -245,8 +249,9 @@ Module.register("weather", { } } else if (type === "humidity") { value += "%"; + } else if (type === "wind") { + value = WeatherUtils.convertWind(value, this.config.windUnits); } - return value; }.bind(this) ); diff --git a/modules/default/weather/weatherobject.js b/modules/default/weather/weatherobject.js index c2e6727b4a..0e28b4f20b 100644 --- a/modules/default/weather/weatherobject.js +++ b/modules/default/weather/weatherobject.js @@ -1,4 +1,4 @@ -/* global SunCalc */ +/* global SunCalc, WeatherUtils */ /* MagicMirror² * Module: Weather @@ -14,17 +14,8 @@ 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; - this.windUnits = windUnits; - this.useKmh = useKmh; + constructor() { this.date = null; this.windSpeed = null; this.windDirection = null; @@ -78,21 +69,6 @@ class WeatherObject { } } - beaufortWindSpeed() { - const windInKmh = this.windUnits === "imperial" ? this.windSpeed * 1.609344 : this.useKmh ? this.windSpeed : (this.windSpeed * 60 * 60) / 1000; - const speeds = [1, 5, 11, 19, 28, 38, 49, 61, 74, 88, 102, 117, 1000]; - for (const [index, speed] of speeds.entries()) { - if (speed > windInKmh) { - return index; - } - } - return 12; - } - - kmhWindSpeed() { - return this.windUnits === "imperial" ? this.windSpeed * 1.609344 : (this.windSpeed * 60 * 60) / 1000; - } - nextSunAction() { return moment().isBetween(this.sunrise, this.sunset) ? "sunset" : "sunrise"; } @@ -101,8 +77,8 @@ class WeatherObject { if (this.feelsLikeTemp) { return this.feelsLikeTemp; } - const windInMph = this.windUnits === "imperial" ? this.windSpeed : this.windSpeed * 2.23694; - const tempInF = this.tempUnits === "imperial" ? this.temperature : (this.temperature * 9) / 5 + 32; + const windInMph = WeatherUtils.convertWind(this.windSpeed, "imperial"); + const tempInF = WeatherUtils.convertTemp(this.temperature, "imperial"); let feelsLike = tempInF; if (windInMph > 3 && tempInF < 50) { @@ -120,7 +96,7 @@ class WeatherObject { 1.99 * Math.pow(10, -6) * tempInF * tempInF * this.humidity * this.humidity; } - return this.tempUnits === "imperial" ? feelsLike : ((feelsLike - 32) * 5) / 9; + return ((feelsLike - 32) * 5) / 9; } /** @@ -134,17 +110,17 @@ class WeatherObject { /** * Update the sunrise / sunset time depending on the location. This can be - * used if your provider doesnt provide that data by itself. Then SunCalc + * used if your provider doesn't 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"); + const now = !this.date ? new Date() : this.date.toDate(); + const times = SunCalc.getTimes(now, lat, lon); + this.sunrise = moment(times.sunrise); + this.sunset = moment(times.sunset); } /** diff --git a/modules/default/weather/weatherprovider.js b/modules/default/weather/weatherprovider.js index d24623b8a7..e7bfe5b7d7 100644 --- a/modules/default/weather/weatherprovider.js +++ b/modules/default/weather/weatherprovider.js @@ -1,4 +1,4 @@ -/* global Class */ +/* global Class, performWebRequest */ /* MagicMirror² * Module: Weather @@ -111,45 +111,23 @@ const WeatherProvider = Class.extend({ this.delegate.updateAvailable(this); }, - getCorsUrl: function () { - if (this.config.mockData || typeof this.config.useCorsProxy === "undefined" || !this.config.useCorsProxy) { - return ""; - } else { - return location.protocol + "//" + location.host + "/cors?url="; + /** + * A convenience function to make requests. + * + * @param {string} url the url to fetch from + * @param {string} type what contenttype to expect in the response, can be "json" or "xml" + * @param {Array.<{name: string, value:string}>} requestHeaders the HTTP headers to send + * @param {Array.} expectedResponseHeaders the expected HTTP headers to recieve + * @returns {Promise} resolved when the fetch is done + */ + fetchData: async function (url, type = "json", requestHeaders = undefined, expectedResponseHeaders = undefined) { + const mockData = this.config.mockData; + if (mockData) { + const data = mockData.substring(1, mockData.length - 1); + return JSON.parse(data); } - }, - - // A convenience function to make requests. It returns a promise. - fetchData: function (url, method = "GET", type = "json") { - url = this.getCorsUrl() + url; - const getData = function (mockData) { - return new Promise(function (resolve, reject) { - if (mockData) { - let data = mockData; - data = data.substring(1, data.length - 1); - resolve(JSON.parse(data)); - } else { - const request = new XMLHttpRequest(); - request.open(method, url, true); - request.onreadystatechange = function () { - if (this.readyState === 4) { - if (this.status === 200) { - if (type === "xml") { - resolve(this.responseXML); - } else { - resolve(JSON.parse(this.response)); - } - } else { - reject(request); - } - } - }; - request.send(); - } - }); - }; - - return getData(this.config.mockData); + const useCorsProxy = typeof this.config.useCorsProxy !== "undefined" && this.config.useCorsProxy; + return performWebRequest(url, type, useCorsProxy, requestHeaders, expectedResponseHeaders); } }); diff --git a/modules/default/weather/weatherutils.js b/modules/default/weather/weatherutils.js new file mode 100644 index 0000000000..c0af86afc3 --- /dev/null +++ b/modules/default/weather/weatherutils.js @@ -0,0 +1,98 @@ +/* MagicMirror² + * Weather Util Methods + * + * By Rejas + * MIT Licensed. + */ +const WeatherUtils = { + /** + * Convert wind (from m/s) to beaufort scale + * + * @param {number} speedInMS the windspeed you want to convert + * @returns {number} the speed in beaufort + */ + beaufortWindSpeed(speedInMS) { + const windInKmh = (speedInMS * 3600) / 1000; + const speeds = [1, 5, 11, 19, 28, 38, 49, 61, 74, 88, 102, 117, 1000]; + for (const [index, speed] of speeds.entries()) { + if (speed > windInKmh) { + return index; + } + } + return 12; + }, + + /** + * Convert temp (from degrees C) into imperial or metric unit depending on + * your config + * + * @param {number} tempInC the temperature in celsius you want to convert + * @param {string} unit can be 'imperial' or 'metric' + * @returns {number} the converted temperature + */ + convertTemp(tempInC, unit) { + return unit === "imperial" ? tempInC * 1.8 + 32 : tempInC; + }, + + /** + * Convert wind speed into another unit. + * + * @param {number} windInMS the windspeed in meter/sec you want to convert + * @param {string} unit can be 'beaufort', 'kmh', 'knots, 'imperial' (mph) + * or 'metric' (mps) + * @returns {number} the converted windspeed + */ + convertWind(windInMS, unit) { + switch (unit) { + case "beaufort": + return this.beaufortWindSpeed(windInMS); + case "kmh": + return (windInMS * 3600) / 1000; + case "knots": + return windInMS * 1.943844; + case "imperial": + return windInMS * 2.2369362920544; + case "metric": + default: + return windInMS; + } + }, + + /* + * Convert the wind direction cardinal to value + */ + convertWindDirection(windDirection) { + const windCardinals = { + N: 0, + NNE: 22, + NE: 45, + ENE: 67, + E: 90, + ESE: 112, + SE: 135, + SSE: 157, + S: 180, + SSW: 202, + SW: 225, + WSW: 247, + W: 270, + WNW: 292, + NW: 315, + NNW: 337 + }; + + return windCardinals.hasOwnProperty(windDirection) ? windCardinals[windDirection] : null; + }, + + convertWindToMetric(mph) { + return mph / 2.2369362920544; + }, + + convertWindToMs(kmh) { + return kmh * 0.27777777777778; + } +}; + +if (typeof module !== "undefined") { + module.exports = WeatherUtils; +} diff --git a/package-lock.json b/package-lock.json index b82132f3f4..5730fcb337 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,49 +1,48 @@ { "name": "magicmirror", - "version": "2.21.0", + "version": "2.22.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "magicmirror", - "version": "2.21.0", + "version": "2.22.0", "hasInstallScript": true, "license": "MIT", "dependencies": { "colors": "^1.4.0", - "console-stamp": "^3.0.6", - "digest-fetch": "^1.3.0", - "eslint": "^8.24.0", - "express": "^4.18.1", + "console-stamp": "^3.1.0", + "digest-fetch": "^2.0.1", + "eslint": "^8.30.0", + "express": "^4.18.2", "express-ipfilter": "^1.3.1", "feedme": "^2.0.2", - "helmet": "^6.0.0", + "helmet": "^6.0.1", "iconv-lite": "^0.6.3", "luxon": "^1.28.0", "module-alias": "^2.2.2", "moment": "^2.29.4", "node-fetch": "^2.6.7", - "node-ical": "^0.15.1", - "socket.io": "^4.5.2" + "node-ical": "^0.15.3", + "socket.io": "^4.5.4" }, "devDependencies": { "eslint-config-prettier": "^8.5.0", - "eslint-plugin-jest": "^27.0.4", - "eslint-plugin-jsdoc": "^39.3.6", + "eslint-plugin-jest": "^27.1.7", + "eslint-plugin-jsdoc": "^39.6.4", "eslint-plugin-prettier": "^4.2.1", "express-basic-auth": "^1.2.1", - "husky": "^8.0.1", - "jest": "^29.0.3", - "jsdom": "^20.0.0", + "husky": "^8.0.2", + "jest": "^29.3.1", + "jsdom": "^20.0.3", "lodash": "^4.17.21", - "nyc": "^15.1.0", - "playwright": "^1.26.1", - "prettier": "^2.7.1", + "playwright": "^1.29.1", + "prettier": "^2.8.1", "pretty-quick": "^3.1.3", - "sinon": "^14.0.0", - "stylelint": "^14.12.1", - "stylelint-config-prettier": "^9.0.3", - "stylelint-config-standard": "^28.0.0", + "sinon": "^15.0.1", + "stylelint": "^14.16.0", + "stylelint-config-prettier": "^9.0.4", + "stylelint-config-standard": "^29.0.0", "stylelint-prettier": "^2.0.0", "suncalc": "^1.9.0" }, @@ -51,7 +50,7 @@ "node": ">=14" }, "optionalDependencies": { - "electron": "^19.1.0" + "electron": "^22.0.0" } }, "node_modules/@ampproject/remapping": { @@ -80,30 +79,30 @@ } }, "node_modules/@babel/compat-data": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.3.tgz", - "integrity": "sha512-prBHMK4JYYK+wDjJF1q99KK4JLL+egWS4nmNqdlMUgCExMZ+iZW0hGhyC3VEbsPjvaN0TBhW//VIFwBrk8sEiw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", + "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/core": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz", - "integrity": "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.7.tgz", + "integrity": "sha512-t1ZjCluspe5DW24bn2Rr1CDb2v9rn/hROtg9a2tmd0+QYf4bsloYfLQzjG4qHPNMhWtKdGC33R5AxGR2Af2cBw==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.3", - "@babel/helper-compilation-targets": "^7.19.3", - "@babel/helper-module-transforms": "^7.19.0", - "@babel/helpers": "^7.19.0", - "@babel/parser": "^7.19.3", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.3", - "@babel/types": "^7.19.3", + "@babel/generator": "^7.20.7", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.20.7", + "@babel/helpers": "^7.20.7", + "@babel/parser": "^7.20.7", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.7", + "@babel/types": "^7.20.7", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", @@ -118,13 +117,19 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/core/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, "node_modules/@babel/generator": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.3.tgz", - "integrity": "sha512-fqVZnmp1ncvZU757UzDheKZpfPgatqY59XtW2/j/18H7u76akb8xqvjw82f+i2UKd/ksYsSick/BCLQUUtJ/qQ==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", + "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", "dev": true, "dependencies": { - "@babel/types": "^7.19.3", + "@babel/types": "^7.20.7", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, @@ -147,14 +152,15 @@ } }, "node_modules/@babel/helper-compilation-targets": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", - "integrity": "sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", "dev": true, "dependencies": { - "@babel/compat-data": "^7.19.3", + "@babel/compat-data": "^7.20.5", "@babel/helper-validator-option": "^7.18.6", "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", "semver": "^6.3.0" }, "engines": { @@ -211,40 +217,40 @@ } }, "node_modules/@babel/helper-module-transforms": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz", - "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.7.tgz", + "integrity": "sha512-FNdu7r67fqMUSVuQpFQGE6BPdhJIhitoxhGzDbAXNcA07uoVG37fOiMk3OSV8rEICuyG6t8LGkd9EE64qIEoIA==", "dev": true, "dependencies": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.18.6", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.7", + "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-plugin-utils": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", - "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", "dev": true, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-simple-access": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", - "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", "dev": true, "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.20.2" }, "engines": { "node": ">=6.9.0" @@ -263,9 +269,9 @@ } }, "node_modules/@babel/helper-string-parser": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", - "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", "dev": true, "engines": { "node": ">=6.9.0" @@ -290,14 +296,14 @@ } }, "node_modules/@babel/helpers": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.0.tgz", - "integrity": "sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.7.tgz", + "integrity": "sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==", "dev": true, "dependencies": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.7", + "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" @@ -389,9 +395,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.3.tgz", - "integrity": "sha512-pJ9xOlNWHiy9+FuFP09DEAFbAn4JskgRsVcc169w2xRBC3FRGuQEwjeIMMND9L2zc0iEhO/tGv4Zq+km+hxNpQ==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz", + "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -563,12 +569,12 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", - "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", "dev": true, "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.19.0" }, "engines": { "node": ">=6.9.0" @@ -578,33 +584,33 @@ } }, "node_modules/@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", "dev": true, "dependencies": { "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/traverse": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.3.tgz", - "integrity": "sha512-qh5yf6149zhq2sgIXmwjnsvmnNQC2iw70UFjp4olxucKrWd/dvlUsBI88VSLUsnMNF7/vnOiA+nk1+yLoCqROQ==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.7.tgz", + "integrity": "sha512-xueOL5+ZKX2dJbg8z8o4f4uTRTqGDRjilva9D1hiRlayJbTY8jBRL+Ph67IeRTIE439/VifHk+Z4g0SwRtQE0A==", "dev": true, "dependencies": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.3", + "@babel/generator": "^7.20.7", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.19.3", - "@babel/types": "^7.19.3", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -622,12 +628,12 @@ } }, "node_modules/@babel/types": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.3.tgz", - "integrity": "sha512-hGCaQzIY22DJlDh9CH7NOxgKkFjBk0Cw9xDO1Xmh2151ti7wiGfQ3LauXzL4HP1fmFlTX6XjpRETTpUcv7wQLw==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", + "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", "dev": true, "dependencies": { - "@babel/helper-string-parser": "^7.18.10", + "@babel/helper-string-parser": "^7.19.4", "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" }, @@ -659,31 +665,30 @@ } }, "node_modules/@electron/get": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.14.1.tgz", - "integrity": "sha512-BrZYyL/6m0ZXz/lDxy/nlVhQz+WF+iPS6qXolEU8atw7h6v1aYkjwJZ63m+bJMBTxDE66X+r2tPS4a/8C82sZw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.2.tgz", + "integrity": "sha512-eFZVFoRXb3GFGd7Ak7W4+6jBl9wBtiZ4AaYOse97ej6mKj5tkyO0dUnUChs1IhJZtx1BENo4/p4WUTXpi6vT+g==", "optional": true, "dependencies": { "debug": "^4.1.1", "env-paths": "^2.2.0", "fs-extra": "^8.1.0", - "got": "^9.6.0", + "got": "^11.8.5", "progress": "^2.0.3", "semver": "^6.2.0", "sumchecker": "^3.0.1" }, "engines": { - "node": ">=8.6" + "node": ">=12" }, "optionalDependencies": { - "global-agent": "^3.0.0", - "global-tunnel-ng": "^2.7.1" + "global-agent": "^3.0.0" } }, "node_modules/@es-joy/jsdoccomment": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.31.0.tgz", - "integrity": "sha512-tc1/iuQcnaiSIUVad72PBierDFpsxdUHtEF/OrfqvM1CBAsIoMP51j52jTMb3dXriwhieTo289InzZj72jL3EQ==", + "version": "0.36.1", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.36.1.tgz", + "integrity": "sha512-922xqFsTpHs6D0BUiG4toiyPOMc8/jafnWKxz1KWgS4XzKPy2qXf1Pe6UFuNSCQqt6tOuhAWXBNuuyUhJmw9Vg==", "dev": true, "dependencies": { "comment-parser": "1.3.1", @@ -691,18 +696,18 @@ "jsdoc-type-pratt-parser": "~3.1.0" }, "engines": { - "node": "^14 || ^16 || ^17 || ^18" + "node": "^14 || ^16 || ^17 || ^18 || ^19" } }, "node_modules/@eslint/eslintrc": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", - "integrity": "sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.0.tgz", + "integrity": "sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A==", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.4.0", - "globals": "^13.15.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -717,27 +722,18 @@ } }, "node_modules/@humanwhocodes/config-array": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.5.tgz", - "integrity": "sha512-XVVDtp+dVvRxMoxSiSfasYaG02VEe1qH5cKgMQJWhol6HwzbcqoCMJi8dAGoYAO57jhUyhI6cWuRiTcRaDaYug==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "dependencies": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", - "minimatch": "^3.0.4" + "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, - "node_modules/@humanwhocodes/gitignore-to-minimatch": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", - "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -870,16 +866,16 @@ } }, "node_modules/@jest/console": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.0.3.tgz", - "integrity": "sha512-cGg0r+klVHSYnfE977S9wmpuQ9L+iYuYgL+5bPXiUlUynLLYunRxswEmhBzvrSKGof5AKiHuTTmUKAqRcDY9dg==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.3.1.tgz", + "integrity": "sha512-IRE6GD47KwcqA09RIWrabKdHPiKDGgtAL31xDxbi/RjQMsr+lY+ppxmHwY0dUEV3qvvxZzoe5Hl0RXZJOjQNUg==", "dev": true, "dependencies": { - "@jest/types": "^29.0.3", + "@jest/types": "^29.3.1", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^29.0.3", - "jest-util": "^29.0.3", + "jest-message-util": "^29.3.1", + "jest-util": "^29.3.1", "slash": "^3.0.0" }, "engines": { @@ -887,37 +883,37 @@ } }, "node_modules/@jest/core": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.0.3.tgz", - "integrity": "sha512-1d0hLbOrM1qQE3eP3DtakeMbKTcXiXP3afWxqz103xPyddS2NhnNghS7MaXx1dcDt4/6p4nlhmeILo2ofgi8cQ==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.3.1.tgz", + "integrity": "sha512-0ohVjjRex985w5MmO5L3u5GR1O30DexhBSpuwx2P+9ftyqHdJXnk7IUWiP80oHMvt7ubHCJHxV0a0vlKVuZirw==", "dev": true, "dependencies": { - "@jest/console": "^29.0.3", - "@jest/reporters": "^29.0.3", - "@jest/test-result": "^29.0.3", - "@jest/transform": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/console": "^29.3.1", + "@jest/reporters": "^29.3.1", + "@jest/test-result": "^29.3.1", + "@jest/transform": "^29.3.1", + "@jest/types": "^29.3.1", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "ci-info": "^3.2.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.0.0", - "jest-config": "^29.0.3", - "jest-haste-map": "^29.0.3", - "jest-message-util": "^29.0.3", - "jest-regex-util": "^29.0.0", - "jest-resolve": "^29.0.3", - "jest-resolve-dependencies": "^29.0.3", - "jest-runner": "^29.0.3", - "jest-runtime": "^29.0.3", - "jest-snapshot": "^29.0.3", - "jest-util": "^29.0.3", - "jest-validate": "^29.0.3", - "jest-watcher": "^29.0.3", + "jest-changed-files": "^29.2.0", + "jest-config": "^29.3.1", + "jest-haste-map": "^29.3.1", + "jest-message-util": "^29.3.1", + "jest-regex-util": "^29.2.0", + "jest-resolve": "^29.3.1", + "jest-resolve-dependencies": "^29.3.1", + "jest-runner": "^29.3.1", + "jest-runtime": "^29.3.1", + "jest-snapshot": "^29.3.1", + "jest-util": "^29.3.1", + "jest-validate": "^29.3.1", + "jest-watcher": "^29.3.1", "micromatch": "^4.0.4", - "pretty-format": "^29.0.3", + "pretty-format": "^29.3.1", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, @@ -934,88 +930,88 @@ } }, "node_modules/@jest/environment": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.0.3.tgz", - "integrity": "sha512-iKl272NKxYNQNqXMQandAIwjhQaGw5uJfGXduu8dS9llHi8jV2ChWrtOAVPnMbaaoDhnI3wgUGNDvZgHeEJQCA==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.3.1.tgz", + "integrity": "sha512-pMmvfOPmoa1c1QpfFW0nXYtNLpofqo4BrCIk6f2kW4JFeNlHV2t3vd+3iDLf31e2ot2Mec0uqZfmI+U0K2CFag==", "dev": true, "dependencies": { - "@jest/fake-timers": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/fake-timers": "^29.3.1", + "@jest/types": "^29.3.1", "@types/node": "*", - "jest-mock": "^29.0.3" + "jest-mock": "^29.3.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.0.3.tgz", - "integrity": "sha512-6W7K+fsI23FQ01H/BWccPyDZFrnU9QlzDcKOjrNVU5L8yUORFAJJIpmyxWPW70+X624KUNqzZwPThPMX28aXEQ==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.3.1.tgz", + "integrity": "sha512-QivM7GlSHSsIAWzgfyP8dgeExPRZ9BIe2LsdPyEhCGkZkoyA+kGsoIzbKAfZCvvRzfZioKwPtCZIt5SaoxYCvg==", "dev": true, "dependencies": { - "expect": "^29.0.3", - "jest-snapshot": "^29.0.3" + "expect": "^29.3.1", + "jest-snapshot": "^29.3.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.0.3.tgz", - "integrity": "sha512-i1xUkau7K/63MpdwiRqaxgZOjxYs4f0WMTGJnYwUKubsNRZSeQbLorS7+I4uXVF9KQ5r61BUPAUMZ7Lf66l64Q==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.3.1.tgz", + "integrity": "sha512-wlrznINZI5sMjwvUoLVk617ll/UYfGIZNxmbU+Pa7wmkL4vYzhV9R2pwVqUh4NWWuLQWkI8+8mOkxs//prKQ3g==", "dev": true, "dependencies": { - "jest-get-type": "^29.0.0" + "jest-get-type": "^29.2.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.0.3.tgz", - "integrity": "sha512-tmbUIo03x0TdtcZCESQ0oQSakPCpo7+s6+9mU19dd71MptkP4zCwoeZqna23//pgbhtT1Wq02VmA9Z9cNtvtCQ==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.3.1.tgz", + "integrity": "sha512-iHTL/XpnDlFki9Tq0Q1GGuVeQ8BHZGIYsvCO5eN/O/oJaRzofG9Xndd9HuSDBI/0ZS79pg0iwn07OMTQ7ngF2A==", "dev": true, "dependencies": { - "@jest/types": "^29.0.3", + "@jest/types": "^29.3.1", "@sinonjs/fake-timers": "^9.1.2", "@types/node": "*", - "jest-message-util": "^29.0.3", - "jest-mock": "^29.0.3", - "jest-util": "^29.0.3" + "jest-message-util": "^29.3.1", + "jest-mock": "^29.3.1", + "jest-util": "^29.3.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/globals": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.0.3.tgz", - "integrity": "sha512-YqGHT65rFY2siPIHHFjuCGUsbzRjdqkwbat+Of6DmYRg5shIXXrLdZoVE/+TJ9O1dsKsFmYhU58JvIbZRU1Z9w==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.3.1.tgz", + "integrity": "sha512-cTicd134vOcwO59OPaB6AmdHQMCtWOe+/DitpTZVxWgMJ+YvXL1HNAmPyiGbSHmF/mXVBkvlm8YYtQhyHPnV6Q==", "dev": true, "dependencies": { - "@jest/environment": "^29.0.3", - "@jest/expect": "^29.0.3", - "@jest/types": "^29.0.3", - "jest-mock": "^29.0.3" + "@jest/environment": "^29.3.1", + "@jest/expect": "^29.3.1", + "@jest/types": "^29.3.1", + "jest-mock": "^29.3.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/reporters": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.0.3.tgz", - "integrity": "sha512-3+QU3d4aiyOWfmk1obDerie4XNCaD5Xo1IlKNde2yGEi02WQD+ZQD0i5Hgqm1e73sMV7kw6pMlCnprtEwEVwxw==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.3.1.tgz", + "integrity": "sha512-GhBu3YFuDrcAYW/UESz1JphEAbvUjaY2vShRZRoRY1mxpCMB3yGSJ4j9n0GxVlEOdCf7qjvUfBCrTUUqhVfbRA==", "dev": true, "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.0.3", - "@jest/test-result": "^29.0.3", - "@jest/transform": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/console": "^29.3.1", + "@jest/test-result": "^29.3.1", + "@jest/transform": "^29.3.1", + "@jest/types": "^29.3.1", "@jridgewell/trace-mapping": "^0.3.15", "@types/node": "*", "chalk": "^4.0.0", @@ -1028,13 +1024,12 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.0.3", - "jest-util": "^29.0.3", - "jest-worker": "^29.0.3", + "jest-message-util": "^29.3.1", + "jest-util": "^29.3.1", + "jest-worker": "^29.3.1", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", - "terminal-link": "^2.0.0", "v8-to-istanbul": "^9.0.1" }, "engines": { @@ -1062,9 +1057,9 @@ } }, "node_modules/@jest/source-map": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.0.0.tgz", - "integrity": "sha512-nOr+0EM8GiHf34mq2GcJyz/gYFyLQ2INDhAylrZJ9mMWoW21mLBfZa0BUVPPMxVYrLjeiRe2Z7kWXOGnS0TFhQ==", + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.2.0.tgz", + "integrity": "sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ==", "dev": true, "dependencies": { "@jridgewell/trace-mapping": "^0.3.15", @@ -1076,13 +1071,13 @@ } }, "node_modules/@jest/test-result": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.0.3.tgz", - "integrity": "sha512-vViVnQjCgTmbhDKEonKJPtcFe9G/CJO4/Np4XwYJah+lF2oI7KKeRp8t1dFvv44wN2NdbDb/qC6pi++Vpp0Dlg==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.3.1.tgz", + "integrity": "sha512-qeLa6qc0ddB0kuOZyZIhfN5q0e2htngokyTWsGriedsDhItisW7SDYZ7ceOe57Ii03sL988/03wAcBh3TChMGw==", "dev": true, "dependencies": { - "@jest/console": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/console": "^29.3.1", + "@jest/types": "^29.3.1", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -1091,14 +1086,14 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.0.3.tgz", - "integrity": "sha512-Hf4+xYSWZdxTNnhDykr8JBs0yBN/nxOXyUQWfotBUqqy0LF9vzcFB0jm/EDNZCx587znLWTIgxcokW7WeZMobQ==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.3.1.tgz", + "integrity": "sha512-IqYvLbieTv20ArgKoAMyhLHNrVHJfzO6ARZAbQRlY4UGWfdDnLlZEF0BvKOMd77uIiIjSZRwq3Jb3Fa3I8+2UA==", "dev": true, "dependencies": { - "@jest/test-result": "^29.0.3", + "@jest/test-result": "^29.3.1", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.3", + "jest-haste-map": "^29.3.1", "slash": "^3.0.0" }, "engines": { @@ -1106,22 +1101,22 @@ } }, "node_modules/@jest/transform": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.0.3.tgz", - "integrity": "sha512-C5ihFTRYaGDbi/xbRQRdbo5ddGtI4VSpmL6AIcZxdhwLbXMa7PcXxxqyI91vGOFHnn5aVM3WYnYKCHEqmLVGzg==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.3.1.tgz", + "integrity": "sha512-8wmCFBTVGYqFNLWfcOWoVuMuKYPUBTnTMDkdvFtAYELwDOl9RGwOsvQWGPFxDJ8AWY9xM/8xCXdqmPK3+Q5Lug==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", - "@jest/types": "^29.0.3", + "@jest/types": "^29.3.1", "@jridgewell/trace-mapping": "^0.3.15", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", + "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.3", - "jest-regex-util": "^29.0.0", - "jest-util": "^29.0.3", + "jest-haste-map": "^29.3.1", + "jest-regex-util": "^29.2.0", + "jest-util": "^29.3.1", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", @@ -1132,9 +1127,9 @@ } }, "node_modules/@jest/types": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.3.tgz", - "integrity": "sha512-coBJmOQvurXjN1Hh5PzF7cmsod0zLIOXpP8KD161mqNlroMhLcwpODiEzi7ZsRl5Z/AIuxpeNm8DCl43F4kz8A==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.3.1.tgz", + "integrity": "sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==", "dev": true, "dependencies": { "@jest/schemas": "^29.0.0", @@ -1186,13 +1181,13 @@ "dev": true }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", - "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "dev": true, "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, "node_modules/@nodelib/fs.scandir": { @@ -1228,24 +1223,27 @@ } }, "node_modules/@sinclair/typebox": { - "version": "0.24.43", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.43.tgz", - "integrity": "sha512-1orQTvtazZmsPeBroJjysvsOQCYV2yjWlebkSY38pl5vr2tdLjEJ+LoxITlGNZaH2RE19WlAwQMkH/7C14wLfw==", + "version": "0.24.51", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", + "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==", "dev": true }, "node_modules/@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", "optional": true, "engines": { - "node": ">=6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" } }, "node_modules/@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", "dev": true, "dependencies": { "type-detect": "4.0.8" @@ -1261,16 +1259,25 @@ } }, "node_modules/@sinonjs/samsam": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.1.1.tgz", - "integrity": "sha512-cZ7rKJTLiE7u7Wi/v9Hc2fs3Ucc3jrWeMgPHbbTCeVAB2S0wOBbYlkJVeNSL04i7fdhT8wIbDq1zhC/PXTD2SA==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-7.0.1.tgz", + "integrity": "sha512-zsAk2Jkiq89mhZovB2LLOdTCxJF4hqqTToGP0ASWlhp4I1hqOjcfmZGafXntCN7MDC6yySH0mFHrYtHceOeLmw==", "dev": true, "dependencies": { - "@sinonjs/commons": "^1.6.0", + "@sinonjs/commons": "^2.0.0", "lodash.get": "^4.4.2", "type-detect": "^4.0.8" } }, + "node_modules/@sinonjs/samsam/node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, "node_modules/@sinonjs/text-encoding": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", @@ -1283,15 +1290,15 @@ "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" }, "node_modules/@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", "optional": true, "dependencies": { - "defer-to-connect": "^1.0.1" + "defer-to-connect": "^2.0.0" }, "engines": { - "node": ">=6" + "node": ">=10" } }, "node_modules/@tootallnate/once": { @@ -1304,9 +1311,9 @@ } }, "node_modules/@types/babel__core": { - "version": "7.1.19", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", - "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", + "version": "7.1.20", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz", + "integrity": "sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==", "dev": true, "dependencies": { "@babel/parser": "^7.1.0", @@ -1336,23 +1343,38 @@ } }, "node_modules/@types/babel__traverse": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.2.tgz", - "integrity": "sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==", + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", + "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", "dev": true, "dependencies": { "@babel/types": "^7.3.0" } }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "optional": true, + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, "node_modules/@types/cookie": { "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.12", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", - "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==" + "version": "2.8.13", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", + "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "dependencies": { + "@types/node": "*" + } }, "node_modules/@types/graceful-fs": { "version": "4.1.5", @@ -1363,6 +1385,12 @@ "@types/node": "*" } }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", + "optional": true + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", @@ -1393,6 +1421,15 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/minimatch": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", @@ -1406,9 +1443,9 @@ "dev": true }, "node_modules/@types/node": { - "version": "16.11.62", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.62.tgz", - "integrity": "sha512-K/ggecSdwAAy2NUW4WKmF4Rc03GKbsfP+k326UWgckoS+Rzd2PaWbjk76dSmqdLQvLTJAO9axiTUJ6488mFsYQ==" + "version": "16.18.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.10.tgz", + "integrity": "sha512-XU1+v7h81p7145ddPfjv7jtWvkSilpcnON3mQ+bDi9Yuf7OI56efOglXRyXWgQ57xH3fEQgh7WOJMncRHVew5w==" }, "node_modules/@types/normalize-package-data": { "version": "2.4.1", @@ -1423,9 +1460,24 @@ "dev": true }, "node_modules/@types/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", + "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", + "dev": true + }, + "node_modules/@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/semver": { + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", "dev": true }, "node_modules/@types/stack-utils": { @@ -1435,9 +1487,9 @@ "dev": true }, "node_modules/@types/yargs": { - "version": "17.0.13", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz", - "integrity": "sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==", + "version": "17.0.17", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.17.tgz", + "integrity": "sha512-72bWxFKTK6uwWJAVT+3rF6Jo6RTojiJ27FQo8Rf60AL+VZbzoVPnMFhKsUnbjR8A3BTCYQ7Mv3hnl8T0A+CX9g==", "dev": true, "dependencies": { "@types/yargs-parser": "*" @@ -1449,14 +1501,23 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, + "node_modules/@types/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@typescript-eslint/scope-manager": { - "version": "5.38.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.38.1.tgz", - "integrity": "sha512-BfRDq5RidVU3RbqApKmS7RFMtkyWMM50qWnDAkKgQiezRtLKsoyRKIvz1Ok5ilRWeD9IuHvaidaLxvGx/2eqTQ==", + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.0.tgz", + "integrity": "sha512-dvJab4bFf7JVvjPuh3sfBUWsiD73aiftKBpWSfi3sUkysDQ4W8x+ZcFpNp7Kgv0weldhpmMOZBjx1wKN8uWvAw==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.38.1", - "@typescript-eslint/visitor-keys": "5.38.1" + "@typescript-eslint/types": "5.47.0", + "@typescript-eslint/visitor-keys": "5.47.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1467,9 +1528,9 @@ } }, "node_modules/@typescript-eslint/types": { - "version": "5.38.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.38.1.tgz", - "integrity": "sha512-QTW1iHq1Tffp9lNfbfPm4WJabbvpyaehQ0SrvVK2yfV79SytD9XDVxqiPvdrv2LK7DGSFo91TB2FgWanbJAZXg==", + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.0.tgz", + "integrity": "sha512-eslFG0Qy8wpGzDdYKu58CEr3WLkjwC5Usa6XbuV89ce/yN5RITLe1O8e+WFEuxnfftHiJImkkOBADj58ahRxSg==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1480,13 +1541,13 @@ } }, "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.38.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.38.1.tgz", - "integrity": "sha512-99b5e/Enoe8fKMLdSuwrfH/C0EIbpUWmeEKHmQlGZb8msY33qn1KlkFww0z26o5Omx7EVjzVDCWEfrfCDHfE7g==", + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.0.tgz", + "integrity": "sha512-LxfKCG4bsRGq60Sqqu+34QT5qT2TEAHvSCCJ321uBWywgE2dS0LKcu5u+3sMGo+Vy9UmLOhdTw5JHzePV/1y4Q==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.38.1", - "@typescript-eslint/visitor-keys": "5.38.1", + "@typescript-eslint/types": "5.47.0", + "@typescript-eslint/visitor-keys": "5.47.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -1506,10 +1567,22 @@ } } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -1521,18 +1594,26 @@ "node": ">=10" } }, + "node_modules/@typescript-eslint/typescript-estree/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/@typescript-eslint/utils": { - "version": "5.38.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.38.1.tgz", - "integrity": "sha512-oIuUiVxPBsndrN81oP8tXnFa/+EcZ03qLqPDfSZ5xIJVm7A9V0rlkQwwBOAGtrdN70ZKDlKv+l1BeT4eSFxwXA==", + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.47.0.tgz", + "integrity": "sha512-U9xcc0N7xINrCdGVPwABjbAKqx4GK67xuMV87toI+HUqgXj26m6RBp9UshEXcTrgCkdGYFzgKLt8kxu49RilDw==", "dev": true, "dependencies": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.38.1", - "@typescript-eslint/types": "5.38.1", - "@typescript-eslint/typescript-estree": "5.38.1", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.47.0", + "@typescript-eslint/types": "5.47.0", + "@typescript-eslint/typescript-estree": "5.47.0", "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" + "eslint-utils": "^3.0.0", + "semver": "^7.3.7" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -1567,13 +1648,46 @@ "node": ">=4.0" } }, + "node_modules/@typescript-eslint/utils/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/utils/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/@typescript-eslint/visitor-keys": { - "version": "5.38.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.38.1.tgz", - "integrity": "sha512-bSHr1rRxXt54+j2n4k54p4fj8AHJ49VDWtjpImOpzQj4qjAiOpPni+V1Tyajh19Api1i844F757cur8wH3YvOA==", + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.0.tgz", + "integrity": "sha512-ByPi5iMa6QqDXe/GmT/hR6MZtVPi0SqMQPDx15FczCBXJo/7M8T88xReOALAfpBLm+zxpPfmhuEvPb577JRAEg==", "dev": true, "dependencies": { - "@typescript-eslint/types": "5.38.1", + "@typescript-eslint/types": "5.47.0", "eslint-visitor-keys": "^3.3.0" }, "engines": { @@ -1603,9 +1717,9 @@ } }, "node_modules/acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==", + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==", "bin": { "acorn": "bin/acorn" }, @@ -1614,25 +1728,13 @@ } }, "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", "dev": true, "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "node_modules/acorn-globals/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" } }, "node_modules/acorn-jsx": { @@ -1644,9 +1746,9 @@ } }, "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true, "engines": { "node": ">=0.4.0" @@ -1664,19 +1766,6 @@ "node": ">= 6.0.0" } }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -1742,9 +1831,9 @@ } }, "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "dependencies": { "normalize-path": "^3.0.0", @@ -1754,24 +1843,6 @@ "node": ">= 8" } }, - "node_modules/append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", - "dev": true, - "dependencies": { - "default-require-extensions": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", - "dev": true - }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -1795,6 +1866,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, "engines": { "node": ">=8" } @@ -1820,27 +1892,28 @@ "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "node_modules/axios": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", - "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.1.3.tgz", + "integrity": "sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA==", "dependencies": { - "follow-redirects": "^1.14.8" + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, "node_modules/babel-jest": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.0.3.tgz", - "integrity": "sha512-ApPyHSOhS/sVzwUOQIWJmdvDhBsMG01HX9z7ogtkp1TToHGGUWFlnXJUIzCgKPSfiYLn3ibipCYzsKSURHEwLg==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.3.1.tgz", + "integrity": "sha512-aard+xnMoxgjwV70t0L6wkW/3HQQtV+O0PEimxKgzNqCJnbYmroPojdP2tqKSOAt8QAKV/uSZU8851M7B5+fcA==", "dev": true, "dependencies": { - "@jest/transform": "^29.0.3", + "@jest/transform": "^29.3.1", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.0.2", + "babel-preset-jest": "^29.2.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" @@ -1869,9 +1942,9 @@ } }, "node_modules/babel-plugin-jest-hoist": { - "version": "29.0.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.0.2.tgz", - "integrity": "sha512-eBr2ynAEFjcebVvu8Ktx580BD1QKCrBG1XwEUTXJe285p9HA/4hOhfWCFRQhTKSyBV0VzjhG7H91Eifz9s29hg==", + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.2.0.tgz", + "integrity": "sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA==", "dev": true, "dependencies": { "@babel/template": "^7.3.3", @@ -1907,12 +1980,12 @@ } }, "node_modules/babel-preset-jest": { - "version": "29.0.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.0.2.tgz", - "integrity": "sha512-BeVXp7rH5TK96ofyEnHjznjLMQ2nAeDJ+QzxKnHAAMs0RgrQsCywjAN8m4mOm5Di0pxU//3AoEeJJrerMH5UeA==", + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.2.0.tgz", + "integrity": "sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA==", "dev": true, "dependencies": { - "babel-plugin-jest-hoist": "^29.0.2", + "babel-plugin-jest-hoist": "^29.2.0", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { @@ -1959,9 +2032,9 @@ "dev": true }, "node_modules/body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "dependencies": { "bytes": "3.1.2", "content-type": "~1.0.4", @@ -1971,7 +2044,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.10.3", + "qs": "6.11.0", "raw-body": "2.5.1", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -2024,6 +2097,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, "dependencies": { "fill-range": "^7.0.1" }, @@ -2031,12 +2105,6 @@ "node": ">=8" } }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, "node_modules/browserslist": { "version": "4.21.4", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", @@ -2087,7 +2155,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "devOptional": true + "dev": true }, "node_modules/bytes": { "version": "3.1.2", @@ -2097,75 +2165,33 @@ "node": ">= 0.8" } }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "optional": true, + "engines": { + "node": ">=10.6.0" + } + }, "node_modules/cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", + "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", "optional": true, "dependencies": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", + "keyv": "^4.0.0", "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cacheable-request/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==", - "optional": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cacheable-request/node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "optional": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/caching-transform": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", - "dev": true, - "dependencies": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/caching-transform/node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, "node_modules/call-bind": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", @@ -2212,10 +2238,19 @@ "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.30001412", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001412.tgz", - "integrity": "sha512-+TeEIee1gS5bYOiuf+PS/kp2mrXic37Hl66VY6EAfxasIk5fELTktK2oOezYed12H8w7jt3s512PpulQidPjwA==", + "version": "1.0.30001441", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001441.tgz", + "integrity": "sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg==", "dev": true, "funding": [ { @@ -2261,10 +2296,13 @@ } }, "node_modules/ci-info": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.4.0.tgz", - "integrity": "sha512-t5QdPT5jq3o262DOQ8zA6E1tlH2upmUc4Hlvrbx1pGYJuiiHl7O7rvVNI+l8HTVhd/q3Qc9vqimkNk5yiXsAug==", - "dev": true + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.0.tgz", + "integrity": "sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==", + "dev": true, + "engines": { + "node": ">=8" + } }, "node_modules/cjs-module-lexer": { "version": "1.2.2", @@ -2282,24 +2320,18 @@ "node": ">=0.3.6" } }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "dependencies": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" } }, "node_modules/clone-response": { @@ -2364,7 +2396,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "dependencies": { "delayed-stream": "~1.0.0" }, @@ -2381,52 +2412,21 @@ "node": ">= 12.0.0" } }, - "node_modules/commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, - "node_modules/concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "engines": [ - "node >= 0.8" - ], - "optional": true, - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "optional": true, - "dependencies": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, "node_modules/console-stamp": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/console-stamp/-/console-stamp-3.0.6.tgz", - "integrity": "sha512-j4tP+1shVIUjSnvrtv5nJ5uVzLeNOTweVHkcEXB2ej4NJdlRp14w0hOzQiF+iQvOTjz4jafmdhd1CdYSwNzM8Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/console-stamp/-/console-stamp-3.1.0.tgz", + "integrity": "sha512-Vt22288o0Hrxb9uYwXMWYuw/Mu8iPSrFPtIiveq9uE0zWXPDDCAIvKZojqnwcyINnJY9tnTeG0neV/MD+2G5+g==", "dependencies": { "chalk": "^4.1.2", "dateformat": "^4.6.3" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/content-disposition": { @@ -2449,18 +2449,9 @@ } }, "node_modules/convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.1" - } - }, - "node_modules/convert-source-map/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", "dev": true }, "node_modules/cookie": { @@ -2476,12 +2467,6 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, - "node_modules/core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "optional": true - }, "node_modules/cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", @@ -2495,9 +2480,9 @@ } }, "node_modules/cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dev": true, "dependencies": { "@types/parse-json": "^4.0.0", @@ -2624,9 +2609,9 @@ } }, "node_modules/decamelize-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", - "integrity": "sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", "dev": true, "dependencies": { "decamelize": "^1.1.0", @@ -2634,6 +2619,9 @@ }, "engines": { "node": ">=0.10.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/decamelize-keys/node_modules/map-obj": { @@ -2646,21 +2634,36 @@ } }, "node_modules/decimal.js": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.1.tgz", - "integrity": "sha512-F29o+vci4DodHYT9UrR5IEbfBw9pE5eSapIJdTqXK5+6hq+t8VRxwQyKlW2i+KDKFkkJQRvFyI/QXD83h8LyQw==", + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", "dev": true }, "node_modules/decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "optional": true, "dependencies": { - "mimic-response": "^1.0.0" + "mimic-response": "^3.1.0" }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/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==", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/dedent": { @@ -2683,24 +2686,15 @@ "node": ">=0.10.0" } }, - "node_modules/default-require-extensions": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", - "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", - "dev": true, - "dependencies": { - "strip-bom": "^4.0.0" - }, + "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==", + "optional": true, "engines": { - "node": ">=8" + "node": ">=10" } }, - "node_modules/defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", - "optional": true - }, "node_modules/define-properties": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", @@ -2721,7 +2715,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true, "engines": { "node": ">=0.4.0" } @@ -2768,20 +2761,22 @@ } }, "node_modules/diff-sequences": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.0.0.tgz", - "integrity": "sha512-7Qe/zd1wxSDL4D/X/FPjOMB+ZMDt71W94KYaq05I2l0oQqgXgs7s4ftYYmV38gBSrPz2vcygxfs1xn0FT+rKNA==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz", + "integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/digest-fetch": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.3.0.tgz", - "integrity": "sha512-CGJuv6iKNM7QyZlM2T3sPAdZWd/p9zQiRNS9G+9COUCwzWFTs0Xp8NF5iePx7wtvhDykReiRRrSeNb4oMmB8lA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-2.0.1.tgz", + "integrity": "sha512-OgzIWveqj8BlQ8hfJv97a9iOzWOgvI5Z3rGAnjkeNpHepHZpD/DHBDJ9mtfDclH5vkbUSGRqNEosYCH1FSO6Pg==", "dependencies": { "base-64": "^0.1.0", + "js-sha256": "^0.9.0", + "js-sha512": "^0.8.0", "md5": "^2.3.0" } }, @@ -2789,6 +2784,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, "dependencies": { "path-type": "^4.0.0" }, @@ -2819,45 +2815,39 @@ "node": ">=12" } }, - "node_modules/duplexer3": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", - "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", - "optional": true - }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "node_modules/electron": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-19.1.0.tgz", - "integrity": "sha512-5o9EEYx0bI0p+L0eSoS8n3gLrEvkdnzwSZ/hnkPoUfuAs/CONCI/TEqswSppeeJ/pi5gXf3/B7hVTNaZZbIdnw==", + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/electron/-/electron-22.0.0.tgz", + "integrity": "sha512-cgRc4wjyM+81A0E8UGv1HNJjL1HBI5cWNh/DUIjzYvoUuiEM0SS0hAH/zaFQ18xOz2ced6Yih8SybpOiOYJhdg==", "hasInstallScript": true, "optional": true, "dependencies": { - "@electron/get": "^1.14.1", + "@electron/get": "^2.0.0", "@types/node": "^16.11.26", - "extract-zip": "^1.0.3" + "extract-zip": "^2.0.1" }, "bin": { "electron": "cli.js" }, "engines": { - "node": ">= 8.6" + "node": ">= 12.20.55" } }, "node_modules/electron-to-chromium": { - "version": "1.4.264", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.264.tgz", - "integrity": "sha512-AZ6ZRkucHOQT8wke50MktxtmcWZr67kE17X/nAXFf62NIdMdgY6xfsaJD5Szoy84lnkuPWH+4tTNE3s2+bPCiw==", + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", "dev": true }, "node_modules/emittery": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", - "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true, "engines": { "node": ">=12" @@ -2890,9 +2880,9 @@ } }, "node_modules/engine.io": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.0.tgz", - "integrity": "sha512-4KzwW3F3bk+KlzSOY57fj/Jx6LyRQ1nbcyIadehl+AnXjKT7gDO0ORdRi/84ixvMKTym6ZKuxvbzN62HDDU1Lg==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.1.tgz", + "integrity": "sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA==", "dependencies": { "@types/cookie": "^0.4.1", "@types/cors": "^2.8.12", @@ -2979,7 +2969,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "devOptional": true + "optional": true }, "node_modules/escalade": { "version": "3.1.1", @@ -3080,14 +3070,14 @@ } }, "node_modules/eslint": { - "version": "8.24.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.24.0.tgz", - "integrity": "sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==", + "version": "8.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.30.0.tgz", + "integrity": "sha512-MGADB39QqYuzEGov+F/qb18r4i7DohCDOfatHaxI2iGlPuC65bwG2gxgO+7DkyL38dRFaRH7RaRAgU6JKL9rMQ==", "dependencies": { - "@eslint/eslintrc": "^1.3.2", - "@humanwhocodes/config-array": "^0.10.5", - "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@eslint/eslintrc": "^1.4.0", + "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -3103,14 +3093,14 @@ "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", - "globby": "^11.1.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", @@ -3147,9 +3137,9 @@ } }, "node_modules/eslint-plugin-jest": { - "version": "27.0.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.0.4.tgz", - "integrity": "sha512-BuvY78pHMpMJ6Cio7sKg6jrqEcnRYPUc4Nlihku4vKx3FjlmMINSX4vcYokZIe+8TKcyr1aI5Kq7vYwgJNdQSA==", + "version": "27.1.7", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.1.7.tgz", + "integrity": "sha512-0QVzf+og4YI1Qr3UoprkqqhezAZjFffdi62b0IurkCXMqPtRW84/UT4CKsYT80h/D82LA9avjO/80Ou1LdgbaQ==", "dev": true, "dependencies": { "@typescript-eslint/utils": "^5.10.0" @@ -3171,30 +3161,42 @@ } }, "node_modules/eslint-plugin-jsdoc": { - "version": "39.3.6", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.3.6.tgz", - "integrity": "sha512-R6dZ4t83qPdMhIOGr7g2QII2pwCjYyKP+z0tPOfO1bbAbQyKC20Y2Rd6z1te86Lq3T7uM8bNo+VD9YFpE8HU/g==", + "version": "39.6.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.6.4.tgz", + "integrity": "sha512-fskvdLCfwmPjHb6e+xNGDtGgbF8X7cDwMtVLAP2WwSf9Htrx68OAx31BESBM1FAwsN2HTQyYQq7m4aW4Q4Nlag==", "dev": true, "dependencies": { - "@es-joy/jsdoccomment": "~0.31.0", + "@es-joy/jsdoccomment": "~0.36.1", "comment-parser": "1.3.1", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", "esquery": "^1.4.0", - "semver": "^7.3.7", + "semver": "^7.3.8", "spdx-expression-parse": "^3.0.1" }, "engines": { - "node": "^14 || ^16 || ^17 || ^18" + "node": "^14 || ^16 || ^17 || ^18 || ^19" }, "peerDependencies": { "eslint": "^7.0.0 || ^8.0.0" } }, + "node_modules/eslint-plugin-jsdoc/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/eslint-plugin-jsdoc/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -3206,6 +3208,12 @@ "node": ">=10" } }, + "node_modules/eslint-plugin-jsdoc/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/eslint-plugin-prettier": { "version": "4.2.1", "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", @@ -3273,9 +3281,9 @@ } }, "node_modules/espree": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", - "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", "dependencies": { "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", @@ -3392,29 +3400,29 @@ } }, "node_modules/expect": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.0.3.tgz", - "integrity": "sha512-t8l5DTws3212VbmPL+tBFXhjRHLmctHB0oQbL8eUc6S7NzZtYUhycrFO9mkxA0ZUC6FAWdNi7JchJSkODtcu1Q==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.3.1.tgz", + "integrity": "sha512-gGb1yTgU30Q0O/tQq+z30KBWv24ApkMgFUpvKBkyLUBL68Wv8dHdJxTBZFl/iT8K/bqDHvUYRH6IIN3rToopPA==", "dev": true, "dependencies": { - "@jest/expect-utils": "^29.0.3", - "jest-get-type": "^29.0.0", - "jest-matcher-utils": "^29.0.3", - "jest-message-util": "^29.0.3", - "jest-util": "^29.0.3" + "@jest/expect-utils": "^29.3.1", + "jest-get-type": "^29.2.0", + "jest-matcher-utils": "^29.3.1", + "jest-message-util": "^29.3.1", + "jest-util": "^29.3.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/express": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", - "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.0", + "body-parser": "1.20.1", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.5.0", @@ -3433,7 +3441,7 @@ "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.10.3", + "qs": "6.11.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "0.18.0", @@ -3485,35 +3493,25 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, "node_modules/extract-zip": { - "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==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "optional": true, "dependencies": { - "concat-stream": "^1.6.2", - "debug": "^2.6.9", - "mkdirp": "^0.5.4", + "debug": "^4.1.1", + "get-stream": "^5.1.0", "yauzl": "^2.10.0" }, "bin": { "extract-zip": "cli.js" + }, + "engines": { + "node": ">= 10.17.0" + }, + "optionalDependencies": { + "@types/yauzl": "^2.9.1" } }, - "node_modules/extract-zip/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "optional": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/extract-zip/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "optional": true - }, "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", @@ -3529,6 +3527,7 @@ "version": "3.2.12", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -3544,6 +3543,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "dependencies": { "is-glob": "^4.0.1" }, @@ -3571,9 +3571,9 @@ } }, "node_modules/fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.14.0.tgz", + "integrity": "sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==", "dependencies": { "reusify": "^1.0.4" } @@ -3623,6 +3623,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, "dependencies": { "to-regex-range": "^5.0.1" }, @@ -3660,23 +3661,6 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, - "node_modules/find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dev": true, - "dependencies": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/avajs/find-cache-dir?sponsor=1" - } - }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -3728,24 +3712,10 @@ } } }, - "node_modules/foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, "node_modules/form-data": { "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", "combined-stream": "^1.0.8", @@ -3771,26 +3741,6 @@ "node": ">= 0.6" } }, - "node_modules/fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, "node_modules/fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -3870,15 +3820,18 @@ } }, "node_modules/get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "optional": true, + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "devOptional": true, "dependencies": { "pump": "^3.0.0" }, "engines": { - "node": ">=6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/glob": { @@ -3928,10 +3881,22 @@ "node": ">=10.0" } }, + "node_modules/global-agent/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "optional": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/global-agent/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "optional": true, "dependencies": { "lru-cache": "^6.0.0" @@ -3943,6 +3908,12 @@ "node": ">=10" } }, + "node_modules/global-agent/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true + }, "node_modules/global-modules": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", @@ -3981,25 +3952,10 @@ "which": "bin/which" } }, - "node_modules/global-tunnel-ng": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz", - "integrity": "sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==", - "optional": true, - "dependencies": { - "encodeurl": "^1.0.2", - "lodash": "^4.17.10", - "npm-conf": "^1.1.3", - "tunnel": "^0.0.6" - }, - "engines": { - "node": ">=0.10" - } - }, "node_modules/globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "dependencies": { "type-fest": "^0.20.2" }, @@ -4029,6 +3985,7 @@ "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -4051,25 +4008,28 @@ "dev": true }, "node_modules/got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", "optional": true, "dependencies": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" + "@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.2", + "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": ">=8.6" + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" } }, "node_modules/graceful-fs": { @@ -4134,35 +4094,10 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "dev": true, - "dependencies": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/hasha/node_modules/type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/helmet": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/helmet/-/helmet-6.0.0.tgz", - "integrity": "sha512-FO9RpR1wNJepH/GbLPQVtkE2eESglXL641p7SdyoT4LngHFJcZheHMoyUcjCZF4qpuMMO1u5q6RK0l9Ux8JBcg==", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-6.0.1.tgz", + "integrity": "sha512-8wo+VdQhTMVBMCITYZaGTbE4lvlthelPYSvoyNvk4RECTmrVjMerp9RfUOQXZWLvCcAn1pKj7ZRxK4lI9Alrcw==", "engines": { "node": ">=14.0.0" } @@ -4179,6 +4114,24 @@ "node": ">=10" } }, + "node_modules/hosted-git-info/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/hosted-git-info/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/html-encoding-sniffer": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", @@ -4244,6 +4197,19 @@ "node": ">= 6" } }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "optional": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -4267,9 +4233,9 @@ } }, "node_modules/husky": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.1.tgz", - "integrity": "sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.2.tgz", + "integrity": "sha512-Tkv80jtvbnkK3mYWxPZePGFpQ/tT3HNSs/sasF9P2YfkMezDl3ON37YN6jUUI4eTg5LcyVynlb6r4eyvOmspvg==", "dev": true, "bin": { "husky": "lib/bin.js" @@ -4293,9 +4259,9 @@ } }, "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==", "engines": { "node": ">= 4" } @@ -4378,7 +4344,7 @@ "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "devOptional": true + "dev": true }, "node_modules/ip": { "version": "1.1.8", @@ -4413,9 +4379,9 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "node_modules/is-core-module": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", "dev": true, "dependencies": { "has": "^1.0.3" @@ -4465,10 +4431,19 @@ "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, "engines": { "node": ">=0.12.0" } }, + "node_modules/is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "engines": { + "node": ">=8" + } + }, "node_modules/is-plain-obj": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", @@ -4505,26 +4480,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "optional": true + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true }, "node_modules/isexe": { "version": "2.0.0", @@ -4540,22 +4500,10 @@ "node": ">=8" } }, - "node_modules/istanbul-lib-hook": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", - "dev": true, - "dependencies": { - "append-transform": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/istanbul-lib-instrument": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", - "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, "dependencies": { "@babel/core": "^7.12.3", @@ -4568,27 +4516,10 @@ "node": ">=8" } }, - "node_modules/istanbul-lib-processinfo": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", - "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", - "dev": true, - "dependencies": { - "archy": "^1.0.0", - "cross-spawn": "^7.0.3", - "istanbul-lib-coverage": "^3.2.0", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "uuid": "^8.3.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", "dev": true, "dependencies": { "istanbul-lib-coverage": "^3.0.0", @@ -4627,15 +4558,15 @@ } }, "node_modules/jest": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.0.3.tgz", - "integrity": "sha512-ElgUtJBLgXM1E8L6K1RW1T96R897YY/3lRYqq9uVcPWtP2AAl/nQ16IYDh/FzQOOQ12VEuLdcPU83mbhG2C3PQ==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.3.1.tgz", + "integrity": "sha512-6iWfL5DTT0Np6UYs/y5Niu7WIfNv/wRTtN5RSXt2DIEft3dx3zPuw/3WJQBCJfmEzvDiEKwoqMbGD9n49+qLSA==", "dev": true, "dependencies": { - "@jest/core": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/core": "^29.3.1", + "@jest/types": "^29.3.1", "import-local": "^3.0.2", - "jest-cli": "^29.0.3" + "jest-cli": "^29.3.1" }, "bin": { "jest": "bin/jest.js" @@ -4653,9 +4584,9 @@ } }, "node_modules/jest-changed-files": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.0.0.tgz", - "integrity": "sha512-28/iDMDrUpGoCitTURuDqUzWQoWmOmOKOFST1mi2lwh62X4BFf6khgH3uSuo1e49X/UDjuApAj3w0wLOex4VPQ==", + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.2.0.tgz", + "integrity": "sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA==", "dev": true, "dependencies": { "execa": "^5.0.0", @@ -4666,28 +4597,28 @@ } }, "node_modules/jest-circus": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.0.3.tgz", - "integrity": "sha512-QeGzagC6Hw5pP+df1+aoF8+FBSgkPmraC1UdkeunWh0jmrp7wC0Hr6umdUAOELBQmxtKAOMNC3KAdjmCds92Zg==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.3.1.tgz", + "integrity": "sha512-wpr26sEvwb3qQQbdlmei+gzp6yoSSoSL6GsLPxnuayZSMrSd5Ka7IjAvatpIernBvT2+Ic6RLTg+jSebScmasg==", "dev": true, "dependencies": { - "@jest/environment": "^29.0.3", - "@jest/expect": "^29.0.3", - "@jest/test-result": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/environment": "^29.3.1", + "@jest/expect": "^29.3.1", + "@jest/test-result": "^29.3.1", + "@jest/types": "^29.3.1", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", "is-generator-fn": "^2.0.0", - "jest-each": "^29.0.3", - "jest-matcher-utils": "^29.0.3", - "jest-message-util": "^29.0.3", - "jest-runtime": "^29.0.3", - "jest-snapshot": "^29.0.3", - "jest-util": "^29.0.3", + "jest-each": "^29.3.1", + "jest-matcher-utils": "^29.3.1", + "jest-message-util": "^29.3.1", + "jest-runtime": "^29.3.1", + "jest-snapshot": "^29.3.1", + "jest-util": "^29.3.1", "p-limit": "^3.1.0", - "pretty-format": "^29.0.3", + "pretty-format": "^29.3.1", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -4696,21 +4627,21 @@ } }, "node_modules/jest-cli": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.0.3.tgz", - "integrity": "sha512-aUy9Gd/Kut1z80eBzG10jAn6BgS3BoBbXyv+uXEqBJ8wnnuZ5RpNfARoskSrTIy1GY4a8f32YGuCMwibtkl9CQ==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.3.1.tgz", + "integrity": "sha512-TO/ewvwyvPOiBBuWZ0gm04z3WWP8TIK8acgPzE4IxgsLKQgb377NYGrQLc3Wl/7ndWzIH2CDNNsUjGxwLL43VQ==", "dev": true, "dependencies": { - "@jest/core": "^29.0.3", - "@jest/test-result": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/core": "^29.3.1", + "@jest/test-result": "^29.3.1", + "@jest/types": "^29.3.1", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^29.0.3", - "jest-util": "^29.0.3", - "jest-validate": "^29.0.3", + "jest-config": "^29.3.1", + "jest-util": "^29.3.1", + "jest-validate": "^29.3.1", "prompts": "^2.0.1", "yargs": "^17.3.1" }, @@ -4730,31 +4661,31 @@ } }, "node_modules/jest-config": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.0.3.tgz", - "integrity": "sha512-U5qkc82HHVYe3fNu2CRXLN4g761Na26rWKf7CjM8LlZB3In1jadEkZdMwsE37rd9RSPV0NfYaCjHdk/gu3v+Ew==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.3.1.tgz", + "integrity": "sha512-y0tFHdj2WnTEhxmGUK1T7fgLen7YK4RtfvpLFBXfQkh2eMJAQq24Vx9472lvn5wg0MAO6B+iPfJfzdR9hJYalg==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.0.3", - "@jest/types": "^29.0.3", - "babel-jest": "^29.0.3", + "@jest/test-sequencer": "^29.3.1", + "@jest/types": "^29.3.1", + "babel-jest": "^29.3.1", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-circus": "^29.0.3", - "jest-environment-node": "^29.0.3", - "jest-get-type": "^29.0.0", - "jest-regex-util": "^29.0.0", - "jest-resolve": "^29.0.3", - "jest-runner": "^29.0.3", - "jest-util": "^29.0.3", - "jest-validate": "^29.0.3", + "jest-circus": "^29.3.1", + "jest-environment-node": "^29.3.1", + "jest-get-type": "^29.2.0", + "jest-regex-util": "^29.2.0", + "jest-resolve": "^29.3.1", + "jest-runner": "^29.3.1", + "jest-util": "^29.3.1", + "jest-validate": "^29.3.1", "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "^29.0.3", + "pretty-format": "^29.3.1", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, @@ -4775,24 +4706,24 @@ } }, "node_modules/jest-diff": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.0.3.tgz", - "integrity": "sha512-+X/AIF5G/vX9fWK+Db9bi9BQas7M9oBME7egU7psbn4jlszLFCu0dW63UgeE6cs/GANq4fLaT+8sGHQQ0eCUfg==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.3.1.tgz", + "integrity": "sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^29.0.0", - "jest-get-type": "^29.0.0", - "pretty-format": "^29.0.3" + "diff-sequences": "^29.3.1", + "jest-get-type": "^29.2.0", + "pretty-format": "^29.3.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-docblock": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.0.0.tgz", - "integrity": "sha512-s5Kpra/kLzbqu9dEjov30kj1n4tfu3e7Pl8v+f8jOkeWNqM6Ds8jRaJfZow3ducoQUrf2Z4rs2N5S3zXnb83gw==", + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.2.0.tgz", + "integrity": "sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A==", "dev": true, "dependencies": { "detect-newline": "^3.0.0" @@ -4802,62 +4733,62 @@ } }, "node_modules/jest-each": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.0.3.tgz", - "integrity": "sha512-wILhZfESURHHBNvPMJ0lZlYZrvOQJxAo3wNHi+ycr90V7M+uGR9Gh4+4a/BmaZF0XTyZsk4OiYEf3GJN7Ltqzg==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.3.1.tgz", + "integrity": "sha512-qrZH7PmFB9rEzCSl00BWjZYuS1BSOH8lLuC0azQE9lQrAx3PWGKHTDudQiOSwIy5dGAJh7KA0ScYlCP7JxvFYA==", "dev": true, "dependencies": { - "@jest/types": "^29.0.3", + "@jest/types": "^29.3.1", "chalk": "^4.0.0", - "jest-get-type": "^29.0.0", - "jest-util": "^29.0.3", - "pretty-format": "^29.0.3" + "jest-get-type": "^29.2.0", + "jest-util": "^29.3.1", + "pretty-format": "^29.3.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-environment-node": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.0.3.tgz", - "integrity": "sha512-cdZqRCnmIlTXC+9vtvmfiY/40Cj6s2T0czXuq1whvQdmpzAnj4sbqVYuZ4zFHk766xTTJ+Ij3uUqkk8KCfXoyg==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.3.1.tgz", + "integrity": "sha512-xm2THL18Xf5sIHoU7OThBPtuH6Lerd+Y1NLYiZJlkE3hbE+7N7r8uvHIl/FkZ5ymKXJe/11SQuf3fv4v6rUMag==", "dev": true, "dependencies": { - "@jest/environment": "^29.0.3", - "@jest/fake-timers": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/environment": "^29.3.1", + "@jest/fake-timers": "^29.3.1", + "@jest/types": "^29.3.1", "@types/node": "*", - "jest-mock": "^29.0.3", - "jest-util": "^29.0.3" + "jest-mock": "^29.3.1", + "jest-util": "^29.3.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-get-type": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.0.0.tgz", - "integrity": "sha512-83X19z/HuLKYXYHskZlBAShO7UfLFXu/vWajw9ZNJASN32li8yHMaVGAQqxFW1RCFOkB7cubaL6FaJVQqqJLSw==", + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz", + "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-haste-map": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.0.3.tgz", - "integrity": "sha512-uMqR99+GuBHo0RjRhOE4iA6LmsxEwRdgiIAQgMU/wdT2XebsLDz5obIwLZm/Psj+GwSEQhw9AfAVKGYbh2G55A==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.3.1.tgz", + "integrity": "sha512-/FFtvoG1xjbbPXQLFef+WSU4yrc0fc0Dds6aRPBojUid7qlPqZvxdUBA03HW0fnVHXVCnCdkuoghYItKNzc/0A==", "dev": true, "dependencies": { - "@jest/types": "^29.0.3", + "@jest/types": "^29.3.1", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.0.0", - "jest-util": "^29.0.3", - "jest-worker": "^29.0.3", + "jest-regex-util": "^29.2.0", + "jest-util": "^29.3.1", + "jest-worker": "^29.3.1", "micromatch": "^4.0.4", "walker": "^1.0.8" }, @@ -4869,46 +4800,46 @@ } }, "node_modules/jest-leak-detector": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.0.3.tgz", - "integrity": "sha512-YfW/G63dAuiuQ3QmQlh8hnqLDe25WFY3eQhuc/Ev1AGmkw5zREblTh7TCSKLoheyggu6G9gxO2hY8p9o6xbaRQ==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.3.1.tgz", + "integrity": "sha512-3DA/VVXj4zFOPagGkuqHnSQf1GZBmmlagpguxEERO6Pla2g84Q1MaVIB3YMxgUaFIaYag8ZnTyQgiZ35YEqAQA==", "dev": true, "dependencies": { - "jest-get-type": "^29.0.0", - "pretty-format": "^29.0.3" + "jest-get-type": "^29.2.0", + "pretty-format": "^29.3.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.0.3.tgz", - "integrity": "sha512-RsR1+cZ6p1hDV4GSCQTg+9qjeotQCgkaleIKLK7dm+U4V/H2bWedU3RAtLm8+mANzZ7eDV33dMar4pejd7047w==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.3.1.tgz", + "integrity": "sha512-fkRMZUAScup3txIKfMe3AIZZmPEjWEdsPJFK3AIy5qRohWqQFg1qrmKfYXR9qEkNc7OdAu2N4KPHibEmy4HPeQ==", "dev": true, "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^29.0.3", - "jest-get-type": "^29.0.0", - "pretty-format": "^29.0.3" + "jest-diff": "^29.3.1", + "jest-get-type": "^29.2.0", + "pretty-format": "^29.3.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-message-util": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.0.3.tgz", - "integrity": "sha512-7T8JiUTtDfppojosORAflABfLsLKMLkBHSWkjNQrjIltGoDzNGn7wEPOSfjqYAGTYME65esQzMJxGDjuLBKdOg==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.3.1.tgz", + "integrity": "sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==", "dev": true, "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.0.3", + "@jest/types": "^29.3.1", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.0.3", + "pretty-format": "^29.3.1", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -4917,22 +4848,23 @@ } }, "node_modules/jest-mock": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.0.3.tgz", - "integrity": "sha512-ort9pYowltbcrCVR43wdlqfAiFJXBx8l4uJDsD8U72LgBcetvEp+Qxj1W9ZYgMRoeAo+ov5cnAGF2B6+Oth+ww==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.3.1.tgz", + "integrity": "sha512-H8/qFDtDVMFvFP4X8NuOT3XRDzOUTz+FeACjufHzsOIBAxivLqkB1PoLCaJx9iPPQ8dZThHPp/G3WRWyMgA3JA==", "dev": true, "dependencies": { - "@jest/types": "^29.0.3", - "@types/node": "*" + "@jest/types": "^29.3.1", + "@types/node": "*", + "jest-util": "^29.3.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.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==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, "engines": { "node": ">=6" @@ -4947,26 +4879,26 @@ } }, "node_modules/jest-regex-util": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.0.0.tgz", - "integrity": "sha512-BV7VW7Sy0fInHWN93MMPtlClweYv2qrSCwfeFWmpribGZtQPWNvRSq9XOVgOEjU1iBGRKXUZil0o2AH7Iy9Lug==", + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.2.0.tgz", + "integrity": "sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA==", "dev": true, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-resolve": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.0.3.tgz", - "integrity": "sha512-toVkia85Y/BPAjJasTC9zIPY6MmVXQPtrCk8SmiheC4MwVFE/CMFlOtMN6jrwPMC6TtNh8+sTMllasFeu1wMPg==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.3.1.tgz", + "integrity": "sha512-amXJgH/Ng712w3Uz5gqzFBBjxV8WFLSmNjoreBGMqxgCz5cH7swmBZzgBaCIOsvb0NbpJ0vgaSFdJqMdT+rADw==", "dev": true, "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.3", + "jest-haste-map": "^29.3.1", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.0.3", - "jest-validate": "^29.0.3", + "jest-util": "^29.3.1", + "jest-validate": "^29.3.1", "resolve": "^1.20.0", "resolve.exports": "^1.1.0", "slash": "^3.0.0" @@ -4976,43 +4908,43 @@ } }, "node_modules/jest-resolve-dependencies": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.0.3.tgz", - "integrity": "sha512-KzuBnXqNvbuCdoJpv8EanbIGObk7vUBNt/PwQPPx2aMhlv/jaXpUJsqWYRpP/0a50faMBY7WFFP8S3/CCzwfDw==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.3.1.tgz", + "integrity": "sha512-Vk0cYq0byRw2WluNmNWGqPeRnZ3p3hHmjJMp2dyyZeYIfiBskwq4rpiuGFR6QGAdbj58WC7HN4hQHjf2mpvrLA==", "dev": true, "dependencies": { - "jest-regex-util": "^29.0.0", - "jest-snapshot": "^29.0.3" + "jest-regex-util": "^29.2.0", + "jest-snapshot": "^29.3.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-runner": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.0.3.tgz", - "integrity": "sha512-Usu6VlTOZlCZoNuh3b2Tv/yzDpKqtiNAetG9t3kJuHfUyVMNW7ipCCJOUojzKkjPoaN7Bl1f7Buu6PE0sGpQxw==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.3.1.tgz", + "integrity": "sha512-oFvcwRNrKMtE6u9+AQPMATxFcTySyKfLhvso7Sdk/rNpbhg4g2GAGCopiInk1OP4q6gz3n6MajW4+fnHWlU3bA==", "dev": true, "dependencies": { - "@jest/console": "^29.0.3", - "@jest/environment": "^29.0.3", - "@jest/test-result": "^29.0.3", - "@jest/transform": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/console": "^29.3.1", + "@jest/environment": "^29.3.1", + "@jest/test-result": "^29.3.1", + "@jest/transform": "^29.3.1", + "@jest/types": "^29.3.1", "@types/node": "*", "chalk": "^4.0.0", - "emittery": "^0.10.2", + "emittery": "^0.13.1", "graceful-fs": "^4.2.9", - "jest-docblock": "^29.0.0", - "jest-environment-node": "^29.0.3", - "jest-haste-map": "^29.0.3", - "jest-leak-detector": "^29.0.3", - "jest-message-util": "^29.0.3", - "jest-resolve": "^29.0.3", - "jest-runtime": "^29.0.3", - "jest-util": "^29.0.3", - "jest-watcher": "^29.0.3", - "jest-worker": "^29.0.3", + "jest-docblock": "^29.2.0", + "jest-environment-node": "^29.3.1", + "jest-haste-map": "^29.3.1", + "jest-leak-detector": "^29.3.1", + "jest-message-util": "^29.3.1", + "jest-resolve": "^29.3.1", + "jest-runtime": "^29.3.1", + "jest-util": "^29.3.1", + "jest-watcher": "^29.3.1", + "jest-worker": "^29.3.1", "p-limit": "^3.1.0", "source-map-support": "0.5.13" }, @@ -5021,31 +4953,31 @@ } }, "node_modules/jest-runtime": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.0.3.tgz", - "integrity": "sha512-12gZXRQ7ozEeEHKTY45a+YLqzNDR/x4c//X6AqwKwKJPpWM8FY4vwn4VQJOcLRS3Nd1fWwgP7LU4SoynhuUMHQ==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.0.3", - "@jest/fake-timers": "^29.0.3", - "@jest/globals": "^29.0.3", - "@jest/source-map": "^29.0.0", - "@jest/test-result": "^29.0.3", - "@jest/transform": "^29.0.3", - "@jest/types": "^29.0.3", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.3.1.tgz", + "integrity": "sha512-jLzkIxIqXwBEOZx7wx9OO9sxoZmgT2NhmQKzHQm1xwR1kNW/dn0OjxR424VwHHf1SPN6Qwlb5pp1oGCeFTQ62A==", + "dev": true, + "dependencies": { + "@jest/environment": "^29.3.1", + "@jest/fake-timers": "^29.3.1", + "@jest/globals": "^29.3.1", + "@jest/source-map": "^29.2.0", + "@jest/test-result": "^29.3.1", + "@jest/transform": "^29.3.1", + "@jest/types": "^29.3.1", "@types/node": "*", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.3", - "jest-message-util": "^29.0.3", - "jest-mock": "^29.0.3", - "jest-regex-util": "^29.0.0", - "jest-resolve": "^29.0.3", - "jest-snapshot": "^29.0.3", - "jest-util": "^29.0.3", + "jest-haste-map": "^29.3.1", + "jest-message-util": "^29.3.1", + "jest-mock": "^29.3.1", + "jest-regex-util": "^29.2.0", + "jest-resolve": "^29.3.1", + "jest-snapshot": "^29.3.1", + "jest-util": "^29.3.1", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, @@ -5054,9 +4986,9 @@ } }, "node_modules/jest-snapshot": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.0.3.tgz", - "integrity": "sha512-52q6JChm04U3deq+mkQ7R/7uy7YyfVIrebMi6ZkBoDJ85yEjm/sJwdr1P0LOIEHmpyLlXrxy3QP0Zf5J2kj0ew==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.3.1.tgz", + "integrity": "sha512-+3JOc+s28upYLI2OJM4PWRGK9AgpsMs/ekNryUV0yMBClT9B1DF2u2qay8YxcQd338PPYSFNb0lsar1B49sLDA==", "dev": true, "dependencies": { "@babel/core": "^7.11.6", @@ -5065,33 +4997,45 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.0.3", - "@jest/transform": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/expect-utils": "^29.3.1", + "@jest/transform": "^29.3.1", + "@jest/types": "^29.3.1", "@types/babel__traverse": "^7.0.6", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.0.3", + "expect": "^29.3.1", "graceful-fs": "^4.2.9", - "jest-diff": "^29.0.3", - "jest-get-type": "^29.0.0", - "jest-haste-map": "^29.0.3", - "jest-matcher-utils": "^29.0.3", - "jest-message-util": "^29.0.3", - "jest-util": "^29.0.3", + "jest-diff": "^29.3.1", + "jest-get-type": "^29.2.0", + "jest-haste-map": "^29.3.1", + "jest-matcher-utils": "^29.3.1", + "jest-message-util": "^29.3.1", + "jest-util": "^29.3.1", "natural-compare": "^1.4.0", - "pretty-format": "^29.0.3", + "pretty-format": "^29.3.1", "semver": "^7.3.5" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-snapshot/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/jest-snapshot/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -5103,13 +5047,19 @@ "node": ">=10" } }, + "node_modules/jest-snapshot/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/jest-util": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.3.tgz", - "integrity": "sha512-Q0xaG3YRG8QiTC4R6fHjHQPaPpz9pJBEi0AeOE4mQh/FuWOijFjGXMMOfQEaU9i3z76cNR7FobZZUQnL6IyfdQ==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.3.1.tgz", + "integrity": "sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==", "dev": true, "dependencies": { - "@jest/types": "^29.0.3", + "@jest/types": "^29.3.1", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -5121,17 +5071,17 @@ } }, "node_modules/jest-validate": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.0.3.tgz", - "integrity": "sha512-OebiqqT6lK8cbMPtrSoS3aZP4juID762lZvpf1u+smZnwTEBCBInan0GAIIhv36MxGaJvmq5uJm7dl5gVt+Zrw==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.3.1.tgz", + "integrity": "sha512-N9Lr3oYR2Mpzuelp1F8negJR3YE+L1ebk1rYA5qYo9TTY3f9OWdptLoNSPP9itOCBIRBqjt/S5XHlzYglLN67g==", "dev": true, "dependencies": { - "@jest/types": "^29.0.3", + "@jest/types": "^29.3.1", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^29.0.0", + "jest-get-type": "^29.2.0", "leven": "^3.1.0", - "pretty-format": "^29.0.3" + "pretty-format": "^29.3.1" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" @@ -5150,18 +5100,18 @@ } }, "node_modules/jest-watcher": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.0.3.tgz", - "integrity": "sha512-tQX9lU91A+9tyUQKUMp0Ns8xAcdhC9fo73eqA3LFxP2bSgiF49TNcc+vf3qgGYYK9qRjFpXW9+4RgF/mbxyOOw==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.3.1.tgz", + "integrity": "sha512-RspXG2BQFDsZSRKGCT/NiNa8RkQ1iKAjrO0//soTMWx/QUt+OcxMqMSBxz23PYGqUuWm2+m2mNNsmj0eIoOaFg==", "dev": true, "dependencies": { - "@jest/test-result": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/test-result": "^29.3.1", + "@jest/types": "^29.3.1", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "emittery": "^0.10.2", - "jest-util": "^29.0.3", + "emittery": "^0.13.1", + "jest-util": "^29.3.1", "string-length": "^4.0.1" }, "engines": { @@ -5169,12 +5119,13 @@ } }, "node_modules/jest-worker": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.0.3.tgz", - "integrity": "sha512-Tl/YWUugQOjoTYwjKdfJWkSOfhufJHO5LhXTSZC3TRoQKO+fuXnZAdoXXBlpLXKGODBL3OvdUasfDD4PcMe6ng==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.3.1.tgz", + "integrity": "sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw==", "dev": true, "dependencies": { "@types/node": "*", + "jest-util": "^29.3.1", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, @@ -5198,9 +5149,23 @@ } }, "node_modules/js-sdsl": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", - "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", + "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/js-sha256": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", + "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" + }, + "node_modules/js-sha512": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.8.0.tgz", + "integrity": "sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==" }, "node_modules/js-tokens": { "version": "4.0.0", @@ -5229,18 +5194,18 @@ } }, "node_modules/jsdom": { - "version": "20.0.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.0.tgz", - "integrity": "sha512-x4a6CKCgx00uCmP+QakBDFXwjAJ69IkkIWHmtmjd3wvXPcdOS44hfX2vqkOQrVrq8l9DhNNADZRXaCEWvgXtVA==", + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", + "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", "dev": true, "dependencies": { "abab": "^2.0.6", - "acorn": "^8.7.1", - "acorn-globals": "^6.0.0", + "acorn": "^8.8.1", + "acorn-globals": "^7.0.0", "cssom": "^0.5.0", "cssstyle": "^2.3.0", "data-urls": "^3.0.2", - "decimal.js": "^10.3.1", + "decimal.js": "^10.4.2", "domexception": "^4.0.0", "escodegen": "^2.0.0", "form-data": "^4.0.0", @@ -5248,18 +5213,17 @@ "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.1", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "^7.0.0", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^3.0.0", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^2.0.0", "whatwg-mimetype": "^3.0.0", "whatwg-url": "^11.0.0", - "ws": "^8.8.0", + "ws": "^8.11.0", "xml-name-validator": "^4.0.0" }, "engines": { @@ -5287,9 +5251,9 @@ } }, "node_modules/json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "optional": true }, "node_modules/json-parse-even-better-errors": { @@ -5315,9 +5279,9 @@ "optional": true }, "node_modules/json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", + "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==", "dev": true, "bin": { "json5": "lib/cli.js" @@ -5342,12 +5306,12 @@ "dev": true }, "node_modules/keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", + "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", "optional": true, "dependencies": { - "json-buffer": "3.0.0" + "json-buffer": "3.0.1" } }, "node_modules/kind-of": { @@ -5369,9 +5333,9 @@ } }, "node_modules/known-css-properties": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.25.0.tgz", - "integrity": "sha512-b0/9J1O9Jcyik1GC6KC42hJ41jKwdO/Mq8Mdo5sYN+IuRTXs2YFHZC3kZSx6ueusqa95x3wLYe/ytKjbAfGixA==", + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.26.0.tgz", + "integrity": "sha512-5FZRzrZzNTBruuurWpvZnvP9pum+fe0HcK8z/ooo+U+Hmp4vtbyp1/QDsqmufirXy4egGzbaH/y2uCZf+6W5Kg==", "dev": true }, "node_modules/leven": { @@ -5420,12 +5384,6 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, - "node_modules/lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", - "dev": true - }, "node_modules/lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", @@ -5444,24 +5402,21 @@ "dev": true }, "node_modules/lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", "optional": true, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "devOptional": true, + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" + "yallist": "^3.0.2" } }, "node_modules/luxon": { @@ -5601,6 +5556,7 @@ "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, "engines": { "node": ">= 8" } @@ -5617,6 +5573,7 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, "dependencies": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -5693,12 +5650,6 @@ "node": "*" } }, - "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "optional": true - }, "node_modules/minimist-options": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", @@ -5722,18 +5673,6 @@ "node": ">=0.10.0" } }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "optional": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, "node_modules/module-alias": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz", @@ -5748,9 +5687,9 @@ } }, "node_modules/moment-timezone": { - "version": "0.5.37", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.37.tgz", - "integrity": "sha512-uEDzDNFhfaywRl+vwXxffjjq1q0Vzr+fcQpQ1bU0kbzorfS7zVtZnCnGc8mhWmF39d4g4YriF6kwA75mJKE/Zg==", + "version": "0.5.40", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.40.tgz", + "integrity": "sha512-tWfmNkRYmBkPJz5mr9GVDn9vRlVZOTe6yqY92rFxiOdWXbjaR0+9LwQnZGGuNR63X456NqmEkbskte8tWL5ePg==", "dependencies": { "moment": ">= 2.9.0" }, @@ -5814,23 +5753,35 @@ } }, "node_modules/nise": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.1.tgz", - "integrity": "sha512-yr5kW2THW1AkxVmCnKEh4nbYkJdB3I7LUkiUgOvEkOp414mc2UMaHMA7pjq1nYowhdoJZGwEKGaQVbxfpWj10A==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", + "integrity": "sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==", "dev": true, "dependencies": { - "@sinonjs/commons": "^1.8.3", - "@sinonjs/fake-timers": ">=5", + "@sinonjs/commons": "^2.0.0", + "@sinonjs/fake-timers": "^10.0.2", "@sinonjs/text-encoding": "^0.7.1", "just-extend": "^4.0.2", "path-to-regexp": "^1.7.0" } }, - "node_modules/nise/node_modules/isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true + "node_modules/nise/node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/nise/node_modules/@sinonjs/fake-timers": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", + "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^2.0.0" + } }, "node_modules/nise/node_modules/path-to-regexp": { "version": "1.8.0", @@ -5880,14 +5831,14 @@ } }, "node_modules/node-ical": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/node-ical/-/node-ical-0.15.1.tgz", - "integrity": "sha512-+MWL5mdYINFc5+Z5HDGJbQAK3QcpqEV8wok61Kb1VzIV16iTA/9vhIRrLcW+Iht5bm9wI7XalEssMohLeTwPgA==", + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/node-ical/-/node-ical-0.15.3.tgz", + "integrity": "sha512-OQ3xipexD/nI0jpoz+ELhMwV8liMMqM+rlxB5xHbPiJRYvueIT+4cipjdt4L64teXXHVmg+xf8OfwJE2LueVlw==", "dependencies": { - "axios": "^0.26.1", + "axios": "1.1.3", "moment-timezone": "^0.5.31", "rrule": "2.6.4", - "uuid": "^8.3.1" + "uuid": "^9.0.0" } }, "node_modules/node-int64": { @@ -5896,22 +5847,10 @@ "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true }, - "node_modules/node-preload": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", - "dev": true, - "dependencies": { - "process-on-spawn": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", + "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==", "dev": true }, "node_modules/normalize-package-data": { @@ -5929,10 +5868,22 @@ "node": ">=10" } }, + "node_modules/normalize-package-data/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/normalize-package-data/node_modules/semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -5944,6 +5895,12 @@ "node": ">=10" } }, + "node_modules/normalize-package-data/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -5954,25 +5911,15 @@ } }, "node_modules/normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", "optional": true, "engines": { - "node": ">=8" - } - }, - "node_modules/npm-conf": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz", - "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==", - "optional": true, - "dependencies": { - "config-chain": "^1.1.11", - "pify": "^3.0.0" + "node": ">=10" }, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/npm-run-path": { @@ -5993,189 +5940,6 @@ "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==", "dev": true }, - "node_modules/nyc": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", - "dev": true, - "dependencies": { - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "caching-transform": "^4.0.0", - "convert-source-map": "^1.7.0", - "decamelize": "^1.2.0", - "find-cache-dir": "^3.2.0", - "find-up": "^4.1.0", - "foreground-child": "^2.0.0", - "get-package-type": "^0.1.0", - "glob": "^7.1.6", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "make-dir": "^3.0.0", - "node-preload": "^0.2.1", - "p-map": "^3.0.0", - "process-on-spawn": "^1.0.0", - "resolve-from": "^5.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "spawn-wrap": "^2.0.0", - "test-exclude": "^6.0.0", - "yargs": "^15.0.2" - }, - "bin": { - "nyc": "bin/nyc.js" - }, - "engines": { - "node": ">=8.9" - } - }, - "node_modules/nyc/node_modules/cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "node_modules/nyc/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, - "dependencies": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/nyc/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "node_modules/nyc/node_modules/yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "dependencies": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/nyc/node_modules/yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "dependencies": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -6252,12 +6016,12 @@ } }, "node_modules/p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", "optional": true, "engines": { - "node": ">=6" + "node": ">=8" } }, "node_modules/p-limit": { @@ -6288,18 +6052,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -6309,21 +6061,6 @@ "node": ">=6" } }, - "node_modules/package-hash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.15", - "hasha": "^5.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -6354,9 +6091,9 @@ } }, "node_modules/parse5": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.1.tgz", - "integrity": "sha512-kwpuwzB+px5WUg9pyK0IcK/shltJN5/OVhQagxhCQNtT9Y9QRZqNY2e1cmbu/paRh5LMnz/oVTVLBpjFmMZhSg==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", "dev": true, "dependencies": { "entities": "^4.4.0" @@ -6412,6 +6149,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, "engines": { "node": ">=8" } @@ -6432,6 +6170,7 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, "engines": { "node": ">=8.6" }, @@ -6439,15 +6178,6 @@ "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "optional": true, - "engines": { - "node": ">=4" - } - }, "node_modules/pirates": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", @@ -6522,13 +6252,13 @@ } }, "node_modules/playwright": { - "version": "1.26.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.26.1.tgz", - "integrity": "sha512-WQmEdCgYYe8jOEkhkW9QLcK0PB+w1RZztBLYIT10MEEsENYg251cU0IzebDINreQsUt+HCwwRhtdz4weH9ICcQ==", + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.29.1.tgz", + "integrity": "sha512-lasC+pMqsQ2uWhNurt3YK3xo0gWlMjslYUylKbHcqF/NTjwp9KStRGO7S6wwz2f52GcSnop8XUK/GymJjdzrxw==", "dev": true, "hasInstallScript": true, "dependencies": { - "playwright-core": "1.26.1" + "playwright-core": "1.29.1" }, "bin": { "playwright": "cli.js" @@ -6538,9 +6268,9 @@ } }, "node_modules/playwright-core": { - "version": "1.26.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.26.1.tgz", - "integrity": "sha512-hzFchhhxnEiPc4qVPs9q2ZR+5eKNifY2hQDHtg1HnTTUuphYCBP8ZRb2si+B1TR7BHirgXaPi48LIye5SgrLAA==", + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.29.1.tgz", + "integrity": "sha512-20Ai3d+lMkWpI9YZYlxk8gxatfgax5STW8GaMozAHwigLiyiKQrdkt7gaoT9UQR8FIVDg6qVXs9IoZUQrDjIIg==", "dev": true, "bin": { "playwright": "cli.js" @@ -6550,9 +6280,9 @@ } }, "node_modules/postcss": { - "version": "8.4.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz", - "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==", + "version": "8.4.20", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz", + "integrity": "sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==", "dev": true, "funding": [ { @@ -6602,9 +6332,9 @@ } }, "node_modules/postcss-selector-parser": { - "version": "6.0.10", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", - "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", + "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", "dev": true, "dependencies": { "cssesc": "^3.0.0", @@ -6628,19 +6358,10 @@ "node": ">= 0.8.0" } }, - "node_modules/prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", - "optional": true, - "engines": { - "node": ">=4" - } - }, "node_modules/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz", + "integrity": "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==", "dev": true, "bin": { "prettier": "bin-prettier.js" @@ -6665,9 +6386,9 @@ } }, "node_modules/pretty-format": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.0.3.tgz", - "integrity": "sha512-cHudsvQr1K5vNVLbvYF/nv3Qy/F/BcEKxGuIeMiVMRHxPOO1RxXooP8g/ZrwAp7Dx+KdMZoOc7NxLHhMrP2f9Q==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz", + "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==", "dev": true, "dependencies": { "@jest/schemas": "^29.0.0", @@ -6762,21 +6483,6 @@ "node": ">=8" } }, - "node_modules/pretty-quick/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/pretty-quick/node_modules/human-signals": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", @@ -6825,24 +6531,6 @@ "node": ">=8" } }, - "node_modules/process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "optional": true - }, - "node_modules/process-on-spawn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", - "dev": true, - "dependencies": { - "fromentries": "^1.2.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -6865,12 +6553,6 @@ "node": ">= 6" } }, - "node_modules/proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", - "optional": true - }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -6883,6 +6565,11 @@ "node": ">= 0.10" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -6908,9 +6595,9 @@ } }, "node_modules/qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "dependencies": { "side-channel": "^1.0.4" }, @@ -6947,12 +6634,15 @@ ] }, "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, + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "optional": true, "engines": { - "node": ">=8" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/range_check": { @@ -7135,27 +6825,6 @@ "node": ">=8" } }, - "node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "optional": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/readable-stream/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "optional": true - }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -7180,18 +6849,6 @@ "url": "https://github.com/sponsors/mysticatea" } }, - "node_modules/release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", - "dev": true, - "dependencies": { - "es6-error": "^4.0.1" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -7210,12 +6867,6 @@ "node": ">=0.10.0" } }, - "node_modules/require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "node_modules/requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -7239,6 +6890,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "optional": true + }, "node_modules/resolve-cwd": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", @@ -7278,12 +6935,15 @@ } }, "node_modules/responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", "optional": true, "dependencies": { - "lowercase-keys": "^1.0.0" + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/reusify": { @@ -7497,12 +7157,6 @@ "node": ">= 0.8.0" } }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, "node_modules/setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -7547,16 +7201,16 @@ "dev": true }, "node_modules/sinon": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-14.0.0.tgz", - "integrity": "sha512-ugA6BFmE+WrJdh0owRZHToLd32Uw3Lxq6E6LtNRU+xTVBefx632h03Q7apXWRsRdZAJ41LB8aUfn2+O4jsDNMw==", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.0.1.tgz", + "integrity": "sha512-PZXKc08f/wcA/BMRGBze2Wmw50CWPiAH3E21EOi4B49vJ616vW4DQh4fQrqsYox2aNR/N3kCqLuB0PwwOucQrg==", "dev": true, "dependencies": { - "@sinonjs/commons": "^1.8.3", - "@sinonjs/fake-timers": "^9.1.2", - "@sinonjs/samsam": "^6.1.1", + "@sinonjs/commons": "^2.0.0", + "@sinonjs/fake-timers": "10.0.2", + "@sinonjs/samsam": "^7.0.1", "diff": "^5.0.0", - "nise": "^5.1.1", + "nise": "^5.1.2", "supports-color": "^7.2.0" }, "funding": { @@ -7564,6 +7218,24 @@ "url": "https://opencollective.com/sinon" } }, + "node_modules/sinon/node_modules/@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/sinon/node_modules/@sinonjs/fake-timers": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", + "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^2.0.0" + } + }, "node_modules/sisteransi": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", @@ -7574,6 +7246,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, "engines": { "node": ">=8" } @@ -7596,16 +7269,16 @@ } }, "node_modules/socket.io": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.2.tgz", - "integrity": "sha512-6fCnk4ARMPZN448+SQcnn1u8OHUC72puJcNtSgg2xS34Cu7br1gQ09YKkO1PFfDn/wyUE9ZgMAwosJed003+NQ==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.4.tgz", + "integrity": "sha512-m3GC94iK9MfIEeIBfbhJs5BqFibMtkRk8ZpKwG2QwxV0m/eEhPIV4ara6XCF1LWNAus7z58RodiZlAH71U3EhQ==", "dependencies": { "accepts": "~1.3.4", "base64id": "~2.0.0", "debug": "~4.3.2", - "engine.io": "~6.2.0", + "engine.io": "~6.2.1", "socket.io-adapter": "~2.4.0", - "socket.io-parser": "~4.2.0" + "socket.io-parser": "~4.2.1" }, "engines": { "node": ">=10.0.0" @@ -7656,23 +7329,6 @@ "source-map": "^0.6.0" } }, - "node_modules/spawn-wrap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", - "dev": true, - "dependencies": { - "foreground-child": "^2.0.0", - "is-windows": "^1.0.2", - "make-dir": "^3.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "which": "^2.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/spdx-correct": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", @@ -7712,9 +7368,9 @@ "optional": true }, "node_modules/stack-utils": { - "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==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, "dependencies": { "escape-string-regexp": "^2.0.0" @@ -7740,21 +7396,6 @@ "node": ">= 0.8" } }, - "node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "optional": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/string_decoder/node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "optional": true - }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -7841,15 +7482,15 @@ "dev": true }, "node_modules/stylelint": { - "version": "14.12.1", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.12.1.tgz", - "integrity": "sha512-ZEM4TuksChMBfuPadQsHUkbOoRySAT9QMfDvvYxdAchOJl0p+csTMBXOu6ORAAxKhwBmxqJiep8V88bXfNs3EQ==", + "version": "14.16.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.16.0.tgz", + "integrity": "sha512-X6uTi9DcxjzLV8ZUAjit1vsRtSwcls0nl07c9rqOPzvpA8IvTX/xWEkBRowS0ffevRrqkHa/ThDEu86u73FQDg==", "dev": true, "dependencies": { "@csstools/selector-specificity": "^2.0.2", "balanced-match": "^2.0.0", "colord": "^2.9.3", - "cosmiconfig": "^7.0.1", + "cosmiconfig": "^7.1.0", "css-functions-list": "^3.1.0", "debug": "^4.3.4", "fast-glob": "^3.2.12", @@ -7859,21 +7500,21 @@ "globby": "^11.1.0", "globjoin": "^0.1.4", "html-tags": "^3.2.0", - "ignore": "^5.2.0", + "ignore": "^5.2.1", "import-lazy": "^4.0.0", "imurmurhash": "^0.1.4", "is-plain-object": "^5.0.0", - "known-css-properties": "^0.25.0", + "known-css-properties": "^0.26.0", "mathml-tag-names": "^2.1.3", "meow": "^9.0.0", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "picocolors": "^1.0.0", - "postcss": "^8.4.16", + "postcss": "^8.4.19", "postcss-media-query-parser": "^0.2.3", "postcss-resolve-nested-selector": "^0.1.1", "postcss-safe-parser": "^6.0.0", - "postcss-selector-parser": "^6.0.10", + "postcss-selector-parser": "^6.0.11", "postcss-value-parser": "^4.2.0", "resolve-from": "^5.0.0", "string-width": "^4.2.3", @@ -7881,7 +7522,7 @@ "style-search": "^0.1.0", "supports-hyperlinks": "^2.3.0", "svg-tags": "^1.0.0", - "table": "^6.8.0", + "table": "^6.8.1", "v8-compile-cache": "^2.3.0", "write-file-atomic": "^4.0.2" }, @@ -7897,9 +7538,9 @@ } }, "node_modules/stylelint-config-prettier": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/stylelint-config-prettier/-/stylelint-config-prettier-9.0.3.tgz", - "integrity": "sha512-5n9gUDp/n5tTMCq1GLqSpA30w2sqWITSSEiAWQlpxkKGAUbjcemQ0nbkRvRUa0B1LgD3+hCvdL7B1eTxy1QHJg==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/stylelint-config-prettier/-/stylelint-config-prettier-9.0.4.tgz", + "integrity": "sha512-38nIGTGpFOiK5LjJ8Ma1yUgpKENxoKSOhbDNSemY7Ep0VsJoXIW9Iq/2hSt699oB9tReynfWicTAoIHiq8Rvbg==", "dev": true, "bin": { "stylelint-config-prettier": "bin/check.js", @@ -7922,15 +7563,15 @@ } }, "node_modules/stylelint-config-standard": { - "version": "28.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-28.0.0.tgz", - "integrity": "sha512-q/StuowDdDmFCravzGHAwgS9pjX0bdOQUEBBDIkIWsQuYGgYz/xsO8CM6eepmIQ1fc5bKdDVimlJZ6MoOUcJ5Q==", + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-29.0.0.tgz", + "integrity": "sha512-uy8tZLbfq6ZrXy4JKu3W+7lYLgRQBxYTUUB88vPgQ+ZzAxdrvcaSUW9hOMNLYBnwH+9Kkj19M2DHdZ4gKwI7tg==", "dev": true, "dependencies": { "stylelint-config-recommended": "^9.0.0" }, "peerDependencies": { - "stylelint": "^14.11.0" + "stylelint": "^14.14.0" } }, "node_modules/stylelint-prettier": { @@ -8031,9 +7672,9 @@ "dev": true }, "node_modules/table": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", "dev": true, "dependencies": { "ajv": "^8.0.1", @@ -8047,9 +7688,9 @@ } }, "node_modules/table/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", @@ -8068,22 +7709,6 @@ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "dev": true }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -8118,19 +7743,11 @@ "node": ">=4" } }, - "node_modules/to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "optional": true, - "engines": { - "node": ">=6" - } - }, "node_modules/to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, "dependencies": { "is-number": "^7.0.0" }, @@ -8211,15 +7828,6 @@ "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" } }, - "node_modules/tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", - "optional": true, - "engines": { - "node": ">=0.6.11 <=0.7.0 || >=0.7.3" - } - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -8263,25 +7871,10 @@ "node": ">= 0.6" } }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "optional": true - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, "node_modules/typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", "dev": true, "peer": true, "bin": { @@ -8310,9 +7903,9 @@ } }, "node_modules/update-browserslist-db": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz", - "integrity": "sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "dev": true, "funding": [ { @@ -8353,23 +7946,11 @@ "requires-port": "^1.0.0" } }, - "node_modules/url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", - "optional": true, - "dependencies": { - "prepend-http": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "devOptional": true + "dev": true }, "node_modules/utils-merge": { "version": "1.0.1", @@ -8380,9 +7961,9 @@ } }, "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==", "bin": { "uuid": "dist/bin/uuid" } @@ -8407,6 +7988,12 @@ "node": ">=10.12.0" } }, + "node_modules/v8-to-istanbul/node_modules/convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + }, "node_modules/validate-npm-package-license": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", @@ -8425,25 +8012,16 @@ "node": ">= 0.8" } }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dev": true, - "dependencies": { - "browser-process-hrtime": "^1.0.0" - } - }, "node_modules/w3c-xmlserializer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", - "integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", "dev": true, "dependencies": { "xml-name-validator": "^4.0.0" }, "engines": { - "node": ">=12" + "node": ">=14" } }, "node_modules/walker": { @@ -8512,12 +8090,6 @@ "node": ">= 8" } }, - "node_modules/which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", - "dev": true - }, "node_modules/word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -8562,9 +8134,9 @@ } }, "node_modules/ws": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.9.0.tgz", - "integrity": "sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", "dev": true, "engines": { "node": ">=10.0.0" @@ -8607,10 +8179,10 @@ } }, "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "devOptional": true + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true }, "node_modules/yaml": { "version": "1.10.2", @@ -8622,18 +8194,18 @@ } }, "node_modules/yargs": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", - "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", "dev": true, "dependencies": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" + "yargs-parser": "^21.1.1" }, "engines": { "node": ">=12" @@ -8700,41 +8272,49 @@ } }, "@babel/compat-data": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.19.3.tgz", - "integrity": "sha512-prBHMK4JYYK+wDjJF1q99KK4JLL+egWS4nmNqdlMUgCExMZ+iZW0hGhyC3VEbsPjvaN0TBhW//VIFwBrk8sEiw==", + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", + "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==", "dev": true }, "@babel/core": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz", - "integrity": "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.7.tgz", + "integrity": "sha512-t1ZjCluspe5DW24bn2Rr1CDb2v9rn/hROtg9a2tmd0+QYf4bsloYfLQzjG4qHPNMhWtKdGC33R5AxGR2Af2cBw==", "dev": true, "requires": { "@ampproject/remapping": "^2.1.0", "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.3", - "@babel/helper-compilation-targets": "^7.19.3", - "@babel/helper-module-transforms": "^7.19.0", - "@babel/helpers": "^7.19.0", - "@babel/parser": "^7.19.3", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.3", - "@babel/types": "^7.19.3", + "@babel/generator": "^7.20.7", + "@babel/helper-compilation-targets": "^7.20.7", + "@babel/helper-module-transforms": "^7.20.7", + "@babel/helpers": "^7.20.7", + "@babel/parser": "^7.20.7", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.7", + "@babel/types": "^7.20.7", "convert-source-map": "^1.7.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", "json5": "^2.2.1", "semver": "^6.3.0" + }, + "dependencies": { + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + } } }, "@babel/generator": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.19.3.tgz", - "integrity": "sha512-fqVZnmp1ncvZU757UzDheKZpfPgatqY59XtW2/j/18H7u76akb8xqvjw82f+i2UKd/ksYsSick/BCLQUUtJ/qQ==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.7.tgz", + "integrity": "sha512-7wqMOJq8doJMZmP4ApXTzLxSr7+oO2jroJURrVEp6XShrQUObV8Tq/D0NCcoYg2uHqUrjzO0zwBjoYzelxK+sw==", "dev": true, "requires": { - "@babel/types": "^7.19.3", + "@babel/types": "^7.20.7", "@jridgewell/gen-mapping": "^0.3.2", "jsesc": "^2.5.1" }, @@ -8753,14 +8333,15 @@ } }, "@babel/helper-compilation-targets": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.19.3.tgz", - "integrity": "sha512-65ESqLGyGmLvgR0mst5AdW1FkNlj9rQsCKduzEoEPhBCDFGXvz2jW6bXFG6i0/MrV2s7hhXjjb2yAzcPuQlLwg==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz", + "integrity": "sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==", "dev": true, "requires": { - "@babel/compat-data": "^7.19.3", + "@babel/compat-data": "^7.20.5", "@babel/helper-validator-option": "^7.18.6", "browserslist": "^4.21.3", + "lru-cache": "^5.1.1", "semver": "^6.3.0" } }, @@ -8799,34 +8380,34 @@ } }, "@babel/helper-module-transforms": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.19.0.tgz", - "integrity": "sha512-3HBZ377Fe14RbLIA+ac3sY4PTgpxHVkFrESaWhoI5PuyXPBBX8+C34qblV9G89ZtycGJCmCI/Ut+VUDK4bltNQ==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.7.tgz", + "integrity": "sha512-FNdu7r67fqMUSVuQpFQGE6BPdhJIhitoxhGzDbAXNcA07uoVG37fOiMk3OSV8rEICuyG6t8LGkd9EE64qIEoIA==", "dev": true, "requires": { "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.18.6", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.7", + "@babel/types": "^7.20.7" } }, "@babel/helper-plugin-utils": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.19.0.tgz", - "integrity": "sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", "dev": true }, "@babel/helper-simple-access": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.18.6.tgz", - "integrity": "sha512-iNpIgTgyAvDQpDj76POqg+YEt8fPxx3yaNBg3S30dxNKm2SWfYhD0TGrK/Eu9wHpUW63VQU894TsTg+GLbUa1g==", + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", "dev": true, "requires": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.20.2" } }, "@babel/helper-split-export-declaration": { @@ -8839,9 +8420,9 @@ } }, "@babel/helper-string-parser": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.18.10.tgz", - "integrity": "sha512-XtIfWmeNY3i4t7t4D2t02q50HvqHybPqW2ki1kosnvWCwuCMeo81Jf0gwr85jy/neUdg5XDdeFE/80DXiO+njw==", + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", "dev": true }, "@babel/helper-validator-identifier": { @@ -8857,14 +8438,14 @@ "dev": true }, "@babel/helpers": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.19.0.tgz", - "integrity": "sha512-DRBCKGwIEdqY3+rPJgG/dKfQy9+08rHIAJx8q2p+HSWP87s2HCrQmaAMMyMll2kIXKCW0cO1RdQskx15Xakftg==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.7.tgz", + "integrity": "sha512-PBPjs5BppzsGaxHQCDKnZ6Gd9s6xl8bBCluz3vEInLGRJmnZan4F6BYCeqtyXqkk4W5IlPmjK4JlOuZkpJ3xZA==", "dev": true, "requires": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "@babel/template": "^7.20.7", + "@babel/traverse": "^7.20.7", + "@babel/types": "^7.20.7" } }, "@babel/highlight": { @@ -8937,9 +8518,9 @@ } }, "@babel/parser": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.19.3.tgz", - "integrity": "sha512-pJ9xOlNWHiy9+FuFP09DEAFbAn4JskgRsVcc169w2xRBC3FRGuQEwjeIMMND9L2zc0iEhO/tGv4Zq+km+hxNpQ==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.7.tgz", + "integrity": "sha512-T3Z9oHybU+0vZlY9CiDSJQTD5ZapcW18ZctFMi0MOAl/4BjFF4ul7NVSARLdbGO5vDqy9eQiGTV0LtKfvCYvcg==", "dev": true }, "@babel/plugin-syntax-async-generators": { @@ -9060,39 +8641,39 @@ } }, "@babel/plugin-syntax-typescript": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.18.6.tgz", - "integrity": "sha512-mAWAuq4rvOepWCBid55JuRNvpTNf2UGVgoz4JV0fXEKolsVZDzsa4NqCef758WZJj/GDu0gVGItjKFiClTAmZA==", + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.20.0.tgz", + "integrity": "sha512-rd9TkG+u1CExzS4SM1BlMEhMXwFLKVjOAFFCDx9PbX5ycJWDoWMcwdJH9RhkPu1dOgn5TrxLot/Gx6lWFuAUNQ==", "dev": true, "requires": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.19.0" } }, "@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.20.7.tgz", + "integrity": "sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==", "dev": true, "requires": { "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7" } }, "@babel/traverse": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.19.3.tgz", - "integrity": "sha512-qh5yf6149zhq2sgIXmwjnsvmnNQC2iw70UFjp4olxucKrWd/dvlUsBI88VSLUsnMNF7/vnOiA+nk1+yLoCqROQ==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.7.tgz", + "integrity": "sha512-xueOL5+ZKX2dJbg8z8o4f4uTRTqGDRjilva9D1hiRlayJbTY8jBRL+Ph67IeRTIE439/VifHk+Z4g0SwRtQE0A==", "dev": true, "requires": { "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.3", + "@babel/generator": "^7.20.7", "@babel/helper-environment-visitor": "^7.18.9", "@babel/helper-function-name": "^7.19.0", "@babel/helper-hoist-variables": "^7.18.6", "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/parser": "^7.19.3", - "@babel/types": "^7.19.3", + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", "debug": "^4.1.0", "globals": "^11.1.0" }, @@ -9106,12 +8687,12 @@ } }, "@babel/types": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.3.tgz", - "integrity": "sha512-hGCaQzIY22DJlDh9CH7NOxgKkFjBk0Cw9xDO1Xmh2151ti7wiGfQ3LauXzL4HP1fmFlTX6XjpRETTpUcv7wQLw==", + "version": "7.20.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.7.tgz", + "integrity": "sha512-69OnhBxSSgK0OzTJai4kyPDiKTIe3j+ctaHdIGVbRahTLAT7L3R9oeXHC2aVSuGYt3cVnoAMDmOCgJ2yaiLMvg==", "dev": true, "requires": { - "@babel/helper-string-parser": "^7.18.10", + "@babel/helper-string-parser": "^7.19.4", "@babel/helper-validator-identifier": "^7.19.1", "to-fast-properties": "^2.0.0" } @@ -9130,26 +8711,25 @@ "requires": {} }, "@electron/get": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-1.14.1.tgz", - "integrity": "sha512-BrZYyL/6m0ZXz/lDxy/nlVhQz+WF+iPS6qXolEU8atw7h6v1aYkjwJZ63m+bJMBTxDE66X+r2tPS4a/8C82sZw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.2.tgz", + "integrity": "sha512-eFZVFoRXb3GFGd7Ak7W4+6jBl9wBtiZ4AaYOse97ej6mKj5tkyO0dUnUChs1IhJZtx1BENo4/p4WUTXpi6vT+g==", "optional": true, "requires": { "debug": "^4.1.1", "env-paths": "^2.2.0", "fs-extra": "^8.1.0", "global-agent": "^3.0.0", - "global-tunnel-ng": "^2.7.1", - "got": "^9.6.0", + "got": "^11.8.5", "progress": "^2.0.3", "semver": "^6.2.0", "sumchecker": "^3.0.1" } }, "@es-joy/jsdoccomment": { - "version": "0.31.0", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.31.0.tgz", - "integrity": "sha512-tc1/iuQcnaiSIUVad72PBierDFpsxdUHtEF/OrfqvM1CBAsIoMP51j52jTMb3dXriwhieTo289InzZj72jL3EQ==", + "version": "0.36.1", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.36.1.tgz", + "integrity": "sha512-922xqFsTpHs6D0BUiG4toiyPOMc8/jafnWKxz1KWgS4XzKPy2qXf1Pe6UFuNSCQqt6tOuhAWXBNuuyUhJmw9Vg==", "dev": true, "requires": { "comment-parser": "1.3.1", @@ -9158,14 +8738,14 @@ } }, "@eslint/eslintrc": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.2.tgz", - "integrity": "sha512-AXYd23w1S/bv3fTs3Lz0vjiYemS08jWkI3hYyS9I1ry+0f+Yjs1wm+sU0BS8qDOPrBIkp4qHYC16I8uVtpLajQ==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.0.tgz", + "integrity": "sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A==", "requires": { "ajv": "^6.12.4", "debug": "^4.3.2", "espree": "^9.4.0", - "globals": "^13.15.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -9174,20 +8754,15 @@ } }, "@humanwhocodes/config-array": { - "version": "0.10.5", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.10.5.tgz", - "integrity": "sha512-XVVDtp+dVvRxMoxSiSfasYaG02VEe1qH5cKgMQJWhol6HwzbcqoCMJi8dAGoYAO57jhUyhI6cWuRiTcRaDaYug==", + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", "requires": { "@humanwhocodes/object-schema": "^1.2.1", "debug": "^4.1.1", - "minimatch": "^3.0.4" + "minimatch": "^3.0.5" } }, - "@humanwhocodes/gitignore-to-minimatch": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@humanwhocodes/gitignore-to-minimatch/-/gitignore-to-minimatch-1.0.2.tgz", - "integrity": "sha512-rSqmMJDdLFUsyxR6FMtD00nfQKKLFb1kv+qBbOVKqErvloEIJLo5bDTJTQNTYgeyp78JsA7u/NPi5jT1GR/MuA==" - }, "@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", @@ -9288,123 +8863,123 @@ "dev": true }, "@jest/console": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.0.3.tgz", - "integrity": "sha512-cGg0r+klVHSYnfE977S9wmpuQ9L+iYuYgL+5bPXiUlUynLLYunRxswEmhBzvrSKGof5AKiHuTTmUKAqRcDY9dg==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.3.1.tgz", + "integrity": "sha512-IRE6GD47KwcqA09RIWrabKdHPiKDGgtAL31xDxbi/RjQMsr+lY+ppxmHwY0dUEV3qvvxZzoe5Hl0RXZJOjQNUg==", "dev": true, "requires": { - "@jest/types": "^29.0.3", + "@jest/types": "^29.3.1", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^29.0.3", - "jest-util": "^29.0.3", + "jest-message-util": "^29.3.1", + "jest-util": "^29.3.1", "slash": "^3.0.0" } }, "@jest/core": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.0.3.tgz", - "integrity": "sha512-1d0hLbOrM1qQE3eP3DtakeMbKTcXiXP3afWxqz103xPyddS2NhnNghS7MaXx1dcDt4/6p4nlhmeILo2ofgi8cQ==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.3.1.tgz", + "integrity": "sha512-0ohVjjRex985w5MmO5L3u5GR1O30DexhBSpuwx2P+9ftyqHdJXnk7IUWiP80oHMvt7ubHCJHxV0a0vlKVuZirw==", "dev": true, "requires": { - "@jest/console": "^29.0.3", - "@jest/reporters": "^29.0.3", - "@jest/test-result": "^29.0.3", - "@jest/transform": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/console": "^29.3.1", + "@jest/reporters": "^29.3.1", + "@jest/test-result": "^29.3.1", + "@jest/transform": "^29.3.1", + "@jest/types": "^29.3.1", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "ci-info": "^3.2.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.0.0", - "jest-config": "^29.0.3", - "jest-haste-map": "^29.0.3", - "jest-message-util": "^29.0.3", - "jest-regex-util": "^29.0.0", - "jest-resolve": "^29.0.3", - "jest-resolve-dependencies": "^29.0.3", - "jest-runner": "^29.0.3", - "jest-runtime": "^29.0.3", - "jest-snapshot": "^29.0.3", - "jest-util": "^29.0.3", - "jest-validate": "^29.0.3", - "jest-watcher": "^29.0.3", + "jest-changed-files": "^29.2.0", + "jest-config": "^29.3.1", + "jest-haste-map": "^29.3.1", + "jest-message-util": "^29.3.1", + "jest-regex-util": "^29.2.0", + "jest-resolve": "^29.3.1", + "jest-resolve-dependencies": "^29.3.1", + "jest-runner": "^29.3.1", + "jest-runtime": "^29.3.1", + "jest-snapshot": "^29.3.1", + "jest-util": "^29.3.1", + "jest-validate": "^29.3.1", + "jest-watcher": "^29.3.1", "micromatch": "^4.0.4", - "pretty-format": "^29.0.3", + "pretty-format": "^29.3.1", "slash": "^3.0.0", "strip-ansi": "^6.0.0" } }, "@jest/environment": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.0.3.tgz", - "integrity": "sha512-iKl272NKxYNQNqXMQandAIwjhQaGw5uJfGXduu8dS9llHi8jV2ChWrtOAVPnMbaaoDhnI3wgUGNDvZgHeEJQCA==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.3.1.tgz", + "integrity": "sha512-pMmvfOPmoa1c1QpfFW0nXYtNLpofqo4BrCIk6f2kW4JFeNlHV2t3vd+3iDLf31e2ot2Mec0uqZfmI+U0K2CFag==", "dev": true, "requires": { - "@jest/fake-timers": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/fake-timers": "^29.3.1", + "@jest/types": "^29.3.1", "@types/node": "*", - "jest-mock": "^29.0.3" + "jest-mock": "^29.3.1" } }, "@jest/expect": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.0.3.tgz", - "integrity": "sha512-6W7K+fsI23FQ01H/BWccPyDZFrnU9QlzDcKOjrNVU5L8yUORFAJJIpmyxWPW70+X624KUNqzZwPThPMX28aXEQ==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.3.1.tgz", + "integrity": "sha512-QivM7GlSHSsIAWzgfyP8dgeExPRZ9BIe2LsdPyEhCGkZkoyA+kGsoIzbKAfZCvvRzfZioKwPtCZIt5SaoxYCvg==", "dev": true, "requires": { - "expect": "^29.0.3", - "jest-snapshot": "^29.0.3" + "expect": "^29.3.1", + "jest-snapshot": "^29.3.1" } }, "@jest/expect-utils": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.0.3.tgz", - "integrity": "sha512-i1xUkau7K/63MpdwiRqaxgZOjxYs4f0WMTGJnYwUKubsNRZSeQbLorS7+I4uXVF9KQ5r61BUPAUMZ7Lf66l64Q==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.3.1.tgz", + "integrity": "sha512-wlrznINZI5sMjwvUoLVk617ll/UYfGIZNxmbU+Pa7wmkL4vYzhV9R2pwVqUh4NWWuLQWkI8+8mOkxs//prKQ3g==", "dev": true, "requires": { - "jest-get-type": "^29.0.0" + "jest-get-type": "^29.2.0" } }, "@jest/fake-timers": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.0.3.tgz", - "integrity": "sha512-tmbUIo03x0TdtcZCESQ0oQSakPCpo7+s6+9mU19dd71MptkP4zCwoeZqna23//pgbhtT1Wq02VmA9Z9cNtvtCQ==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.3.1.tgz", + "integrity": "sha512-iHTL/XpnDlFki9Tq0Q1GGuVeQ8BHZGIYsvCO5eN/O/oJaRzofG9Xndd9HuSDBI/0ZS79pg0iwn07OMTQ7ngF2A==", "dev": true, "requires": { - "@jest/types": "^29.0.3", + "@jest/types": "^29.3.1", "@sinonjs/fake-timers": "^9.1.2", "@types/node": "*", - "jest-message-util": "^29.0.3", - "jest-mock": "^29.0.3", - "jest-util": "^29.0.3" + "jest-message-util": "^29.3.1", + "jest-mock": "^29.3.1", + "jest-util": "^29.3.1" } }, "@jest/globals": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.0.3.tgz", - "integrity": "sha512-YqGHT65rFY2siPIHHFjuCGUsbzRjdqkwbat+Of6DmYRg5shIXXrLdZoVE/+TJ9O1dsKsFmYhU58JvIbZRU1Z9w==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.3.1.tgz", + "integrity": "sha512-cTicd134vOcwO59OPaB6AmdHQMCtWOe+/DitpTZVxWgMJ+YvXL1HNAmPyiGbSHmF/mXVBkvlm8YYtQhyHPnV6Q==", "dev": true, "requires": { - "@jest/environment": "^29.0.3", - "@jest/expect": "^29.0.3", - "@jest/types": "^29.0.3", - "jest-mock": "^29.0.3" + "@jest/environment": "^29.3.1", + "@jest/expect": "^29.3.1", + "@jest/types": "^29.3.1", + "jest-mock": "^29.3.1" } }, "@jest/reporters": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.0.3.tgz", - "integrity": "sha512-3+QU3d4aiyOWfmk1obDerie4XNCaD5Xo1IlKNde2yGEi02WQD+ZQD0i5Hgqm1e73sMV7kw6pMlCnprtEwEVwxw==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.3.1.tgz", + "integrity": "sha512-GhBu3YFuDrcAYW/UESz1JphEAbvUjaY2vShRZRoRY1mxpCMB3yGSJ4j9n0GxVlEOdCf7qjvUfBCrTUUqhVfbRA==", "dev": true, "requires": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.0.3", - "@jest/test-result": "^29.0.3", - "@jest/transform": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/console": "^29.3.1", + "@jest/test-result": "^29.3.1", + "@jest/transform": "^29.3.1", + "@jest/types": "^29.3.1", "@jridgewell/trace-mapping": "^0.3.15", "@types/node": "*", "chalk": "^4.0.0", @@ -9417,13 +8992,12 @@ "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.0.3", - "jest-util": "^29.0.3", - "jest-worker": "^29.0.3", + "jest-message-util": "^29.3.1", + "jest-util": "^29.3.1", + "jest-worker": "^29.3.1", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", - "terminal-link": "^2.0.0", "v8-to-istanbul": "^9.0.1" } }, @@ -9437,9 +9011,9 @@ } }, "@jest/source-map": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.0.0.tgz", - "integrity": "sha512-nOr+0EM8GiHf34mq2GcJyz/gYFyLQ2INDhAylrZJ9mMWoW21mLBfZa0BUVPPMxVYrLjeiRe2Z7kWXOGnS0TFhQ==", + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.2.0.tgz", + "integrity": "sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ==", "dev": true, "requires": { "@jridgewell/trace-mapping": "^0.3.15", @@ -9448,46 +9022,46 @@ } }, "@jest/test-result": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.0.3.tgz", - "integrity": "sha512-vViVnQjCgTmbhDKEonKJPtcFe9G/CJO4/Np4XwYJah+lF2oI7KKeRp8t1dFvv44wN2NdbDb/qC6pi++Vpp0Dlg==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.3.1.tgz", + "integrity": "sha512-qeLa6qc0ddB0kuOZyZIhfN5q0e2htngokyTWsGriedsDhItisW7SDYZ7ceOe57Ii03sL988/03wAcBh3TChMGw==", "dev": true, "requires": { - "@jest/console": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/console": "^29.3.1", + "@jest/types": "^29.3.1", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" } }, "@jest/test-sequencer": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.0.3.tgz", - "integrity": "sha512-Hf4+xYSWZdxTNnhDykr8JBs0yBN/nxOXyUQWfotBUqqy0LF9vzcFB0jm/EDNZCx587znLWTIgxcokW7WeZMobQ==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.3.1.tgz", + "integrity": "sha512-IqYvLbieTv20ArgKoAMyhLHNrVHJfzO6ARZAbQRlY4UGWfdDnLlZEF0BvKOMd77uIiIjSZRwq3Jb3Fa3I8+2UA==", "dev": true, "requires": { - "@jest/test-result": "^29.0.3", + "@jest/test-result": "^29.3.1", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.3", + "jest-haste-map": "^29.3.1", "slash": "^3.0.0" } }, "@jest/transform": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.0.3.tgz", - "integrity": "sha512-C5ihFTRYaGDbi/xbRQRdbo5ddGtI4VSpmL6AIcZxdhwLbXMa7PcXxxqyI91vGOFHnn5aVM3WYnYKCHEqmLVGzg==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.3.1.tgz", + "integrity": "sha512-8wmCFBTVGYqFNLWfcOWoVuMuKYPUBTnTMDkdvFtAYELwDOl9RGwOsvQWGPFxDJ8AWY9xM/8xCXdqmPK3+Q5Lug==", "dev": true, "requires": { "@babel/core": "^7.11.6", - "@jest/types": "^29.0.3", + "@jest/types": "^29.3.1", "@jridgewell/trace-mapping": "^0.3.15", "babel-plugin-istanbul": "^6.1.1", "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", + "convert-source-map": "^2.0.0", "fast-json-stable-stringify": "^2.1.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.3", - "jest-regex-util": "^29.0.0", - "jest-util": "^29.0.3", + "jest-haste-map": "^29.3.1", + "jest-regex-util": "^29.2.0", + "jest-util": "^29.3.1", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", @@ -9495,9 +9069,9 @@ } }, "@jest/types": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.0.3.tgz", - "integrity": "sha512-coBJmOQvurXjN1Hh5PzF7cmsod0zLIOXpP8KD161mqNlroMhLcwpODiEzi7ZsRl5Z/AIuxpeNm8DCl43F4kz8A==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.3.1.tgz", + "integrity": "sha512-d0S0jmmTpjnhCmNpApgX3jrUZgZ22ivKJRvL2lli5hpCRoNnp1f85r2/wpKfXuYu8E7Jjh1hGfhPyup1NM5AmA==", "dev": true, "requires": { "@jest/schemas": "^29.0.0", @@ -9537,13 +9111,13 @@ "dev": true }, "@jridgewell/trace-mapping": { - "version": "0.3.15", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.15.tgz", - "integrity": "sha512-oWZNOULl+UbhsgB51uuZzglikfIKSUBO/M9W2OfEjn7cmqoAiCgmv9lyACTUacZwBz0ITnJ2NqjU8Tx0DHL88g==", + "version": "0.3.17", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz", + "integrity": "sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==", "dev": true, "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" } }, "@nodelib/fs.scandir": { @@ -9570,21 +9144,21 @@ } }, "@sinclair/typebox": { - "version": "0.24.43", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.43.tgz", - "integrity": "sha512-1orQTvtazZmsPeBroJjysvsOQCYV2yjWlebkSY38pl5vr2tdLjEJ+LoxITlGNZaH2RE19WlAwQMkH/7C14wLfw==", + "version": "0.24.51", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", + "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==", "dev": true }, "@sindresorhus/is": { - "version": "0.14.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-0.14.0.tgz", - "integrity": "sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ==", + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", "optional": true }, "@sinonjs/commons": { - "version": "1.8.3", - "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.3.tgz", - "integrity": "sha512-xkNcLAn/wZaX14RPlwizcKicDk9G3F8m2nU3L7Ukm5zBgTwiT0wsoFAHx9Jq56fJA1z/7uKGtCRu16sOUCLIHQ==", + "version": "1.8.6", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-1.8.6.tgz", + "integrity": "sha512-Ky+XkAkqPZSm3NLBeUng77EBQl3cmeJhITaGHdYH8kjVB+aun3S4XBRti2zt17mtt0mIUDiNxYeoJm6drVvBJQ==", "dev": true, "requires": { "type-detect": "4.0.8" @@ -9600,14 +9174,25 @@ } }, "@sinonjs/samsam": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.1.1.tgz", - "integrity": "sha512-cZ7rKJTLiE7u7Wi/v9Hc2fs3Ucc3jrWeMgPHbbTCeVAB2S0wOBbYlkJVeNSL04i7fdhT8wIbDq1zhC/PXTD2SA==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-7.0.1.tgz", + "integrity": "sha512-zsAk2Jkiq89mhZovB2LLOdTCxJF4hqqTToGP0ASWlhp4I1hqOjcfmZGafXntCN7MDC6yySH0mFHrYtHceOeLmw==", "dev": true, "requires": { - "@sinonjs/commons": "^1.6.0", + "@sinonjs/commons": "^2.0.0", "lodash.get": "^4.4.2", "type-detect": "^4.0.8" + }, + "dependencies": { + "@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + } } }, "@sinonjs/text-encoding": { @@ -9622,12 +9207,12 @@ "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" }, "@szmarczak/http-timer": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-1.1.2.tgz", - "integrity": "sha512-XIB2XbzHTN6ieIjfIMV9hlVcfPU26s2vafYWQcZHWXHOxiaRZYEDKEwdl129Zyg50+foYV2jCgtrqSA6qNuNSA==", + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", "optional": true, "requires": { - "defer-to-connect": "^1.0.1" + "defer-to-connect": "^2.0.0" } }, "@tootallnate/once": { @@ -9637,9 +9222,9 @@ "dev": true }, "@types/babel__core": { - "version": "7.1.19", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", - "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", + "version": "7.1.20", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.20.tgz", + "integrity": "sha512-PVb6Bg2QuscZ30FvOU7z4guG6c926D9YRvOxEaelzndpMsvP+YM74Q/dAFASpg2l6+XLalxSGxcq/lrgYWZtyQ==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -9669,23 +9254,38 @@ } }, "@types/babel__traverse": { - "version": "7.18.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.2.tgz", - "integrity": "sha512-FcFaxOr2V5KZCviw1TnutEMVUVsGt4D2hP1TAfXZAMKuHYW3xQhe3jTxNPWutgCJ3/X1c5yX8ZoGVEItxKbwBg==", + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.18.3.tgz", + "integrity": "sha512-1kbcJ40lLB7MHsj39U4Sh1uTd2E7rLEa79kmDpI6cy+XiXsteB3POdQomoq4FxszMrO3ZYchkhYJw7A2862b3w==", "dev": true, "requires": { "@babel/types": "^7.3.0" } }, + "@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "optional": true, + "requires": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, "@types/cookie": { "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.12", - "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.12.tgz", - "integrity": "sha512-vt+kDhq/M2ayberEtJcIN/hxXy1Pk+59g2FV/ZQceeaTyCtCucjL2Q7FXlFjtWn4n15KCr1NE2lNNFhp0lEThw==" + "version": "2.8.13", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.13.tgz", + "integrity": "sha512-RG8AStHlUiV5ysZQKq97copd2UmVYw3/pRMLefISZ3S1hK104Cwm7iLQ3fTKx+lsUH2CE8FlLaYeEA2LSeqYUA==", + "requires": { + "@types/node": "*" + } }, "@types/graceful-fs": { "version": "4.1.5", @@ -9696,6 +9296,12 @@ "@types/node": "*" } }, + "@types/http-cache-semantics": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", + "optional": true + }, "@types/istanbul-lib-coverage": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", @@ -9726,6 +9332,15 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "dev": true }, + "@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "optional": true, + "requires": { + "@types/node": "*" + } + }, "@types/minimatch": { "version": "3.0.5", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", @@ -9739,9 +9354,9 @@ "dev": true }, "@types/node": { - "version": "16.11.62", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.62.tgz", - "integrity": "sha512-K/ggecSdwAAy2NUW4WKmF4Rc03GKbsfP+k326UWgckoS+Rzd2PaWbjk76dSmqdLQvLTJAO9axiTUJ6488mFsYQ==" + "version": "16.18.10", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.10.tgz", + "integrity": "sha512-XU1+v7h81p7145ddPfjv7jtWvkSilpcnON3mQ+bDi9Yuf7OI56efOglXRyXWgQ57xH3fEQgh7WOJMncRHVew5w==" }, "@types/normalize-package-data": { "version": "2.4.1", @@ -9756,9 +9371,24 @@ "dev": true }, "@types/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.2.tgz", + "integrity": "sha512-KufADq8uQqo1pYKVIYzfKbJfBAc0sOeXqGbFaSpv8MRmC/zXgowNZmFcbngndGk922QDmOASEXUZCaY48gs4cg==", + "dev": true + }, + "@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "optional": true, + "requires": { + "@types/node": "*" + } + }, + "@types/semver": { + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==", "dev": true }, "@types/stack-utils": { @@ -9768,9 +9398,9 @@ "dev": true }, "@types/yargs": { - "version": "17.0.13", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz", - "integrity": "sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==", + "version": "17.0.17", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.17.tgz", + "integrity": "sha512-72bWxFKTK6uwWJAVT+3rF6Jo6RTojiJ27FQo8Rf60AL+VZbzoVPnMFhKsUnbjR8A3BTCYQ7Mv3hnl8T0A+CX9g==", "dev": true, "requires": { "@types/yargs-parser": "*" @@ -9782,30 +9412,39 @@ "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", "dev": true }, + "@types/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "optional": true, + "requires": { + "@types/node": "*" + } + }, "@typescript-eslint/scope-manager": { - "version": "5.38.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.38.1.tgz", - "integrity": "sha512-BfRDq5RidVU3RbqApKmS7RFMtkyWMM50qWnDAkKgQiezRtLKsoyRKIvz1Ok5ilRWeD9IuHvaidaLxvGx/2eqTQ==", + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.0.tgz", + "integrity": "sha512-dvJab4bFf7JVvjPuh3sfBUWsiD73aiftKBpWSfi3sUkysDQ4W8x+ZcFpNp7Kgv0weldhpmMOZBjx1wKN8uWvAw==", "dev": true, "requires": { - "@typescript-eslint/types": "5.38.1", - "@typescript-eslint/visitor-keys": "5.38.1" + "@typescript-eslint/types": "5.47.0", + "@typescript-eslint/visitor-keys": "5.47.0" } }, "@typescript-eslint/types": { - "version": "5.38.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.38.1.tgz", - "integrity": "sha512-QTW1iHq1Tffp9lNfbfPm4WJabbvpyaehQ0SrvVK2yfV79SytD9XDVxqiPvdrv2LK7DGSFo91TB2FgWanbJAZXg==", + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.0.tgz", + "integrity": "sha512-eslFG0Qy8wpGzDdYKu58CEr3WLkjwC5Usa6XbuV89ce/yN5RITLe1O8e+WFEuxnfftHiJImkkOBADj58ahRxSg==", "dev": true }, "@typescript-eslint/typescript-estree": { - "version": "5.38.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.38.1.tgz", - "integrity": "sha512-99b5e/Enoe8fKMLdSuwrfH/C0EIbpUWmeEKHmQlGZb8msY33qn1KlkFww0z26o5Omx7EVjzVDCWEfrfCDHfE7g==", + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.0.tgz", + "integrity": "sha512-LxfKCG4bsRGq60Sqqu+34QT5qT2TEAHvSCCJ321uBWywgE2dS0LKcu5u+3sMGo+Vy9UmLOhdTw5JHzePV/1y4Q==", "dev": true, "requires": { - "@typescript-eslint/types": "5.38.1", - "@typescript-eslint/visitor-keys": "5.38.1", + "@typescript-eslint/types": "5.47.0", + "@typescript-eslint/visitor-keys": "5.47.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", @@ -9813,29 +9452,46 @@ "tsutils": "^3.21.0" }, "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, "@typescript-eslint/utils": { - "version": "5.38.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.38.1.tgz", - "integrity": "sha512-oIuUiVxPBsndrN81oP8tXnFa/+EcZ03qLqPDfSZ5xIJVm7A9V0rlkQwwBOAGtrdN70ZKDlKv+l1BeT4eSFxwXA==", + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.47.0.tgz", + "integrity": "sha512-U9xcc0N7xINrCdGVPwABjbAKqx4GK67xuMV87toI+HUqgXj26m6RBp9UshEXcTrgCkdGYFzgKLt8kxu49RilDw==", "dev": true, "requires": { "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.38.1", - "@typescript-eslint/types": "5.38.1", - "@typescript-eslint/typescript-estree": "5.38.1", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.47.0", + "@typescript-eslint/types": "5.47.0", + "@typescript-eslint/typescript-estree": "5.47.0", "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" + "eslint-utils": "^3.0.0", + "semver": "^7.3.7" }, "dependencies": { "eslint-scope": { @@ -9853,16 +9509,40 @@ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, "@typescript-eslint/visitor-keys": { - "version": "5.38.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.38.1.tgz", - "integrity": "sha512-bSHr1rRxXt54+j2n4k54p4fj8AHJ49VDWtjpImOpzQj4qjAiOpPni+V1Tyajh19Api1i844F757cur8wH3YvOA==", + "version": "5.47.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.0.tgz", + "integrity": "sha512-ByPi5iMa6QqDXe/GmT/hR6MZtVPi0SqMQPDx15FczCBXJo/7M8T88xReOALAfpBLm+zxpPfmhuEvPb577JRAEg==", "dev": true, "requires": { - "@typescript-eslint/types": "5.38.1", + "@typescript-eslint/types": "5.47.0", "eslint-visitor-keys": "^3.3.0" } }, @@ -9882,26 +9562,18 @@ } }, "acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==" + "version": "8.8.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.1.tgz", + "integrity": "sha512-7zFpHzhnqYKrkYdUjF1HI1bzd0VygEGX8lFk4k5zVMqHEoES+P+7TKI+EvLO9WVMJ8eekdO0aDEK044xTXwPPA==" }, "acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-7.0.1.tgz", + "integrity": "sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==", "dev": true, "requires": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - }, - "dependencies": { - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - } + "acorn": "^8.1.0", + "acorn-walk": "^8.0.2" } }, "acorn-jsx": { @@ -9911,9 +9583,9 @@ "requires": {} }, "acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", + "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", "dev": true }, "agent-base": { @@ -9925,16 +9597,6 @@ "debug": "4" } }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, "ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", @@ -9977,30 +9639,15 @@ } }, "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", "dev": true, "requires": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" } }, - "append-transform": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", - "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", - "dev": true, - "requires": { - "default-require-extensions": "^3.0.0" - } - }, - "archy": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", - "integrity": "sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==", - "dev": true - }, "argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", @@ -10020,7 +9667,8 @@ "array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==" + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true }, "arrify": { "version": "2.0.1", @@ -10037,27 +9685,28 @@ "asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", - "dev": true + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" }, "axios": { - "version": "0.26.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.26.1.tgz", - "integrity": "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==", + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.1.3.tgz", + "integrity": "sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA==", "requires": { - "follow-redirects": "^1.14.8" + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" } }, "babel-jest": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.0.3.tgz", - "integrity": "sha512-ApPyHSOhS/sVzwUOQIWJmdvDhBsMG01HX9z7ogtkp1TToHGGUWFlnXJUIzCgKPSfiYLn3ibipCYzsKSURHEwLg==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.3.1.tgz", + "integrity": "sha512-aard+xnMoxgjwV70t0L6wkW/3HQQtV+O0PEimxKgzNqCJnbYmroPojdP2tqKSOAt8QAKV/uSZU8851M7B5+fcA==", "dev": true, "requires": { - "@jest/transform": "^29.0.3", + "@jest/transform": "^29.3.1", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.0.2", + "babel-preset-jest": "^29.2.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" @@ -10077,9 +9726,9 @@ } }, "babel-plugin-jest-hoist": { - "version": "29.0.2", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.0.2.tgz", - "integrity": "sha512-eBr2ynAEFjcebVvu8Ktx580BD1QKCrBG1XwEUTXJe285p9HA/4hOhfWCFRQhTKSyBV0VzjhG7H91Eifz9s29hg==", + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.2.0.tgz", + "integrity": "sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA==", "dev": true, "requires": { "@babel/template": "^7.3.3", @@ -10109,12 +9758,12 @@ } }, "babel-preset-jest": { - "version": "29.0.2", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.0.2.tgz", - "integrity": "sha512-BeVXp7rH5TK96ofyEnHjznjLMQ2nAeDJ+QzxKnHAAMs0RgrQsCywjAN8m4mOm5Di0pxU//3AoEeJJrerMH5UeA==", + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.2.0.tgz", + "integrity": "sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA==", "dev": true, "requires": { - "babel-plugin-jest-hoist": "^29.0.2", + "babel-plugin-jest-hoist": "^29.2.0", "babel-preset-current-node-syntax": "^1.0.0" } }, @@ -10151,9 +9800,9 @@ } }, "body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", + "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", "requires": { "bytes": "3.1.2", "content-type": "~1.0.4", @@ -10163,7 +9812,7 @@ "http-errors": "2.0.0", "iconv-lite": "0.4.24", "on-finished": "2.4.1", - "qs": "6.10.3", + "qs": "6.11.0", "raw-body": "2.5.1", "type-is": "~1.6.18", "unpipe": "1.0.0" @@ -10211,16 +9860,11 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, "requires": { "fill-range": "^7.0.1" } }, - "browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, "browserslist": { "version": "4.21.4", "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", @@ -10252,69 +9896,32 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==", - "devOptional": true + "dev": true }, "bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" }, + "cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "optional": true + }, "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", + "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", "optional": true, "requires": { "clone-response": "^1.0.2", "get-stream": "^5.1.0", "http-cache-semantics": "^4.0.0", - "keyv": "^3.0.0", + "keyv": "^4.0.0", "lowercase-keys": "^2.0.0", - "normalize-url": "^4.1.0", - "responselike": "^1.0.2" - }, - "dependencies": { - "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==", - "optional": true, - "requires": { - "pump": "^3.0.0" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "optional": true - } - } - }, - "caching-transform": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", - "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", - "dev": true, - "requires": { - "hasha": "^5.0.0", - "make-dir": "^3.0.0", - "package-hash": "^4.0.0", - "write-file-atomic": "^3.0.0" - }, - "dependencies": { - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - } + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" } }, "call-bind": { @@ -10346,12 +9953,20 @@ "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.30001412", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001412.tgz", - "integrity": "sha512-+TeEIee1gS5bYOiuf+PS/kp2mrXic37Hl66VY6EAfxasIk5fELTktK2oOezYed12H8w7jt3s512PpulQidPjwA==", + "version": "1.0.30001441", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001441.tgz", + "integrity": "sha512-OyxRR4Vof59I3yGWXws6i908EtGbMzVUi3ganaZQHmydk1iwDhRnvaPG2WaR0KcqrDFKrxVZHULT396LEPhXfg==", "dev": true }, "chalk": { @@ -10375,9 +9990,9 @@ "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==" }, "ci-info": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.4.0.tgz", - "integrity": "sha512-t5QdPT5jq3o262DOQ8zA6E1tlH2upmUc4Hlvrbx1pGYJuiiHl7O7rvVNI+l8HTVhd/q3Qc9vqimkNk5yiXsAug==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.7.0.tgz", + "integrity": "sha512-2CpRNYmImPx+RXKLq6jko/L07phmS9I02TyqkcNU20GCF/GgaWvc58hPtjxDX8lPpkdwc9sNh72V9k00S7ezog==", "dev": true }, "cjs-module-lexer": { @@ -10391,20 +10006,14 @@ "resolved": "https://registry.npmjs.org/clarinet/-/clarinet-0.12.5.tgz", "integrity": "sha512-4833ySquSUW91fnPaYI94LX3OdnyfwD8/NrMi6a4Kt6EmOsphLWmEzx9bZPqO9+DtQzSv2s3WSYNLsrXt59FKg==" }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", "dev": true, "requires": { "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", + "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, @@ -10457,7 +10066,6 @@ "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "dev": true, "requires": { "delayed-stream": "~1.0.0" } @@ -10468,43 +10076,15 @@ "integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==", "dev": true }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==", - "dev": true - }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==" }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "optional": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "config-chain": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz", - "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==", - "optional": true, - "requires": { - "ini": "^1.3.4", - "proto-list": "~1.2.1" - } - }, "console-stamp": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/console-stamp/-/console-stamp-3.0.6.tgz", - "integrity": "sha512-j4tP+1shVIUjSnvrtv5nJ5uVzLeNOTweVHkcEXB2ej4NJdlRp14w0hOzQiF+iQvOTjz4jafmdhd1CdYSwNzM8Q==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/console-stamp/-/console-stamp-3.1.0.tgz", + "integrity": "sha512-Vt22288o0Hrxb9uYwXMWYuw/Mu8iPSrFPtIiveq9uE0zWXPDDCAIvKZojqnwcyINnJY9tnTeG0neV/MD+2G5+g==", "requires": { "chalk": "^4.1.2", "dateformat": "^4.6.3" @@ -10524,21 +10104,10 @@ "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true - } - } + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true }, "cookie": { "version": "0.5.0", @@ -10550,12 +10119,6 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, - "core-util-is": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", - "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", - "optional": true - }, "cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", @@ -10566,9 +10129,9 @@ } }, "cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz", + "integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==", "dev": true, "requires": { "@types/parse-json": "^4.0.0", @@ -10659,9 +10222,9 @@ "dev": true }, "decamelize-keys": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.0.tgz", - "integrity": "sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/decamelize-keys/-/decamelize-keys-1.1.1.tgz", + "integrity": "sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==", "dev": true, "requires": { "decamelize": "^1.1.0", @@ -10677,18 +10240,26 @@ } }, "decimal.js": { - "version": "10.4.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.1.tgz", - "integrity": "sha512-F29o+vci4DodHYT9UrR5IEbfBw9pE5eSapIJdTqXK5+6hq+t8VRxwQyKlW2i+KDKFkkJQRvFyI/QXD83h8LyQw==", + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", "dev": true }, "decompress-response": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-3.3.0.tgz", - "integrity": "sha512-BzRPQuY1ip+qDonAOz42gRm/pg9F768C+npV/4JOsxRC2sq+Rlk+Q4ZCAsOhnIaMrgarILY+RMUIvMmmX1qAEA==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", "optional": true, "requires": { - "mimic-response": "^1.0.0" + "mimic-response": "^3.1.0" + }, + "dependencies": { + "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==", + "optional": true + } } }, "dedent": { @@ -10708,19 +10279,10 @@ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", "dev": true }, - "default-require-extensions": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", - "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", - "dev": true, - "requires": { - "strip-bom": "^4.0.0" - } - }, "defer-to-connect": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-1.1.3.tgz", - "integrity": "sha512-0ISdNousHvZT2EiFlZeZAHBUvSxmKswVCEf8hW7KWgG4a8MVEu/3Vb6uWYozkjylyCxe0JBIiRB1jV45S70WVQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", "optional": true }, "define-properties": { @@ -10736,8 +10298,7 @@ "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", - "dev": true + "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, "depd": { "version": "2.0.0", @@ -10768,17 +10329,19 @@ "dev": true }, "diff-sequences": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.0.0.tgz", - "integrity": "sha512-7Qe/zd1wxSDL4D/X/FPjOMB+ZMDt71W94KYaq05I2l0oQqgXgs7s4ftYYmV38gBSrPz2vcygxfs1xn0FT+rKNA==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.3.1.tgz", + "integrity": "sha512-hlM3QR272NXCi4pq+N4Kok4kOp6EsgOM3ZSpJI7Da3UAs+Ttsi8MRmB6trM/lhyzUxGfOgnpkHtgqm5Q/CTcfQ==", "dev": true }, "digest-fetch": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-1.3.0.tgz", - "integrity": "sha512-CGJuv6iKNM7QyZlM2T3sPAdZWd/p9zQiRNS9G+9COUCwzWFTs0Xp8NF5iePx7wtvhDykReiRRrSeNb4oMmB8lA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/digest-fetch/-/digest-fetch-2.0.1.tgz", + "integrity": "sha512-OgzIWveqj8BlQ8hfJv97a9iOzWOgvI5Z3rGAnjkeNpHepHZpD/DHBDJ9mtfDclH5vkbUSGRqNEosYCH1FSO6Pg==", "requires": { "base-64": "^0.1.0", + "js-sha256": "^0.9.0", + "js-sha512": "^0.8.0", "md5": "^2.3.0" } }, @@ -10786,6 +10349,7 @@ "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", + "dev": true, "requires": { "path-type": "^4.0.0" } @@ -10807,38 +10371,32 @@ "webidl-conversions": "^7.0.0" } }, - "duplexer3": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/duplexer3/-/duplexer3-0.1.5.tgz", - "integrity": "sha512-1A8za6ws41LQgv9HrE/66jyC5yuSjQ3L/KOpFtoBilsAK2iA2wuS5rTt1OCzIvtS2V7nVmedsUU+DGRcjBmOYA==", - "optional": true - }, "ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==" }, "electron": { - "version": "19.1.0", - "resolved": "https://registry.npmjs.org/electron/-/electron-19.1.0.tgz", - "integrity": "sha512-5o9EEYx0bI0p+L0eSoS8n3gLrEvkdnzwSZ/hnkPoUfuAs/CONCI/TEqswSppeeJ/pi5gXf3/B7hVTNaZZbIdnw==", + "version": "22.0.0", + "resolved": "https://registry.npmjs.org/electron/-/electron-22.0.0.tgz", + "integrity": "sha512-cgRc4wjyM+81A0E8UGv1HNJjL1HBI5cWNh/DUIjzYvoUuiEM0SS0hAH/zaFQ18xOz2ced6Yih8SybpOiOYJhdg==", "optional": true, "requires": { - "@electron/get": "^1.14.1", + "@electron/get": "^2.0.0", "@types/node": "^16.11.26", - "extract-zip": "^1.0.3" + "extract-zip": "^2.0.1" } }, "electron-to-chromium": { - "version": "1.4.264", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.264.tgz", - "integrity": "sha512-AZ6ZRkucHOQT8wke50MktxtmcWZr67kE17X/nAXFf62NIdMdgY6xfsaJD5Szoy84lnkuPWH+4tTNE3s2+bPCiw==", + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==", "dev": true }, "emittery": { - "version": "0.10.2", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.10.2.tgz", - "integrity": "sha512-aITqOwnLanpHLNXZJENbOgjUBeHocD+xsSJmNrjovKBW5HbSpW3d1pEls7GFQPUWXiwG9+0P4GtHfEqC/4M0Iw==", + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", + "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true }, "emoji-regex": { @@ -10862,9 +10420,9 @@ } }, "engine.io": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.0.tgz", - "integrity": "sha512-4KzwW3F3bk+KlzSOY57fj/Jx6LyRQ1nbcyIadehl+AnXjKT7gDO0ORdRi/84ixvMKTym6ZKuxvbzN62HDDU1Lg==", + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.2.1.tgz", + "integrity": "sha512-ECceEFcAaNRybd3lsGQKas3ZlMVjN3cyWwMP25D2i0zWfyiytVbTpRPa34qrr+FHddtpBVOmq4H/DCv1O0lZRA==", "requires": { "@types/cookie": "^0.4.1", "@types/cors": "^2.8.12", @@ -10921,7 +10479,7 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "devOptional": true + "optional": true }, "escalade": { "version": "3.1.1", @@ -10994,14 +10552,14 @@ } }, "eslint": { - "version": "8.24.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.24.0.tgz", - "integrity": "sha512-dWFaPhGhTAiPcCgm3f6LI2MBWbogMnTJzFBbhXVRQDJPkr9pGZvVjlVfXd+vyDcWPA2Ic9L2AXPIQM0+vk/cSQ==", + "version": "8.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.30.0.tgz", + "integrity": "sha512-MGADB39QqYuzEGov+F/qb18r4i7DohCDOfatHaxI2iGlPuC65bwG2gxgO+7DkyL38dRFaRH7RaRAgU6JKL9rMQ==", "requires": { - "@eslint/eslintrc": "^1.3.2", - "@humanwhocodes/config-array": "^0.10.5", - "@humanwhocodes/gitignore-to-minimatch": "^1.0.2", + "@eslint/eslintrc": "^1.4.0", + "@humanwhocodes/config-array": "^0.11.8", "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", "ajv": "^6.10.0", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", @@ -11017,14 +10575,14 @@ "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", - "glob-parent": "^6.0.1", - "globals": "^13.15.0", - "globby": "^11.1.0", + "glob-parent": "^6.0.2", + "globals": "^13.19.0", "grapheme-splitter": "^1.0.4", "ignore": "^5.2.0", "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", @@ -11047,37 +10605,52 @@ "requires": {} }, "eslint-plugin-jest": { - "version": "27.0.4", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.0.4.tgz", - "integrity": "sha512-BuvY78pHMpMJ6Cio7sKg6jrqEcnRYPUc4Nlihku4vKx3FjlmMINSX4vcYokZIe+8TKcyr1aI5Kq7vYwgJNdQSA==", + "version": "27.1.7", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.1.7.tgz", + "integrity": "sha512-0QVzf+og4YI1Qr3UoprkqqhezAZjFffdi62b0IurkCXMqPtRW84/UT4CKsYT80h/D82LA9avjO/80Ou1LdgbaQ==", "dev": true, "requires": { "@typescript-eslint/utils": "^5.10.0" } }, "eslint-plugin-jsdoc": { - "version": "39.3.6", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.3.6.tgz", - "integrity": "sha512-R6dZ4t83qPdMhIOGr7g2QII2pwCjYyKP+z0tPOfO1bbAbQyKC20Y2Rd6z1te86Lq3T7uM8bNo+VD9YFpE8HU/g==", + "version": "39.6.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.6.4.tgz", + "integrity": "sha512-fskvdLCfwmPjHb6e+xNGDtGgbF8X7cDwMtVLAP2WwSf9Htrx68OAx31BESBM1FAwsN2HTQyYQq7m4aW4Q4Nlag==", "dev": true, "requires": { - "@es-joy/jsdoccomment": "~0.31.0", + "@es-joy/jsdoccomment": "~0.36.1", "comment-parser": "1.3.1", "debug": "^4.3.4", "escape-string-regexp": "^4.0.0", "esquery": "^1.4.0", - "semver": "^7.3.7", + "semver": "^7.3.8", "spdx-expression-parse": "^3.0.1" }, "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, @@ -11120,9 +10693,9 @@ "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==" }, "espree": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", - "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", "requires": { "acorn": "^8.8.0", "acorn-jsx": "^5.3.2", @@ -11198,26 +10771,26 @@ "dev": true }, "expect": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.0.3.tgz", - "integrity": "sha512-t8l5DTws3212VbmPL+tBFXhjRHLmctHB0oQbL8eUc6S7NzZtYUhycrFO9mkxA0ZUC6FAWdNi7JchJSkODtcu1Q==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.3.1.tgz", + "integrity": "sha512-gGb1yTgU30Q0O/tQq+z30KBWv24ApkMgFUpvKBkyLUBL68Wv8dHdJxTBZFl/iT8K/bqDHvUYRH6IIN3rToopPA==", "dev": true, "requires": { - "@jest/expect-utils": "^29.0.3", - "jest-get-type": "^29.0.0", - "jest-matcher-utils": "^29.0.3", - "jest-message-util": "^29.0.3", - "jest-util": "^29.0.3" + "@jest/expect-utils": "^29.3.1", + "jest-get-type": "^29.2.0", + "jest-matcher-utils": "^29.3.1", + "jest-message-util": "^29.3.1", + "jest-util": "^29.3.1" } }, "express": { - "version": "4.18.1", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.1.tgz", - "integrity": "sha512-zZBcOX9TfehHQhtupq57OF8lFZ3UZi08Y97dwFCkD8p9d/d2Y3M+ykKcwaMDEL+4qyUolgBDX6AblpR3fL212Q==", + "version": "4.18.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", + "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", "requires": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.0", + "body-parser": "1.20.1", "content-disposition": "0.5.4", "content-type": "~1.0.4", "cookie": "0.5.0", @@ -11236,7 +10809,7 @@ "parseurl": "~1.3.3", "path-to-regexp": "0.1.7", "proxy-addr": "~2.0.7", - "qs": "6.10.3", + "qs": "6.11.0", "range-parser": "~1.2.1", "safe-buffer": "5.2.1", "send": "0.18.0", @@ -11284,32 +10857,15 @@ } }, "extract-zip": { - "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==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", "optional": true, "requires": { - "concat-stream": "^1.6.2", - "debug": "^2.6.9", - "mkdirp": "^0.5.4", + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", "yauzl": "^2.10.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "optional": true, - "requires": { - "ms": "2.0.0" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "optional": true - } } }, "fast-deep-equal": { @@ -11327,6 +10883,7 @@ "version": "3.2.12", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "dev": true, "requires": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -11339,6 +10896,7 @@ "version": "5.1.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, "requires": { "is-glob": "^4.0.1" } @@ -11362,9 +10920,9 @@ "dev": true }, "fastq": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.13.0.tgz", - "integrity": "sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==", + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.14.0.tgz", + "integrity": "sha512-eR2D+V9/ExcbF9ls441yIuN6TI2ED1Y2ZcA5BmMtJsOkWOFRJQ0Jt0g1UwqXJJVAb+V+umH5Dfr8oh4EVP7VVg==", "requires": { "reusify": "^1.0.4" } @@ -11408,6 +10966,7 @@ "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, "requires": { "to-regex-range": "^5.0.1" } @@ -11441,17 +11000,6 @@ } } }, - "find-cache-dir": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.2.tgz", - "integrity": "sha512-wXZV5emFEjrridIgED11OoUKLxiYjAcqot/NJdAkOhlJ+vGzwhOAfcG5OX1jP+S0PcjEn8bdMJv+g2jwQ3Onig==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^3.0.2", - "pkg-dir": "^4.1.0" - } - }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -11480,21 +11028,10 @@ "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" }, - "foreground-child": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-2.0.0.tgz", - "integrity": "sha512-dCIq9FpEcyQyXKCkyzmlPTFNgrCzPudOe+mhvJU5zAtlBnGVy2yKxtfsxK2tQBThwq225jcvBjpw1Gr40uzZCA==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "signal-exit": "^3.0.2" - } - }, "form-data": { "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", "combined-stream": "^1.0.8", @@ -11511,12 +11048,6 @@ "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" }, - "fromentries": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", - "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", - "dev": true - }, "fs-extra": { "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", @@ -11574,10 +11105,10 @@ "dev": true }, "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "optional": true, + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "devOptional": true, "requires": { "pump": "^3.0.0" } @@ -11617,14 +11148,29 @@ "serialize-error": "^7.0.1" }, "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "optional": true, + "requires": { + "yallist": "^4.0.0" + } + }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "optional": true, "requires": { "lru-cache": "^6.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "optional": true } } }, @@ -11659,22 +11205,10 @@ } } }, - "global-tunnel-ng": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/global-tunnel-ng/-/global-tunnel-ng-2.7.1.tgz", - "integrity": "sha512-4s+DyciWBV0eK148wqXxcmVAbFVPqtc3sEtUE/GTQfuU80rySLcMhUmHKSHI7/LDj8q0gDYI1lIhRRB7ieRAqg==", - "optional": true, - "requires": { - "encodeurl": "^1.0.2", - "lodash": "^4.17.10", - "npm-conf": "^1.1.3", - "tunnel": "^0.0.6" - } - }, "globals": { - "version": "13.17.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.17.0.tgz", - "integrity": "sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==", + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", "requires": { "type-fest": "^0.20.2" } @@ -11692,6 +11226,7 @@ "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, "requires": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -11708,22 +11243,22 @@ "dev": true }, "got": { - "version": "9.6.0", - "resolved": "https://registry.npmjs.org/got/-/got-9.6.0.tgz", - "integrity": "sha512-R7eWptXuGYxwijs0eV+v3o6+XH1IqVK8dJOEecQfTmkncw9AV4dcw/Dhxi8MdlqPthxxpZyizMzyg8RTmEsG+Q==", + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", "optional": true, "requires": { - "@sindresorhus/is": "^0.14.0", - "@szmarczak/http-timer": "^1.1.2", - "cacheable-request": "^6.0.0", - "decompress-response": "^3.3.0", - "duplexer3": "^0.1.4", - "get-stream": "^4.1.0", - "lowercase-keys": "^1.0.1", - "mimic-response": "^1.0.1", - "p-cancelable": "^1.0.0", - "to-readable-stream": "^1.0.0", - "url-parse-lax": "^3.0.0" + "@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.2", + "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" } }, "graceful-fs": { @@ -11770,28 +11305,10 @@ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" }, - "hasha": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", - "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", - "dev": true, - "requires": { - "is-stream": "^2.0.0", - "type-fest": "^0.8.0" - }, - "dependencies": { - "type-fest": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", - "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", - "dev": true - } - } - }, "helmet": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/helmet/-/helmet-6.0.0.tgz", - "integrity": "sha512-FO9RpR1wNJepH/GbLPQVtkE2eESglXL641p7SdyoT4LngHFJcZheHMoyUcjCZF4qpuMMO1u5q6RK0l9Ux8JBcg==" + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-6.0.1.tgz", + "integrity": "sha512-8wo+VdQhTMVBMCITYZaGTbE4lvlthelPYSvoyNvk4RECTmrVjMerp9RfUOQXZWLvCcAn1pKj7ZRxK4lI9Alrcw==" }, "hosted-git-info": { "version": "4.1.0", @@ -11800,6 +11317,23 @@ "dev": true, "requires": { "lru-cache": "^6.0.0" + }, + "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + } } }, "html-encoding-sniffer": { @@ -11852,6 +11386,16 @@ "debug": "4" } }, + "http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "optional": true, + "requires": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + } + }, "https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -11869,9 +11413,9 @@ "dev": true }, "husky": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.1.tgz", - "integrity": "sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw==", + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.2.tgz", + "integrity": "sha512-Tkv80jtvbnkK3mYWxPZePGFpQ/tT3HNSs/sasF9P2YfkMezDl3ON37YN6jUUI4eTg5LcyVynlb6r4eyvOmspvg==", "dev": true }, "iconv-lite": { @@ -11883,9 +11427,9 @@ } }, "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==" + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz", + "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==" }, "import-fresh": { "version": "3.3.0", @@ -11941,7 +11485,7 @@ "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "devOptional": true + "dev": true }, "ip": { "version": "1.1.8", @@ -11970,9 +11514,9 @@ "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" }, "is-core-module": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.10.0.tgz", - "integrity": "sha512-Erxj2n/LDAZ7H8WNJXd9tw38GYM3dv8rk8Zcs+jJuxYTW7sozH+SS8NtrSjVL1/vpLvWi1hxy96IzjJ3EHTJJg==", + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", "dev": true, "requires": { "has": "^1.0.3" @@ -12006,7 +11550,13 @@ "is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==" + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-path-inside": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", + "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==" }, "is-plain-obj": { "version": "1.1.0", @@ -12032,23 +11582,11 @@ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "optional": true + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", + "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", + "dev": true }, "isexe": { "version": "2.0.0", @@ -12061,19 +11599,10 @@ "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", "dev": true }, - "istanbul-lib-hook": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", - "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", - "dev": true, - "requires": { - "append-transform": "^2.0.0" - } - }, "istanbul-lib-instrument": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.0.tgz", - "integrity": "sha512-6Lthe1hqXHBNsqvgDzGO6l03XNeu3CrG4RqQ1KM9+l5+jNGpEJfIELx1NS3SEHmJQA8np/u+E4EPRKRiu6m19A==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", + "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", "dev": true, "requires": { "@babel/core": "^7.12.3", @@ -12083,20 +11612,6 @@ "semver": "^6.3.0" } }, - "istanbul-lib-processinfo": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.3.tgz", - "integrity": "sha512-NkwHbo3E00oybX6NGJi6ar0B29vxyvNwoC7eJ4G4Yq28UfY758Hgn/heV8VRFhevPED4LXfFz0DQ8z/0kw9zMg==", - "dev": true, - "requires": { - "archy": "^1.0.0", - "cross-spawn": "^7.0.3", - "istanbul-lib-coverage": "^3.2.0", - "p-map": "^3.0.0", - "rimraf": "^3.0.0", - "uuid": "^8.3.2" - } - }, "istanbul-lib-report": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", @@ -12130,21 +11645,21 @@ } }, "jest": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.0.3.tgz", - "integrity": "sha512-ElgUtJBLgXM1E8L6K1RW1T96R897YY/3lRYqq9uVcPWtP2AAl/nQ16IYDh/FzQOOQ12VEuLdcPU83mbhG2C3PQ==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.3.1.tgz", + "integrity": "sha512-6iWfL5DTT0Np6UYs/y5Niu7WIfNv/wRTtN5RSXt2DIEft3dx3zPuw/3WJQBCJfmEzvDiEKwoqMbGD9n49+qLSA==", "dev": true, "requires": { - "@jest/core": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/core": "^29.3.1", + "@jest/types": "^29.3.1", "import-local": "^3.0.2", - "jest-cli": "^29.0.3" + "jest-cli": "^29.3.1" } }, "jest-changed-files": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.0.0.tgz", - "integrity": "sha512-28/iDMDrUpGoCitTURuDqUzWQoWmOmOKOFST1mi2lwh62X4BFf6khgH3uSuo1e49X/UDjuApAj3w0wLOex4VPQ==", + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.2.0.tgz", + "integrity": "sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA==", "dev": true, "requires": { "execa": "^5.0.0", @@ -12152,308 +11667,309 @@ } }, "jest-circus": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.0.3.tgz", - "integrity": "sha512-QeGzagC6Hw5pP+df1+aoF8+FBSgkPmraC1UdkeunWh0jmrp7wC0Hr6umdUAOELBQmxtKAOMNC3KAdjmCds92Zg==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.3.1.tgz", + "integrity": "sha512-wpr26sEvwb3qQQbdlmei+gzp6yoSSoSL6GsLPxnuayZSMrSd5Ka7IjAvatpIernBvT2+Ic6RLTg+jSebScmasg==", "dev": true, "requires": { - "@jest/environment": "^29.0.3", - "@jest/expect": "^29.0.3", - "@jest/test-result": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/environment": "^29.3.1", + "@jest/expect": "^29.3.1", + "@jest/test-result": "^29.3.1", + "@jest/types": "^29.3.1", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", "dedent": "^0.7.0", "is-generator-fn": "^2.0.0", - "jest-each": "^29.0.3", - "jest-matcher-utils": "^29.0.3", - "jest-message-util": "^29.0.3", - "jest-runtime": "^29.0.3", - "jest-snapshot": "^29.0.3", - "jest-util": "^29.0.3", + "jest-each": "^29.3.1", + "jest-matcher-utils": "^29.3.1", + "jest-message-util": "^29.3.1", + "jest-runtime": "^29.3.1", + "jest-snapshot": "^29.3.1", + "jest-util": "^29.3.1", "p-limit": "^3.1.0", - "pretty-format": "^29.0.3", + "pretty-format": "^29.3.1", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-cli": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.0.3.tgz", - "integrity": "sha512-aUy9Gd/Kut1z80eBzG10jAn6BgS3BoBbXyv+uXEqBJ8wnnuZ5RpNfARoskSrTIy1GY4a8f32YGuCMwibtkl9CQ==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.3.1.tgz", + "integrity": "sha512-TO/ewvwyvPOiBBuWZ0gm04z3WWP8TIK8acgPzE4IxgsLKQgb377NYGrQLc3Wl/7ndWzIH2CDNNsUjGxwLL43VQ==", "dev": true, "requires": { - "@jest/core": "^29.0.3", - "@jest/test-result": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/core": "^29.3.1", + "@jest/test-result": "^29.3.1", + "@jest/types": "^29.3.1", "chalk": "^4.0.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^29.0.3", - "jest-util": "^29.0.3", - "jest-validate": "^29.0.3", + "jest-config": "^29.3.1", + "jest-util": "^29.3.1", + "jest-validate": "^29.3.1", "prompts": "^2.0.1", "yargs": "^17.3.1" } }, "jest-config": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.0.3.tgz", - "integrity": "sha512-U5qkc82HHVYe3fNu2CRXLN4g761Na26rWKf7CjM8LlZB3In1jadEkZdMwsE37rd9RSPV0NfYaCjHdk/gu3v+Ew==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.3.1.tgz", + "integrity": "sha512-y0tFHdj2WnTEhxmGUK1T7fgLen7YK4RtfvpLFBXfQkh2eMJAQq24Vx9472lvn5wg0MAO6B+iPfJfzdR9hJYalg==", "dev": true, "requires": { "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.0.3", - "@jest/types": "^29.0.3", - "babel-jest": "^29.0.3", + "@jest/test-sequencer": "^29.3.1", + "@jest/types": "^29.3.1", + "babel-jest": "^29.3.1", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-circus": "^29.0.3", - "jest-environment-node": "^29.0.3", - "jest-get-type": "^29.0.0", - "jest-regex-util": "^29.0.0", - "jest-resolve": "^29.0.3", - "jest-runner": "^29.0.3", - "jest-util": "^29.0.3", - "jest-validate": "^29.0.3", + "jest-circus": "^29.3.1", + "jest-environment-node": "^29.3.1", + "jest-get-type": "^29.2.0", + "jest-regex-util": "^29.2.0", + "jest-resolve": "^29.3.1", + "jest-runner": "^29.3.1", + "jest-util": "^29.3.1", + "jest-validate": "^29.3.1", "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "^29.0.3", + "pretty-format": "^29.3.1", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" } }, "jest-diff": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.0.3.tgz", - "integrity": "sha512-+X/AIF5G/vX9fWK+Db9bi9BQas7M9oBME7egU7psbn4jlszLFCu0dW63UgeE6cs/GANq4fLaT+8sGHQQ0eCUfg==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.3.1.tgz", + "integrity": "sha512-vU8vyiO7568tmin2lA3r2DP8oRvzhvRcD4DjpXc6uGveQodyk7CKLhQlCSiwgx3g0pFaE88/KLZ0yaTWMc4Uiw==", "dev": true, "requires": { "chalk": "^4.0.0", - "diff-sequences": "^29.0.0", - "jest-get-type": "^29.0.0", - "pretty-format": "^29.0.3" + "diff-sequences": "^29.3.1", + "jest-get-type": "^29.2.0", + "pretty-format": "^29.3.1" } }, "jest-docblock": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.0.0.tgz", - "integrity": "sha512-s5Kpra/kLzbqu9dEjov30kj1n4tfu3e7Pl8v+f8jOkeWNqM6Ds8jRaJfZow3ducoQUrf2Z4rs2N5S3zXnb83gw==", + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.2.0.tgz", + "integrity": "sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A==", "dev": true, "requires": { "detect-newline": "^3.0.0" } }, "jest-each": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.0.3.tgz", - "integrity": "sha512-wILhZfESURHHBNvPMJ0lZlYZrvOQJxAo3wNHi+ycr90V7M+uGR9Gh4+4a/BmaZF0XTyZsk4OiYEf3GJN7Ltqzg==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.3.1.tgz", + "integrity": "sha512-qrZH7PmFB9rEzCSl00BWjZYuS1BSOH8lLuC0azQE9lQrAx3PWGKHTDudQiOSwIy5dGAJh7KA0ScYlCP7JxvFYA==", "dev": true, "requires": { - "@jest/types": "^29.0.3", + "@jest/types": "^29.3.1", "chalk": "^4.0.0", - "jest-get-type": "^29.0.0", - "jest-util": "^29.0.3", - "pretty-format": "^29.0.3" + "jest-get-type": "^29.2.0", + "jest-util": "^29.3.1", + "pretty-format": "^29.3.1" } }, "jest-environment-node": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.0.3.tgz", - "integrity": "sha512-cdZqRCnmIlTXC+9vtvmfiY/40Cj6s2T0czXuq1whvQdmpzAnj4sbqVYuZ4zFHk766xTTJ+Ij3uUqkk8KCfXoyg==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.3.1.tgz", + "integrity": "sha512-xm2THL18Xf5sIHoU7OThBPtuH6Lerd+Y1NLYiZJlkE3hbE+7N7r8uvHIl/FkZ5ymKXJe/11SQuf3fv4v6rUMag==", "dev": true, "requires": { - "@jest/environment": "^29.0.3", - "@jest/fake-timers": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/environment": "^29.3.1", + "@jest/fake-timers": "^29.3.1", + "@jest/types": "^29.3.1", "@types/node": "*", - "jest-mock": "^29.0.3", - "jest-util": "^29.0.3" + "jest-mock": "^29.3.1", + "jest-util": "^29.3.1" } }, "jest-get-type": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.0.0.tgz", - "integrity": "sha512-83X19z/HuLKYXYHskZlBAShO7UfLFXu/vWajw9ZNJASN32li8yHMaVGAQqxFW1RCFOkB7cubaL6FaJVQqqJLSw==", + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz", + "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==", "dev": true }, "jest-haste-map": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.0.3.tgz", - "integrity": "sha512-uMqR99+GuBHo0RjRhOE4iA6LmsxEwRdgiIAQgMU/wdT2XebsLDz5obIwLZm/Psj+GwSEQhw9AfAVKGYbh2G55A==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.3.1.tgz", + "integrity": "sha512-/FFtvoG1xjbbPXQLFef+WSU4yrc0fc0Dds6aRPBojUid7qlPqZvxdUBA03HW0fnVHXVCnCdkuoghYItKNzc/0A==", "dev": true, "requires": { - "@jest/types": "^29.0.3", + "@jest/types": "^29.3.1", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "fsevents": "^2.3.2", "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.0.0", - "jest-util": "^29.0.3", - "jest-worker": "^29.0.3", + "jest-regex-util": "^29.2.0", + "jest-util": "^29.3.1", + "jest-worker": "^29.3.1", "micromatch": "^4.0.4", "walker": "^1.0.8" } }, "jest-leak-detector": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.0.3.tgz", - "integrity": "sha512-YfW/G63dAuiuQ3QmQlh8hnqLDe25WFY3eQhuc/Ev1AGmkw5zREblTh7TCSKLoheyggu6G9gxO2hY8p9o6xbaRQ==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.3.1.tgz", + "integrity": "sha512-3DA/VVXj4zFOPagGkuqHnSQf1GZBmmlagpguxEERO6Pla2g84Q1MaVIB3YMxgUaFIaYag8ZnTyQgiZ35YEqAQA==", "dev": true, "requires": { - "jest-get-type": "^29.0.0", - "pretty-format": "^29.0.3" + "jest-get-type": "^29.2.0", + "pretty-format": "^29.3.1" } }, "jest-matcher-utils": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.0.3.tgz", - "integrity": "sha512-RsR1+cZ6p1hDV4GSCQTg+9qjeotQCgkaleIKLK7dm+U4V/H2bWedU3RAtLm8+mANzZ7eDV33dMar4pejd7047w==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.3.1.tgz", + "integrity": "sha512-fkRMZUAScup3txIKfMe3AIZZmPEjWEdsPJFK3AIy5qRohWqQFg1qrmKfYXR9qEkNc7OdAu2N4KPHibEmy4HPeQ==", "dev": true, "requires": { "chalk": "^4.0.0", - "jest-diff": "^29.0.3", - "jest-get-type": "^29.0.0", - "pretty-format": "^29.0.3" + "jest-diff": "^29.3.1", + "jest-get-type": "^29.2.0", + "pretty-format": "^29.3.1" } }, "jest-message-util": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.0.3.tgz", - "integrity": "sha512-7T8JiUTtDfppojosORAflABfLsLKMLkBHSWkjNQrjIltGoDzNGn7wEPOSfjqYAGTYME65esQzMJxGDjuLBKdOg==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.3.1.tgz", + "integrity": "sha512-lMJTbgNcDm5z+6KDxWtqOFWlGQxD6XaYwBqHR8kmpkP+WWWG90I35kdtQHY67Ay5CSuydkTBbJG+tH9JShFCyA==", "dev": true, "requires": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.0.3", + "@jest/types": "^29.3.1", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.0.3", + "pretty-format": "^29.3.1", "slash": "^3.0.0", "stack-utils": "^2.0.3" } }, "jest-mock": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.0.3.tgz", - "integrity": "sha512-ort9pYowltbcrCVR43wdlqfAiFJXBx8l4uJDsD8U72LgBcetvEp+Qxj1W9ZYgMRoeAo+ov5cnAGF2B6+Oth+ww==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.3.1.tgz", + "integrity": "sha512-H8/qFDtDVMFvFP4X8NuOT3XRDzOUTz+FeACjufHzsOIBAxivLqkB1PoLCaJx9iPPQ8dZThHPp/G3WRWyMgA3JA==", "dev": true, "requires": { - "@jest/types": "^29.0.3", - "@types/node": "*" + "@jest/types": "^29.3.1", + "@types/node": "*", + "jest-util": "^29.3.1" } }, "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==", + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.3.tgz", + "integrity": "sha512-+3NpwQEnRoIBtx4fyhblQDPgJI0H1IEIkX7ShLUjPGA7TtUTvI1oiKi3SR4oBR0hQhQR80l4WAe5RrXBwWMA8w==", "dev": true, "requires": {} }, "jest-regex-util": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.0.0.tgz", - "integrity": "sha512-BV7VW7Sy0fInHWN93MMPtlClweYv2qrSCwfeFWmpribGZtQPWNvRSq9XOVgOEjU1iBGRKXUZil0o2AH7Iy9Lug==", + "version": "29.2.0", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.2.0.tgz", + "integrity": "sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA==", "dev": true }, "jest-resolve": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.0.3.tgz", - "integrity": "sha512-toVkia85Y/BPAjJasTC9zIPY6MmVXQPtrCk8SmiheC4MwVFE/CMFlOtMN6jrwPMC6TtNh8+sTMllasFeu1wMPg==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.3.1.tgz", + "integrity": "sha512-amXJgH/Ng712w3Uz5gqzFBBjxV8WFLSmNjoreBGMqxgCz5cH7swmBZzgBaCIOsvb0NbpJ0vgaSFdJqMdT+rADw==", "dev": true, "requires": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.3", + "jest-haste-map": "^29.3.1", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.0.3", - "jest-validate": "^29.0.3", + "jest-util": "^29.3.1", + "jest-validate": "^29.3.1", "resolve": "^1.20.0", "resolve.exports": "^1.1.0", "slash": "^3.0.0" } }, "jest-resolve-dependencies": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.0.3.tgz", - "integrity": "sha512-KzuBnXqNvbuCdoJpv8EanbIGObk7vUBNt/PwQPPx2aMhlv/jaXpUJsqWYRpP/0a50faMBY7WFFP8S3/CCzwfDw==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.3.1.tgz", + "integrity": "sha512-Vk0cYq0byRw2WluNmNWGqPeRnZ3p3hHmjJMp2dyyZeYIfiBskwq4rpiuGFR6QGAdbj58WC7HN4hQHjf2mpvrLA==", "dev": true, "requires": { - "jest-regex-util": "^29.0.0", - "jest-snapshot": "^29.0.3" + "jest-regex-util": "^29.2.0", + "jest-snapshot": "^29.3.1" } }, "jest-runner": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.0.3.tgz", - "integrity": "sha512-Usu6VlTOZlCZoNuh3b2Tv/yzDpKqtiNAetG9t3kJuHfUyVMNW7ipCCJOUojzKkjPoaN7Bl1f7Buu6PE0sGpQxw==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.3.1.tgz", + "integrity": "sha512-oFvcwRNrKMtE6u9+AQPMATxFcTySyKfLhvso7Sdk/rNpbhg4g2GAGCopiInk1OP4q6gz3n6MajW4+fnHWlU3bA==", "dev": true, "requires": { - "@jest/console": "^29.0.3", - "@jest/environment": "^29.0.3", - "@jest/test-result": "^29.0.3", - "@jest/transform": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/console": "^29.3.1", + "@jest/environment": "^29.3.1", + "@jest/test-result": "^29.3.1", + "@jest/transform": "^29.3.1", + "@jest/types": "^29.3.1", "@types/node": "*", "chalk": "^4.0.0", - "emittery": "^0.10.2", + "emittery": "^0.13.1", "graceful-fs": "^4.2.9", - "jest-docblock": "^29.0.0", - "jest-environment-node": "^29.0.3", - "jest-haste-map": "^29.0.3", - "jest-leak-detector": "^29.0.3", - "jest-message-util": "^29.0.3", - "jest-resolve": "^29.0.3", - "jest-runtime": "^29.0.3", - "jest-util": "^29.0.3", - "jest-watcher": "^29.0.3", - "jest-worker": "^29.0.3", + "jest-docblock": "^29.2.0", + "jest-environment-node": "^29.3.1", + "jest-haste-map": "^29.3.1", + "jest-leak-detector": "^29.3.1", + "jest-message-util": "^29.3.1", + "jest-resolve": "^29.3.1", + "jest-runtime": "^29.3.1", + "jest-util": "^29.3.1", + "jest-watcher": "^29.3.1", + "jest-worker": "^29.3.1", "p-limit": "^3.1.0", "source-map-support": "0.5.13" } }, "jest-runtime": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.0.3.tgz", - "integrity": "sha512-12gZXRQ7ozEeEHKTY45a+YLqzNDR/x4c//X6AqwKwKJPpWM8FY4vwn4VQJOcLRS3Nd1fWwgP7LU4SoynhuUMHQ==", - "dev": true, - "requires": { - "@jest/environment": "^29.0.3", - "@jest/fake-timers": "^29.0.3", - "@jest/globals": "^29.0.3", - "@jest/source-map": "^29.0.0", - "@jest/test-result": "^29.0.3", - "@jest/transform": "^29.0.3", - "@jest/types": "^29.0.3", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.3.1.tgz", + "integrity": "sha512-jLzkIxIqXwBEOZx7wx9OO9sxoZmgT2NhmQKzHQm1xwR1kNW/dn0OjxR424VwHHf1SPN6Qwlb5pp1oGCeFTQ62A==", + "dev": true, + "requires": { + "@jest/environment": "^29.3.1", + "@jest/fake-timers": "^29.3.1", + "@jest/globals": "^29.3.1", + "@jest/source-map": "^29.2.0", + "@jest/test-result": "^29.3.1", + "@jest/transform": "^29.3.1", + "@jest/types": "^29.3.1", "@types/node": "*", "chalk": "^4.0.0", "cjs-module-lexer": "^1.0.0", "collect-v8-coverage": "^1.0.0", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.0.3", - "jest-message-util": "^29.0.3", - "jest-mock": "^29.0.3", - "jest-regex-util": "^29.0.0", - "jest-resolve": "^29.0.3", - "jest-snapshot": "^29.0.3", - "jest-util": "^29.0.3", + "jest-haste-map": "^29.3.1", + "jest-message-util": "^29.3.1", + "jest-mock": "^29.3.1", + "jest-regex-util": "^29.2.0", + "jest-resolve": "^29.3.1", + "jest-snapshot": "^29.3.1", + "jest-util": "^29.3.1", "slash": "^3.0.0", "strip-bom": "^4.0.0" } }, "jest-snapshot": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.0.3.tgz", - "integrity": "sha512-52q6JChm04U3deq+mkQ7R/7uy7YyfVIrebMi6ZkBoDJ85yEjm/sJwdr1P0LOIEHmpyLlXrxy3QP0Zf5J2kj0ew==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.3.1.tgz", + "integrity": "sha512-+3JOc+s28upYLI2OJM4PWRGK9AgpsMs/ekNryUV0yMBClT9B1DF2u2qay8YxcQd338PPYSFNb0lsar1B49sLDA==", "dev": true, "requires": { "@babel/core": "^7.11.6", @@ -12462,44 +11978,59 @@ "@babel/plugin-syntax-typescript": "^7.7.2", "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.0.3", - "@jest/transform": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/expect-utils": "^29.3.1", + "@jest/transform": "^29.3.1", + "@jest/types": "^29.3.1", "@types/babel__traverse": "^7.0.6", "@types/prettier": "^2.1.5", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.0.3", + "expect": "^29.3.1", "graceful-fs": "^4.2.9", - "jest-diff": "^29.0.3", - "jest-get-type": "^29.0.0", - "jest-haste-map": "^29.0.3", - "jest-matcher-utils": "^29.0.3", - "jest-message-util": "^29.0.3", - "jest-util": "^29.0.3", + "jest-diff": "^29.3.1", + "jest-get-type": "^29.2.0", + "jest-haste-map": "^29.3.1", + "jest-matcher-utils": "^29.3.1", + "jest-message-util": "^29.3.1", + "jest-util": "^29.3.1", "natural-compare": "^1.4.0", - "pretty-format": "^29.0.3", + "pretty-format": "^29.3.1", "semver": "^7.3.5" }, "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, "jest-util": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.0.3.tgz", - "integrity": "sha512-Q0xaG3YRG8QiTC4R6fHjHQPaPpz9pJBEi0AeOE4mQh/FuWOijFjGXMMOfQEaU9i3z76cNR7FobZZUQnL6IyfdQ==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.3.1.tgz", + "integrity": "sha512-7YOVZaiX7RJLv76ZfHt4nbNEzzTRiMW/IiOG7ZOKmTXmoGBxUDefgMAxQubu6WPVqP5zSzAdZG0FfLcC7HOIFQ==", "dev": true, "requires": { - "@jest/types": "^29.0.3", + "@jest/types": "^29.3.1", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -12508,17 +12039,17 @@ } }, "jest-validate": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.0.3.tgz", - "integrity": "sha512-OebiqqT6lK8cbMPtrSoS3aZP4juID762lZvpf1u+smZnwTEBCBInan0GAIIhv36MxGaJvmq5uJm7dl5gVt+Zrw==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.3.1.tgz", + "integrity": "sha512-N9Lr3oYR2Mpzuelp1F8negJR3YE+L1ebk1rYA5qYo9TTY3f9OWdptLoNSPP9itOCBIRBqjt/S5XHlzYglLN67g==", "dev": true, "requires": { - "@jest/types": "^29.0.3", + "@jest/types": "^29.3.1", "camelcase": "^6.2.0", "chalk": "^4.0.0", - "jest-get-type": "^29.0.0", + "jest-get-type": "^29.2.0", "leven": "^3.1.0", - "pretty-format": "^29.0.3" + "pretty-format": "^29.3.1" }, "dependencies": { "camelcase": { @@ -12530,28 +12061,29 @@ } }, "jest-watcher": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.0.3.tgz", - "integrity": "sha512-tQX9lU91A+9tyUQKUMp0Ns8xAcdhC9fo73eqA3LFxP2bSgiF49TNcc+vf3qgGYYK9qRjFpXW9+4RgF/mbxyOOw==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.3.1.tgz", + "integrity": "sha512-RspXG2BQFDsZSRKGCT/NiNa8RkQ1iKAjrO0//soTMWx/QUt+OcxMqMSBxz23PYGqUuWm2+m2mNNsmj0eIoOaFg==", "dev": true, "requires": { - "@jest/test-result": "^29.0.3", - "@jest/types": "^29.0.3", + "@jest/test-result": "^29.3.1", + "@jest/types": "^29.3.1", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", - "emittery": "^0.10.2", - "jest-util": "^29.0.3", + "emittery": "^0.13.1", + "jest-util": "^29.3.1", "string-length": "^4.0.1" } }, "jest-worker": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.0.3.tgz", - "integrity": "sha512-Tl/YWUugQOjoTYwjKdfJWkSOfhufJHO5LhXTSZC3TRoQKO+fuXnZAdoXXBlpLXKGODBL3OvdUasfDD4PcMe6ng==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.3.1.tgz", + "integrity": "sha512-lY4AnnmsEWeiXirAIA0c9SDPbuCBq8IYuDVL8PMm0MZ2PEs2yPvRA/J64QBXuZp7CYKrDM/rmNrc9/i3KJQncw==", "dev": true, "requires": { "@types/node": "*", + "jest-util": "^29.3.1", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, @@ -12568,9 +12100,19 @@ } }, "js-sdsl": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", - "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==" + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", + "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==" + }, + "js-sha256": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/js-sha256/-/js-sha256-0.9.0.tgz", + "integrity": "sha512-sga3MHh9sgQN2+pJ9VYZ+1LPwXOxuBJBA5nrR5/ofPfuiJBE2hnjsaN8se8JznOmGLN2p49Pe5U/ttafcs/apA==" + }, + "js-sha512": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/js-sha512/-/js-sha512-0.8.0.tgz", + "integrity": "sha512-PWsmefG6Jkodqt+ePTvBZCSMFgN7Clckjd0O7su3I0+BW2QWUTJNzjktHsztGLhncP2h8mcF9V9Y2Ha59pAViQ==" }, "js-tokens": { "version": "4.0.0", @@ -12593,18 +12135,18 @@ "dev": true }, "jsdom": { - "version": "20.0.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.0.tgz", - "integrity": "sha512-x4a6CKCgx00uCmP+QakBDFXwjAJ69IkkIWHmtmjd3wvXPcdOS44hfX2vqkOQrVrq8l9DhNNADZRXaCEWvgXtVA==", + "version": "20.0.3", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.3.tgz", + "integrity": "sha512-SYhBvTh89tTfCD/CRdSOm13mOBa42iTaTyfyEWBdKcGdPxPtLFBXuHR8XHb33YNYaP+lLbmSvBTsnoesCNJEsQ==", "dev": true, "requires": { "abab": "^2.0.6", - "acorn": "^8.7.1", - "acorn-globals": "^6.0.0", + "acorn": "^8.8.1", + "acorn-globals": "^7.0.0", "cssom": "^0.5.0", "cssstyle": "^2.3.0", "data-urls": "^3.0.2", - "decimal.js": "^10.3.1", + "decimal.js": "^10.4.2", "domexception": "^4.0.0", "escodegen": "^2.0.0", "form-data": "^4.0.0", @@ -12612,18 +12154,17 @@ "http-proxy-agent": "^5.0.0", "https-proxy-agent": "^5.0.1", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "^7.0.0", + "nwsapi": "^2.2.2", + "parse5": "^7.1.1", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^3.0.0", + "tough-cookie": "^4.1.2", + "w3c-xmlserializer": "^4.0.0", "webidl-conversions": "^7.0.0", "whatwg-encoding": "^2.0.0", "whatwg-mimetype": "^3.0.0", "whatwg-url": "^11.0.0", - "ws": "^8.8.0", + "ws": "^8.11.0", "xml-name-validator": "^4.0.0" } }, @@ -12634,9 +12175,9 @@ "dev": true }, "json-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.0.tgz", - "integrity": "sha512-CuUqjv0FUZIdXkHPI8MezCnFCdaTAacej1TZYulLoAg1h/PhwkdXFN4V/gzY4g+fMBCOV2xF+rp7t2XD2ns/NQ==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", "optional": true }, "json-parse-even-better-errors": { @@ -12662,9 +12203,9 @@ "optional": true }, "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.2.tgz", + "integrity": "sha512-46Tk9JiOL2z7ytNQWFLpj99RZkVgeHf87yGQKsIkaPz1qSH9UczKH1rO7K3wgRselo0tYMUNfecYpm/p1vC7tQ==", "dev": true }, "jsonfile": { @@ -12683,12 +12224,12 @@ "dev": true }, "keyv": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz", - "integrity": "sha512-9ykJ/46SN/9KPM/sichzQ7OvXyGDYKGTaDlKMGCAlg2UK8KRy4jb0d8sFc+0Tt0YYnThq8X2RZgCg74RPxgcVA==", + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", + "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", "optional": true, "requires": { - "json-buffer": "3.0.0" + "json-buffer": "3.0.1" } }, "kind-of": { @@ -12704,9 +12245,9 @@ "dev": true }, "known-css-properties": { - "version": "0.25.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.25.0.tgz", - "integrity": "sha512-b0/9J1O9Jcyik1GC6KC42hJ41jKwdO/Mq8Mdo5sYN+IuRTXs2YFHZC3kZSx6ueusqa95x3wLYe/ytKjbAfGixA==", + "version": "0.26.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.26.0.tgz", + "integrity": "sha512-5FZRzrZzNTBruuurWpvZnvP9pum+fe0HcK8z/ooo+U+Hmp4vtbyp1/QDsqmufirXy4egGzbaH/y2uCZf+6W5Kg==", "dev": true }, "leven": { @@ -12743,12 +12284,6 @@ "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, - "lodash.flattendeep": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", - "integrity": "sha512-uHaJFihxmJcEX3kT4I23ABqKKalJ/zDrDg0lsFtc1h+3uw49SIJ5beyhx5ExVRti3AvKoOJngIj7xz3oylPdWQ==", - "dev": true - }, "lodash.get": { "version": "4.4.2", "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", @@ -12767,18 +12302,18 @@ "dev": true }, "lowercase-keys": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-1.0.1.tgz", - "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", "optional": true }, "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "devOptional": true, + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, "requires": { - "yallist": "^4.0.0" + "yallist": "^3.0.2" } }, "luxon": { @@ -12882,7 +12417,8 @@ "merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==" + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true }, "methods": { "version": "1.1.2", @@ -12893,6 +12429,7 @@ "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, "requires": { "braces": "^3.0.2", "picomatch": "^2.3.1" @@ -12942,12 +12479,6 @@ "brace-expansion": "^1.1.7" } }, - "minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "optional": true - }, "minimist-options": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-4.1.0.tgz", @@ -12967,15 +12498,6 @@ } } }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "optional": true, - "requires": { - "minimist": "^1.2.6" - } - }, "module-alias": { "version": "2.2.2", "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz", @@ -12987,9 +12509,9 @@ "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==" }, "moment-timezone": { - "version": "0.5.37", - "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.37.tgz", - "integrity": "sha512-uEDzDNFhfaywRl+vwXxffjjq1q0Vzr+fcQpQ1bU0kbzorfS7zVtZnCnGc8mhWmF39d4g4YriF6kwA75mJKE/Zg==", + "version": "0.5.40", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.40.tgz", + "integrity": "sha512-tWfmNkRYmBkPJz5mr9GVDn9vRlVZOTe6yqY92rFxiOdWXbjaR0+9LwQnZGGuNR63X456NqmEkbskte8tWL5ePg==", "requires": { "moment": ">= 2.9.0" } @@ -13035,23 +12557,35 @@ "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==" }, "nise": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.1.tgz", - "integrity": "sha512-yr5kW2THW1AkxVmCnKEh4nbYkJdB3I7LUkiUgOvEkOp414mc2UMaHMA7pjq1nYowhdoJZGwEKGaQVbxfpWj10A==", + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.4.tgz", + "integrity": "sha512-8+Ib8rRJ4L0o3kfmyVCL7gzrohyDe0cMFTBa2d364yIrEGMEoetznKJx899YxjybU6bL9SQkYPSBBs1gyYs8Xg==", "dev": true, "requires": { - "@sinonjs/commons": "^1.8.3", - "@sinonjs/fake-timers": ">=5", + "@sinonjs/commons": "^2.0.0", + "@sinonjs/fake-timers": "^10.0.2", "@sinonjs/text-encoding": "^0.7.1", "just-extend": "^4.0.2", "path-to-regexp": "^1.7.0" }, "dependencies": { - "isarray": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", - "integrity": "sha512-D2S+3GLxWH+uhrNEcoh/fnmYeP8E8/zHl644d/jdA0g2uyXvy3sb0qxotE+ne0LtccHknQzWwZEzhak7oJ0COQ==", - "dev": true + "@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", + "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^2.0.0" + } }, "path-to-regexp": { "version": "1.8.0", @@ -13094,14 +12628,14 @@ } }, "node-ical": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/node-ical/-/node-ical-0.15.1.tgz", - "integrity": "sha512-+MWL5mdYINFc5+Z5HDGJbQAK3QcpqEV8wok61Kb1VzIV16iTA/9vhIRrLcW+Iht5bm9wI7XalEssMohLeTwPgA==", + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/node-ical/-/node-ical-0.15.3.tgz", + "integrity": "sha512-OQ3xipexD/nI0jpoz+ELhMwV8liMMqM+rlxB5xHbPiJRYvueIT+4cipjdt4L64teXXHVmg+xf8OfwJE2LueVlw==", "requires": { - "axios": "^0.26.1", + "axios": "1.1.3", "moment-timezone": "^0.5.31", "rrule": "2.6.4", - "uuid": "^8.3.1" + "uuid": "^9.0.0" } }, "node-int64": { @@ -13110,19 +12644,10 @@ "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true }, - "node-preload": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", - "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", - "dev": true, - "requires": { - "process-on-spawn": "^1.0.0" - } - }, "node-releases": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.6.tgz", - "integrity": "sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==", + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", + "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==", "dev": true }, "normalize-package-data": { @@ -13137,14 +12662,29 @@ "validate-npm-package-license": "^3.0.1" }, "dependencies": { + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", "dev": true, "requires": { "lru-cache": "^6.0.0" } + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true } } }, @@ -13155,21 +12695,11 @@ "dev": true }, "normalize-url": { - "version": "4.5.1", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-4.5.1.tgz", - "integrity": "sha512-9UZCFRHQdNrfTpGg8+1INIg93B6zE0aXMVFkw1WFwvO4SlZywU6aLg5Of0Ap/PgcbSw4LNxvMWXMeugwMCX0AA==", + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", "optional": true }, - "npm-conf": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/npm-conf/-/npm-conf-1.1.3.tgz", - "integrity": "sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw==", - "optional": true, - "requires": { - "config-chain": "^1.1.11", - "pify": "^3.0.0" - } - }, "npm-run-path": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", @@ -13185,155 +12715,6 @@ "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==", "dev": true }, - "nyc": { - "version": "15.1.0", - "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", - "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", - "dev": true, - "requires": { - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "caching-transform": "^4.0.0", - "convert-source-map": "^1.7.0", - "decamelize": "^1.2.0", - "find-cache-dir": "^3.2.0", - "find-up": "^4.1.0", - "foreground-child": "^2.0.0", - "get-package-type": "^0.1.0", - "glob": "^7.1.6", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-hook": "^3.0.0", - "istanbul-lib-instrument": "^4.0.0", - "istanbul-lib-processinfo": "^2.0.2", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.0.2", - "make-dir": "^3.0.0", - "node-preload": "^0.2.1", - "p-map": "^3.0.0", - "process-on-spawn": "^1.0.0", - "resolve-from": "^5.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "spawn-wrap": "^2.0.0", - "test-exclude": "^6.0.0", - "yargs": "^15.0.2" - }, - "dependencies": { - "cliui": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-6.0.0.tgz", - "integrity": "sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^6.2.0" - } - }, - "find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "requires": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - } - }, - "istanbul-lib-instrument": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.3.tgz", - "integrity": "sha512-BXgQl9kf4WTCPCCpmFGoJkz/+uhvm7h7PFKUYxh7qarQd3ER33vHG//qaE8eN25l07YqZPpHXU9I09l/RD5aGQ==", - "dev": true, - "requires": { - "@babel/core": "^7.7.5", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.0.0", - "semver": "^6.3.0" - } - }, - "locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "requires": { - "p-locate": "^4.1.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "requires": { - "p-limit": "^2.2.0" - } - }, - "resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true - }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "y18n": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.3.tgz", - "integrity": "sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==", - "dev": true - }, - "yargs": { - "version": "15.4.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", - "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", - "dev": true, - "requires": { - "cliui": "^6.0.0", - "decamelize": "^1.2.0", - "find-up": "^4.1.0", - "get-caller-file": "^2.0.1", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^4.2.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^18.1.2" - } - }, - "yargs-parser": { - "version": "18.1.3", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", - "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, "object-assign": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", @@ -13389,9 +12770,9 @@ } }, "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", "optional": true }, "p-limit": { @@ -13410,33 +12791,12 @@ "p-limit": "^3.0.2" } }, - "p-map": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", - "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, "p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", "dev": true }, - "package-hash": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", - "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.15", - "hasha": "^5.0.0", - "lodash.flattendeep": "^4.4.0", - "release-zalgo": "^1.0.0" - } - }, "parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -13458,9 +12818,9 @@ } }, "parse5": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.1.tgz", - "integrity": "sha512-kwpuwzB+px5WUg9pyK0IcK/shltJN5/OVhQagxhCQNtT9Y9QRZqNY2e1cmbu/paRh5LMnz/oVTVLBpjFmMZhSg==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", "dev": true, "requires": { "entities": "^4.4.0" @@ -13500,7 +12860,8 @@ "path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true }, "pend": { "version": "1.2.0", @@ -13517,13 +12878,8 @@ "picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "optional": true + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true }, "pirates": { "version": "4.0.5", @@ -13580,24 +12936,24 @@ } }, "playwright": { - "version": "1.26.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.26.1.tgz", - "integrity": "sha512-WQmEdCgYYe8jOEkhkW9QLcK0PB+w1RZztBLYIT10MEEsENYg251cU0IzebDINreQsUt+HCwwRhtdz4weH9ICcQ==", + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.29.1.tgz", + "integrity": "sha512-lasC+pMqsQ2uWhNurt3YK3xo0gWlMjslYUylKbHcqF/NTjwp9KStRGO7S6wwz2f52GcSnop8XUK/GymJjdzrxw==", "dev": true, "requires": { - "playwright-core": "1.26.1" + "playwright-core": "1.29.1" } }, "playwright-core": { - "version": "1.26.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.26.1.tgz", - "integrity": "sha512-hzFchhhxnEiPc4qVPs9q2ZR+5eKNifY2hQDHtg1HnTTUuphYCBP8ZRb2si+B1TR7BHirgXaPi48LIye5SgrLAA==", + "version": "1.29.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.29.1.tgz", + "integrity": "sha512-20Ai3d+lMkWpI9YZYlxk8gxatfgax5STW8GaMozAHwigLiyiKQrdkt7gaoT9UQR8FIVDg6qVXs9IoZUQrDjIIg==", "dev": true }, "postcss": { - "version": "8.4.16", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz", - "integrity": "sha512-ipHE1XBvKzm5xI7hiHCZJCSugxvsdq2mPnsq5+UF+VHCjiBvtDrlxJfMBToWaP9D5XlgNmcFGqoHmUn0EYEaRQ==", + "version": "8.4.20", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz", + "integrity": "sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==", "dev": true, "requires": { "nanoid": "^3.3.4", @@ -13625,9 +12981,9 @@ "requires": {} }, "postcss-selector-parser": { - "version": "6.0.10", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.10.tgz", - "integrity": "sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==", + "version": "6.0.11", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.11.tgz", + "integrity": "sha512-zbARubNdogI9j7WY4nQJBiNqQf3sLS3wCP4WfOidu+p28LofJqDH1tcXypGrcmMHhDk2t9wGhCsYe/+szLTy1g==", "dev": true, "requires": { "cssesc": "^3.0.0", @@ -13645,16 +13001,10 @@ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==" }, - "prepend-http": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/prepend-http/-/prepend-http-2.0.0.tgz", - "integrity": "sha512-ravE6m9Atw9Z/jjttRUZ+clIXogdghyZAuWJ3qEzjT+jI/dL1ifAqhZeC5VHzQp1MSt1+jxKkFNemj/iO7tVUA==", - "optional": true - }, "prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==", + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.8.1.tgz", + "integrity": "sha512-lqGoSJBQNJidqCHE80vqZJHWHRFoNYsSpP9AjFhlhi9ODCJA541svILes/+/1GM3VaL/abZi7cpFzOpdR9UPKg==", "dev": true }, "prettier-linter-helpers": { @@ -13667,9 +13017,9 @@ } }, "pretty-format": { - "version": "29.0.3", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.0.3.tgz", - "integrity": "sha512-cHudsvQr1K5vNVLbvYF/nv3Qy/F/BcEKxGuIeMiVMRHxPOO1RxXooP8g/ZrwAp7Dx+KdMZoOc7NxLHhMrP2f9Q==", + "version": "29.3.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.3.1.tgz", + "integrity": "sha512-FyLnmb1cYJV8biEIiRyzRFvs2lry7PPIvOqKVe1GCUEYg4YGmlx1qG9EJNMxArYm7piII4qb8UV1Pncq5dxmcg==", "dev": true, "requires": { "@jest/schemas": "^29.0.0", @@ -13736,15 +13086,6 @@ "path-exists": "^4.0.0" } }, - "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" - } - }, "human-signals": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-1.1.1.tgz", @@ -13780,21 +13121,6 @@ } } }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "optional": true - }, - "process-on-spawn": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", - "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", - "dev": true, - "requires": { - "fromentries": "^1.2.0" - } - }, "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -13811,12 +13137,6 @@ "sisteransi": "^1.0.5" } }, - "proto-list": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz", - "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==", - "optional": true - }, "proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -13826,6 +13146,11 @@ "ipaddr.js": "1.9.1" } }, + "proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -13848,9 +13173,9 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", "requires": { "side-channel": "^1.0.4" } @@ -13867,10 +13192,10 @@ "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==" }, "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 + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "optional": true }, "range_check": { "version": "2.0.4", @@ -14013,29 +13338,6 @@ } } }, - "readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "optional": true - } - } - }, "redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -14051,15 +13353,6 @@ "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==" }, - "release-zalgo": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", - "integrity": "sha512-gUAyHVHPPC5wdqX/LG4LWtRYtgjxyX78oanFNTMMyFEfOqdC54s3eE82imuWKbOeqYht2CrNf64Qb8vgmmtZGA==", - "dev": true, - "requires": { - "es6-error": "^4.0.1" - } - }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -14072,12 +13365,6 @@ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, "requires-port": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", @@ -14095,6 +13382,12 @@ "supports-preserve-symlinks-flag": "^1.0.0" } }, + "resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "optional": true + }, "resolve-cwd": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", @@ -14124,12 +13417,12 @@ "dev": true }, "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", "optional": true, "requires": { - "lowercase-keys": "^1.0.0" + "lowercase-keys": "^2.0.0" } }, "reusify": { @@ -14282,12 +13575,6 @@ "send": "0.18.0" } }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==", - "dev": true - }, "setprototypeof": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", @@ -14323,17 +13610,37 @@ "dev": true }, "sinon": { - "version": "14.0.0", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-14.0.0.tgz", - "integrity": "sha512-ugA6BFmE+WrJdh0owRZHToLd32Uw3Lxq6E6LtNRU+xTVBefx632h03Q7apXWRsRdZAJ41LB8aUfn2+O4jsDNMw==", + "version": "15.0.1", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-15.0.1.tgz", + "integrity": "sha512-PZXKc08f/wcA/BMRGBze2Wmw50CWPiAH3E21EOi4B49vJ616vW4DQh4fQrqsYox2aNR/N3kCqLuB0PwwOucQrg==", "dev": true, "requires": { - "@sinonjs/commons": "^1.8.3", - "@sinonjs/fake-timers": "^9.1.2", - "@sinonjs/samsam": "^6.1.1", + "@sinonjs/commons": "^2.0.0", + "@sinonjs/fake-timers": "10.0.2", + "@sinonjs/samsam": "^7.0.1", "diff": "^5.0.0", - "nise": "^5.1.1", + "nise": "^5.1.2", "supports-color": "^7.2.0" + }, + "dependencies": { + "@sinonjs/commons": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", + "integrity": "sha512-uLa0j859mMrg2slwQYdO/AkrOfmH+X6LTVmNTS9CqexuE2IvVORIkSpJLqePAbEnKJ77aMmCwr1NUZ57120Xcg==", + "dev": true, + "requires": { + "type-detect": "4.0.8" + } + }, + "@sinonjs/fake-timers": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.0.2.tgz", + "integrity": "sha512-SwUDyjWnah1AaNl7kxsa7cfLhlTYoiyhDAIgyh+El30YvXs/o7OLXpYH88Zdhyx9JExKrmHDJ+10bwIcY80Jmw==", + "dev": true, + "requires": { + "@sinonjs/commons": "^2.0.0" + } + } } }, "sisteransi": { @@ -14345,7 +13652,8 @@ "slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==" + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true }, "slice-ansi": { "version": "4.0.0", @@ -14359,16 +13667,16 @@ } }, "socket.io": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.2.tgz", - "integrity": "sha512-6fCnk4ARMPZN448+SQcnn1u8OHUC72puJcNtSgg2xS34Cu7br1gQ09YKkO1PFfDn/wyUE9ZgMAwosJed003+NQ==", + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.4.tgz", + "integrity": "sha512-m3GC94iK9MfIEeIBfbhJs5BqFibMtkRk8ZpKwG2QwxV0m/eEhPIV4ara6XCF1LWNAus7z58RodiZlAH71U3EhQ==", "requires": { "accepts": "~1.3.4", "base64id": "~2.0.0", "debug": "~4.3.2", - "engine.io": "~6.2.0", + "engine.io": "~6.2.1", "socket.io-adapter": "~2.4.0", - "socket.io-parser": "~4.2.0" + "socket.io-parser": "~4.2.1" } }, "socket.io-adapter": { @@ -14407,20 +13715,6 @@ "source-map": "^0.6.0" } }, - "spawn-wrap": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", - "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", - "dev": true, - "requires": { - "foreground-child": "^2.0.0", - "is-windows": "^1.0.2", - "make-dir": "^3.0.0", - "rimraf": "^3.0.0", - "signal-exit": "^3.0.2", - "which": "^2.0.1" - } - }, "spdx-correct": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", @@ -14460,9 +13754,9 @@ "optional": true }, "stack-utils": { - "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==", + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, "requires": { "escape-string-regexp": "^2.0.0" @@ -14481,23 +13775,6 @@ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==" }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - }, - "dependencies": { - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "optional": true - } - } - }, "string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -14560,15 +13837,15 @@ "dev": true }, "stylelint": { - "version": "14.12.1", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.12.1.tgz", - "integrity": "sha512-ZEM4TuksChMBfuPadQsHUkbOoRySAT9QMfDvvYxdAchOJl0p+csTMBXOu6ORAAxKhwBmxqJiep8V88bXfNs3EQ==", + "version": "14.16.0", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.16.0.tgz", + "integrity": "sha512-X6uTi9DcxjzLV8ZUAjit1vsRtSwcls0nl07c9rqOPzvpA8IvTX/xWEkBRowS0ffevRrqkHa/ThDEu86u73FQDg==", "dev": true, "requires": { "@csstools/selector-specificity": "^2.0.2", "balanced-match": "^2.0.0", "colord": "^2.9.3", - "cosmiconfig": "^7.0.1", + "cosmiconfig": "^7.1.0", "css-functions-list": "^3.1.0", "debug": "^4.3.4", "fast-glob": "^3.2.12", @@ -14578,21 +13855,21 @@ "globby": "^11.1.0", "globjoin": "^0.1.4", "html-tags": "^3.2.0", - "ignore": "^5.2.0", + "ignore": "^5.2.1", "import-lazy": "^4.0.0", "imurmurhash": "^0.1.4", "is-plain-object": "^5.0.0", - "known-css-properties": "^0.25.0", + "known-css-properties": "^0.26.0", "mathml-tag-names": "^2.1.3", "meow": "^9.0.0", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "picocolors": "^1.0.0", - "postcss": "^8.4.16", + "postcss": "^8.4.19", "postcss-media-query-parser": "^0.2.3", "postcss-resolve-nested-selector": "^0.1.1", "postcss-safe-parser": "^6.0.0", - "postcss-selector-parser": "^6.0.10", + "postcss-selector-parser": "^6.0.11", "postcss-value-parser": "^4.2.0", "resolve-from": "^5.0.0", "string-width": "^4.2.3", @@ -14600,7 +13877,7 @@ "style-search": "^0.1.0", "supports-hyperlinks": "^2.3.0", "svg-tags": "^1.0.0", - "table": "^6.8.0", + "table": "^6.8.1", "v8-compile-cache": "^2.3.0", "write-file-atomic": "^4.0.2" }, @@ -14620,9 +13897,9 @@ } }, "stylelint-config-prettier": { - "version": "9.0.3", - "resolved": "https://registry.npmjs.org/stylelint-config-prettier/-/stylelint-config-prettier-9.0.3.tgz", - "integrity": "sha512-5n9gUDp/n5tTMCq1GLqSpA30w2sqWITSSEiAWQlpxkKGAUbjcemQ0nbkRvRUa0B1LgD3+hCvdL7B1eTxy1QHJg==", + "version": "9.0.4", + "resolved": "https://registry.npmjs.org/stylelint-config-prettier/-/stylelint-config-prettier-9.0.4.tgz", + "integrity": "sha512-38nIGTGpFOiK5LjJ8Ma1yUgpKENxoKSOhbDNSemY7Ep0VsJoXIW9Iq/2hSt699oB9tReynfWicTAoIHiq8Rvbg==", "dev": true, "requires": {} }, @@ -14634,9 +13911,9 @@ "requires": {} }, "stylelint-config-standard": { - "version": "28.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-28.0.0.tgz", - "integrity": "sha512-q/StuowDdDmFCravzGHAwgS9pjX0bdOQUEBBDIkIWsQuYGgYz/xsO8CM6eepmIQ1fc5bKdDVimlJZ6MoOUcJ5Q==", + "version": "29.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-29.0.0.tgz", + "integrity": "sha512-uy8tZLbfq6ZrXy4JKu3W+7lYLgRQBxYTUUB88vPgQ+ZzAxdrvcaSUW9hOMNLYBnwH+9Kkj19M2DHdZ4gKwI7tg==", "dev": true, "requires": { "stylelint-config-recommended": "^9.0.0" @@ -14703,9 +13980,9 @@ "dev": true }, "table": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", + "version": "6.8.1", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.1.tgz", + "integrity": "sha512-Y4X9zqrCftUhMeH2EptSSERdVKt/nEdijTOacGD/97EKjhQ/Qs8RTlEGABSJNNN8lac9kheH+af7yAkEWlgneA==", "dev": true, "requires": { "ajv": "^8.0.1", @@ -14716,9 +13993,9 @@ }, "dependencies": { "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "version": "8.11.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.2.tgz", + "integrity": "sha512-E4bfmKAhGiSTvMfL1Myyycaub+cUEU2/IvpylXkUu7CHBkBj1f/ikdzbD7YQ6FKUbixDxeYvB/xY4fvyroDlQg==", "dev": true, "requires": { "fast-deep-equal": "^3.1.1", @@ -14735,16 +14012,6 @@ } } }, - "terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - } - }, "test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", @@ -14773,16 +14040,11 @@ "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", "dev": true }, - "to-readable-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/to-readable-stream/-/to-readable-stream-1.0.0.tgz", - "integrity": "sha512-Iq25XBt6zD5npPhlLVXGFN3/gyR2/qODcKNNyTMd4vbm39HUaOiAM4PMq0eMVC/Tkxz+Zjdsc55g9yyz+Yq00Q==", - "optional": true - }, "to-regex-range": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, "requires": { "is-number": "^7.0.0" } @@ -14841,12 +14103,6 @@ "tslib": "^1.8.1" } }, - "tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", - "optional": true - }, "type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -14875,25 +14131,10 @@ "mime-types": "~2.1.24" } }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==", - "optional": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, "typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "version": "4.9.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", + "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==", "dev": true, "peer": true }, @@ -14909,9 +14150,9 @@ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" }, "update-browserslist-db": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.9.tgz", - "integrity": "sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg==", + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", "dev": true, "requires": { "escalade": "^3.1.1", @@ -14936,20 +14177,11 @@ "requires-port": "^1.0.0" } }, - "url-parse-lax": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/url-parse-lax/-/url-parse-lax-3.0.0.tgz", - "integrity": "sha512-NjFKA0DidqPa5ciFcSrXnAltTtzz84ogy+NebPvfEgAck0+TNg4UJ4IN+fB7zRZfbgUf0syOo9MDxFkDSMuFaQ==", - "optional": true, - "requires": { - "prepend-http": "^2.0.0" - } - }, "util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "devOptional": true + "dev": true }, "utils-merge": { "version": "1.0.1", @@ -14957,9 +14189,9 @@ "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" }, "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==" + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.0.tgz", + "integrity": "sha512-MXcSTerfPa4uqyzStbRoTgt5XIe3x5+42+q1sDuy3R5MDk66URdLMOZe5aPX/SQd+kuYAh0FdP/pO28IkQyTeg==" }, "v8-compile-cache": { "version": "2.3.0", @@ -14976,6 +14208,14 @@ "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", "convert-source-map": "^1.6.0" + }, + "dependencies": { + "convert-source-map": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", + "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==", + "dev": true + } } }, "validate-npm-package-license": { @@ -14993,19 +14233,10 @@ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" }, - "w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dev": true, - "requires": { - "browser-process-hrtime": "^1.0.0" - } - }, "w3c-xmlserializer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-3.0.0.tgz", - "integrity": "sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-4.0.0.tgz", + "integrity": "sha512-d+BFHzbiCx6zGfz0HyQ6Rg69w9k19nviJspaj4yNscGjrHu94sVP+aRm75yEbCh+r2/yR+7q6hux9LVtbuTGBw==", "dev": true, "requires": { "xml-name-validator": "^4.0.0" @@ -15059,12 +14290,6 @@ "isexe": "^2.0.0" } }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==", - "dev": true - }, "word-wrap": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", @@ -15097,9 +14322,9 @@ } }, "ws": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.9.0.tgz", - "integrity": "sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==", + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.11.0.tgz", + "integrity": "sha512-HPG3wQd9sNQoT9xHyNCXoDUa+Xw/VevmY9FoHyQ+g+rrMn4j6FB4np7Z0OhdTgjx6MgQLK7jwSy1YecU1+4Asg==", "dev": true, "requires": {} }, @@ -15122,10 +14347,10 @@ "dev": true }, "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "devOptional": true + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true }, "yaml": { "version": "1.10.2", @@ -15134,18 +14359,18 @@ "dev": true }, "yargs": { - "version": "17.5.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.5.1.tgz", - "integrity": "sha512-t6YAJcxDkNX7NFYiVtKvWUz8l+PaKTLiL63mJYWR2GnHq2gjEWISzsLp9wg3aY36dY1j+gfIEL3pIF+XlJJfbA==", + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", "dev": true, "requires": { - "cliui": "^7.0.2", + "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", - "yargs-parser": "^21.0.0" + "yargs-parser": "^21.1.1" }, "dependencies": { "yargs-parser": { diff --git a/package.json b/package.json index b805bb9f2c..fd7322dc8c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "magicmirror", - "version": "2.21.0", + "version": "2.22.0", "description": "The open source modular smart mirror platform.", "main": "js/electron.js", "scripts": { @@ -13,7 +13,7 @@ "install-fonts": "echo \"Installing fonts ...\n\" && cd fonts && npm install --loglevel=error --no-audit --no-fund --no-update-notifier", "postinstall": "npm run install-vendor && npm run install-fonts && echo \"MagicMirror² installation finished successfully! \n\"", "test": "NODE_ENV=test jest -i --forceExit", - "test:coverage": "NODE_ENV=test nyc --reporter=lcov --reporter=text jest -i --forceExit", + "test:coverage": "NODE_ENV=test jest --coverage -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", @@ -50,44 +50,43 @@ "homepage": "https://magicmirror.builders", "devDependencies": { "eslint-config-prettier": "^8.5.0", - "eslint-plugin-jest": "^27.0.4", - "eslint-plugin-jsdoc": "^39.3.6", + "eslint-plugin-jest": "^27.1.7", + "eslint-plugin-jsdoc": "^39.6.4", "eslint-plugin-prettier": "^4.2.1", "express-basic-auth": "^1.2.1", - "husky": "^8.0.1", - "jest": "^29.0.3", - "jsdom": "^20.0.0", + "husky": "^8.0.2", + "jest": "^29.3.1", + "jsdom": "^20.0.3", "lodash": "^4.17.21", - "nyc": "^15.1.0", - "playwright": "^1.26.1", - "prettier": "^2.7.1", + "playwright": "^1.29.1", + "prettier": "^2.8.1", "pretty-quick": "^3.1.3", - "sinon": "^14.0.0", - "stylelint": "^14.12.1", - "stylelint-config-prettier": "^9.0.3", - "stylelint-config-standard": "^28.0.0", + "sinon": "^15.0.1", + "stylelint": "^14.16.0", + "stylelint-config-prettier": "^9.0.4", + "stylelint-config-standard": "^29.0.0", "stylelint-prettier": "^2.0.0", "suncalc": "^1.9.0" }, "optionalDependencies": { - "electron": "^19.1.0" + "electron": "^22.0.0" }, "dependencies": { "colors": "^1.4.0", - "console-stamp": "^3.0.6", - "digest-fetch": "^1.3.0", - "eslint": "^8.24.0", - "express": "^4.18.1", + "console-stamp": "^3.1.0", + "digest-fetch": "^2.0.1", + "eslint": "^8.30.0", + "express": "^4.18.2", "express-ipfilter": "^1.3.1", "feedme": "^2.0.2", - "helmet": "^6.0.0", + "helmet": "^6.0.1", "iconv-lite": "^0.6.3", "luxon": "^1.28.0", "module-alias": "^2.2.2", "moment": "^2.29.4", "node-fetch": "^2.6.7", - "node-ical": "^0.15.1", - "socket.io": "^4.5.2" + "node-ical": "^0.15.3", + "socket.io": "^4.5.4" }, "_moduleAliases": { "node_helper": "js/node_helper.js", @@ -96,48 +95,5 @@ }, "engines": { "node": ">=14" - }, - "jest": { - "verbose": true, - "testTimeout": 20000, - "testSequencer": "/tests/configs/test_sequencer.js", - "projects": [ - { - "displayName": "unit", - "moduleNameMapper": { - "logger": "/js/logger.js" - }, - "testMatch": [ - "**/tests/unit/**/*.[jt]s?(x)" - ], - "testPathIgnorePatterns": [ - "/tests/unit/mocks" - ] - }, - { - "displayName": "electron", - "testMatch": [ - "**/tests/electron/**/*.[jt]s?(x)" - ] - }, - { - "displayName": "e2e", - "setupFilesAfterEnv": [ - "/tests/e2e/mock-console.js" - ], - "testMatch": [ - "**/tests/e2e/**/*.[jt]s?(x)" - ], - "modulePaths": [ - "/js/" - ], - "testPathIgnorePatterns": [ - "/tests/e2e/modules/mocks", - "/tests/e2e/modules/basic-auth.js", - "/tests/e2e/global-setup.js", - "/tests/e2e/mock-console.js" - ] - } - ] } } diff --git a/tests/configs/data/en.json b/tests/configs/data/en.json deleted file mode 100644 index 8a24a16fb3..0000000000 --- a/tests/configs/data/en.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "LOADING": "Loading …", - - "TODAY": "Today", - "TOMORROW": "Tomorrow", - "DAYAFTERTOMORROW": "In 2 days", - "RUNNING": "Ends in", - "EMPTY": "No upcoming events.", - - "WEEK": "Week {weekNumber}", - - "N": "N", - "NNE": "NNE", - "NE": "NE", - "ENE": "ENE", - "E": "E", - "ESE": "ESE", - "SE": "SE", - "SSE": "SSE", - "S": "S", - "SSW": "SSW", - "SW": "SW", - "WSW": "WSW", - "W": "W", - "WNW": "WNW", - "NW": "NW", - "NNW": "NNW", - - "UPDATE_NOTIFICATION": "MagicMirror² update available.", - "UPDATE_NOTIFICATION_MODULE": "Update available for MODULE_NAME module.", - "UPDATE_INFO_SINGLE": "The current installation is COMMIT_COUNT commit behind on the BRANCH_NAME branch.", - "UPDATE_INFO_MULTIPLE": "The current installation is COMMIT_COUNT commits behind on the BRANCH_NAME branch." -} diff --git a/tests/configs/default.js b/tests/configs/default.js index 7d0f8eed15..509dfd9860 100644 --- a/tests/configs/default.js +++ b/tests/configs/default.js @@ -3,7 +3,7 @@ * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com * MIT Licensed. */ -exports.configFactory = function (options) { +exports.configFactory = (options) => { return Object.assign( { electronOptions: { diff --git a/tests/configs/modules/calendar/auth-default.js b/tests/configs/modules/calendar/auth-default.js index a4ef4ba1e0..0b2491612f 100644 --- a/tests/configs/modules/calendar/auth-default.js +++ b/tests/configs/modules/calendar/auth-default.js @@ -14,7 +14,7 @@ let config = { calendars: [ { maximumNumberOfDays: 10000, - url: "http://localhost:8080/tests/configs/data/calendar_test.ics", + url: "http://localhost:8080/tests/mocks/calendar_test.ics", auth: { user: "MagicMirror", pass: "CallMeADog" diff --git a/tests/configs/modules/calendar/basic-auth.js b/tests/configs/modules/calendar/basic-auth.js index 9290a43b4f..5cbebceb2f 100644 --- a/tests/configs/modules/calendar/basic-auth.js +++ b/tests/configs/modules/calendar/basic-auth.js @@ -14,7 +14,7 @@ let config = { calendars: [ { maximumNumberOfDays: 10000, - url: "http://localhost:8080/tests/configs/data/calendar_test.ics", + url: "http://localhost:8080/tests/mocks/calendar_test.ics", auth: { user: "MagicMirror", pass: "CallMeADog", diff --git a/tests/configs/modules/calendar/changed-port.js b/tests/configs/modules/calendar/changed-port.js index 09aeb5893d..5027726115 100644 --- a/tests/configs/modules/calendar/changed-port.js +++ b/tests/configs/modules/calendar/changed-port.js @@ -14,7 +14,7 @@ let config = { calendars: [ { maximumNumberOfDays: 10000, - url: "http://localhost:8010/tests/configs/data/calendar_test.ics", + url: "http://localhost:8010/tests/mocks/calendar_test.ics", auth: { user: "MagicMirror", pass: "CallMeADog" diff --git a/tests/configs/modules/calendar/custom.js b/tests/configs/modules/calendar/custom.js index 2b396f806e..54d117d7a7 100644 --- a/tests/configs/modules/calendar/custom.js +++ b/tests/configs/modules/calendar/custom.js @@ -18,7 +18,7 @@ let config = { symbol: "birthday-cake", fullDaySymbol: "calendar-day", recurringSymbol: "undo", - url: "http://localhost:8080/tests/configs/data/calendar_test_icons.ics" + url: "http://localhost:8080/tests/mocks/calendar_test_icons.ics" } ] } diff --git a/tests/configs/modules/calendar/default.js b/tests/configs/modules/calendar/default.js index cd50a0ae9b..2dee121203 100644 --- a/tests/configs/modules/calendar/default.js +++ b/tests/configs/modules/calendar/default.js @@ -14,7 +14,7 @@ let config = { calendars: [ { maximumNumberOfDays: 10000, - url: "http://localhost:8080/tests/configs/data/calendar_test.ics" + url: "http://localhost:8080/tests/mocks/calendar_test.ics" } ] } diff --git a/tests/configs/modules/calendar/fail-basic-auth.js b/tests/configs/modules/calendar/fail-basic-auth.js index 39c1792725..e0b3ff15ae 100644 --- a/tests/configs/modules/calendar/fail-basic-auth.js +++ b/tests/configs/modules/calendar/fail-basic-auth.js @@ -16,7 +16,7 @@ let config = { calendars: [ { maximumNumberOfDays: 10000, - url: "http://localhost:8020/tests/configs/data/calendar_test.ics", + url: "http://localhost:8020/tests/mocks/calendar_test.ics", auth: { user: "MagicMirror", pass: "StairwayToHeaven", diff --git a/tests/configs/modules/calendar/old-basic-auth.js b/tests/configs/modules/calendar/old-basic-auth.js index c1fb5590cb..01805e5c8c 100644 --- a/tests/configs/modules/calendar/old-basic-auth.js +++ b/tests/configs/modules/calendar/old-basic-auth.js @@ -14,7 +14,7 @@ let config = { calendars: [ { maximumNumberOfDays: 10000, - url: "http://localhost:8080/tests/configs/data/calendar_test.ics", + url: "http://localhost:8080/tests/mocks/calendar_test.ics", user: "MagicMirror", pass: "CallMeADog" } diff --git a/tests/configs/modules/calendar/recurring.js b/tests/configs/modules/calendar/recurring.js index a513d35d06..d05cce6c9b 100644 --- a/tests/configs/modules/calendar/recurring.js +++ b/tests/configs/modules/calendar/recurring.js @@ -15,7 +15,7 @@ let config = { { maximumEntries: 6, maximumNumberOfDays: 3650, - url: "http://localhost:8080/tests/configs/data/calendar_test_recurring.ics" + url: "http://localhost:8080/tests/mocks/calendar_test_recurring.ics" } ] } diff --git a/tests/configs/modules/compliments/compliments_date.js b/tests/configs/modules/compliments/compliments_date.js index d84a6bde85..2d9018b1d6 100644 --- a/tests/configs/modules/compliments/compliments_date.js +++ b/tests/configs/modules/compliments/compliments_date.js @@ -11,7 +11,6 @@ let config = { module: "compliments", position: "middle_center", config: { - mockDate: "2020-01-01", compliments: { morning: [], afternoon: [], diff --git a/tests/configs/modules/compliments/compliments_remote.js b/tests/configs/modules/compliments/compliments_remote.js new file mode 100644 index 0000000000..4658929682 --- /dev/null +++ b/tests/configs/modules/compliments/compliments_remote.js @@ -0,0 +1,21 @@ +/* MagicMirror² Test config compliments with remote file + * + * By Rejas + * MIT Licensed. + */ +let config = { + modules: [ + { + module: "compliments", + position: "middle_center", + config: { + remoteFile: "http://localhost:8080/tests/mocks/compliments_test.json" + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/newsfeed/default.js b/tests/configs/modules/newsfeed/default.js index 00bf569dac..34a7587fb0 100644 --- a/tests/configs/modules/newsfeed/default.js +++ b/tests/configs/modules/newsfeed/default.js @@ -14,7 +14,7 @@ let config = { feeds: [ { title: "Rodrigo Ramirez Blog", - url: "http://localhost:8080/tests/configs/data/feed_test_rodrigoramirez.xml" + url: "http://localhost:8080/tests/mocks/newsfeed_test.xml" } ] } diff --git a/tests/configs/modules/newsfeed/ignore_items.js b/tests/configs/modules/newsfeed/ignore_items.js index bbcf4db28f..fd104ba414 100644 --- a/tests/configs/modules/newsfeed/ignore_items.js +++ b/tests/configs/modules/newsfeed/ignore_items.js @@ -13,7 +13,7 @@ let config = { feeds: [ { title: "Rodrigo Ramirez Blog", - url: "http://localhost:8080/tests/configs/data/feed_test_rodrigoramirez.xml" + url: "http://localhost:8080/tests/mocks/newsfeed_test.xml" } ], ignoreOldItems: true diff --git a/tests/configs/modules/newsfeed/prohibited_words.js b/tests/configs/modules/newsfeed/prohibited_words.js index 42eb572f26..4ff6aec0fa 100644 --- a/tests/configs/modules/newsfeed/prohibited_words.js +++ b/tests/configs/modules/newsfeed/prohibited_words.js @@ -13,7 +13,7 @@ let config = { feeds: [ { title: "Rodrigo Ramirez Blog", - url: "http://localhost:8080/tests/configs/data/feed_test_rodrigoramirez.xml" + url: "http://localhost:8080/tests/mocks/newsfeed_test.xml" } ], prohibitedWords: ["QPanel"], diff --git a/tests/configs/modules/positions.js b/tests/configs/modules/positions.js index 6086fadd4c..77ad8f72c9 100644 --- a/tests/configs/modules/positions.js +++ b/tests/configs/modules/positions.js @@ -6,7 +6,7 @@ let config = { modules: // Using exotic content. This is why don't accept go to JSON configuration file - (function () { + (() => { let 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"]; let modules = Array(); for (let idx in positions) { diff --git a/tests/configs/modules/weather/currentweather_options.js b/tests/configs/modules/weather/currentweather_options.js index bd433f6435..2dd9216327 100644 --- a/tests/configs/modules/weather/currentweather_options.js +++ b/tests/configs/modules/weather/currentweather_options.js @@ -11,7 +11,7 @@ let config = { config: { location: "Munich", mockData: '"#####WEATHERDATA#####"', - useBeaufort: false, + windUnits: "beaufort", showWindDirectionAsArrow: true, showSun: false, showHumidity: true, diff --git a/tests/e2e/env_spec.js b/tests/e2e/env_spec.js index 06a09d6d5e..a62ab54448 100644 --- a/tests/e2e/env_spec.js +++ b/tests/e2e/env_spec.js @@ -1,34 +1,27 @@ -const fetch = require("fetch"); -const helpers = require("./global-setup"); +const helpers = require("./helpers/global-setup"); describe("App environment", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/default.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/default.js"); + await helpers.getDocument(); }); afterAll(async () => { await helpers.stopApplication(); }); - it("get request from http://localhost:8080 should return 200", (done) => { - fetch("http://localhost:8080").then((res) => { - done(); - expect(res.status).toBe(200); - }); + it("get request from http://localhost:8080 should return 200", async () => { + const res = await helpers.fetch("http://localhost:8080"); + expect(res.status).toBe(200); }); - it("get request from http://localhost:8080/nothing should return 404", (done) => { - fetch("http://localhost:8080/nothing").then((res) => { - done(); - expect(res.status).toBe(404); - }); + it("get request from http://localhost:8080/nothing should return 404", async () => { + const res = await helpers.fetch("http://localhost:8080/nothing"); + expect(res.status).toBe(404); }); - it("should show the title MagicMirror²", (done) => { - helpers.waitForElement("title").then((elem) => { - done(); - expect(elem).not.toBe(null); - expect(elem.textContent).toBe("MagicMirror²"); - }); + it("should show the title MagicMirror²", async () => { + const elem = await helpers.waitForElement("title"); + expect(elem).not.toBe(null); + expect(elem.textContent).toBe("MagicMirror²"); }); }); diff --git a/tests/e2e/fonts.js b/tests/e2e/fonts_spec.js similarity index 67% rename from tests/e2e/fonts.js rename to tests/e2e/fonts_spec.js index 056b0306ea..b0d642d026 100644 --- a/tests/e2e/fonts.js +++ b/tests/e2e/fonts_spec.js @@ -1,7 +1,6 @@ -const fetch = require("fetch"); -const helpers = require("./global-setup"); +const helpers = require("./helpers/global-setup"); -describe("All font files from roboto.css should be downloadable", function () { +describe("All font files from roboto.css should be downloadable", () => { const fontFiles = []; // Statements below filters out all 'url' lines in the CSS file const fileContent = require("fs").readFileSync(__dirname + "/../../fonts/roboto.css", "utf8"); @@ -14,18 +13,16 @@ describe("All font files from roboto.css should be downloadable", function () { match = regex.exec(fileContent); } - beforeAll(function () { - helpers.startApplication("tests/configs/without_modules.js"); + beforeAll(async () => { + await helpers.startApplication("tests/configs/without_modules.js"); }); - afterAll(async function () { + afterAll(async () => { await helpers.stopApplication(); }); - test.each(fontFiles)("should return 200 HTTP code for file '%s'", (fontFile, done) => { + test.each(fontFiles)("should return 200 HTTP code for file '%s'", async (fontFile) => { const fontUrl = "http://localhost:8080/fonts/" + fontFile; - fetch(fontUrl).then((res) => { - expect(res.status).toBe(200); - done(); - }); + const res = await helpers.fetch(fontUrl); + expect(res.status).toBe(200); }); }); diff --git a/tests/e2e/modules/basic-auth.js b/tests/e2e/helpers/basic-auth.js similarity index 72% rename from tests/e2e/modules/basic-auth.js rename to tests/e2e/helpers/basic-auth.js index 9ace932bc0..84917a44f0 100644 --- a/tests/e2e/modules/basic-auth.js +++ b/tests/e2e/helpers/basic-auth.js @@ -11,7 +11,7 @@ const basicAuth = auth({ app.use(basicAuth); // Set available directories -const directories = ["/tests/configs"]; +const directories = ["/tests/configs", "/tests/mocks"]; const rootPath = path.resolve(__dirname + "/../../../"); for (let directory of directories) { @@ -20,10 +20,10 @@ for (let directory of directories) { let server; -exports.listen = function () { - server = app.listen.apply(app, arguments); +exports.listen = (...args) => { + server = app.listen.apply(app, args); }; -exports.close = function (callback) { - server.close(callback); +exports.close = async () => { + await server.close(); }; diff --git a/tests/e2e/global-setup.js b/tests/e2e/helpers/global-setup.js similarity index 55% rename from tests/e2e/global-setup.js rename to tests/e2e/helpers/global-setup.js index 1cd9a2c0b1..582ab3ec81 100644 --- a/tests/e2e/global-setup.js +++ b/tests/e2e/helpers/global-setup.js @@ -1,8 +1,11 @@ const jsdom = require("jsdom"); +const corefetch = require("fetch"); -exports.startApplication = (configFilename, exec) => { +exports.startApplication = async (configFilename, exec) => { jest.resetModules(); - this.stopApplication(); + if (global.app) { + await this.stopApplication(); + } // Set config sample for use in test if (configFilename === "") { process.env.MM_CONFIG_FILE = "config/config.js"; @@ -11,24 +14,33 @@ exports.startApplication = (configFilename, exec) => { } if (exec) exec; global.app = require("app.js"); - global.app.start(); + + return new Promise((resolve) => { + global.app.start(resolve); + }); }; exports.stopApplication = async () => { if (global.app) { - global.app.stop(); + return new Promise((resolve) => { + global.app.stop(resolve); + delete global.app; + }); } - await new Promise((resolve) => setTimeout(resolve, 100)); + return Promise.resolve(); }; -exports.getDocument = (callback) => { - 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 = () => { - global.document = dom.window.document; - callback(); - }; +exports.getDocument = () => { + return new Promise((resolve) => { + const url = "http://" + (config.address || "localhost") + ":" + (config.port || "8080"); + jsdom.JSDOM.fromURL(url, { resources: "usable", runScripts: "dangerously" }).then((dom) => { + dom.window.name = "jsdom"; + dom.window.fetch = corefetch; + dom.window.onload = () => { + global.document = dom.window.document; + resolve(); + }; + }); }); }; @@ -71,3 +83,17 @@ exports.waitForAllElements = (selector) => { }, 100); }); }; + +exports.fetch = (url) => { + return new Promise((resolve) => { + corefetch(url).then((res) => { + resolve(res); + }); + }); +}; + +exports.testMatch = async (element, regex) => { + const elem = await this.waitForElement(element); + expect(elem).not.toBe(null); + expect(elem.textContent).toMatch(regex); +}; diff --git a/tests/e2e/mock-console.js b/tests/e2e/helpers/mock-console.js similarity index 93% rename from tests/e2e/mock-console.js rename to tests/e2e/helpers/mock-console.js index 454a8e4672..3f9909f11a 100644 --- a/tests/e2e/mock-console.js +++ b/tests/e2e/helpers/mock-console.js @@ -3,13 +3,13 @@ * * @param {string} err The error message. */ -function mockError(err) { +const mockError = (err) => { if (err.includes("ECONNREFUSED") || err.includes("ECONNRESET") || err.includes("socket hang up") || err.includes("exports is not defined") || err.includes("write EPIPE")) { jest.fn(); } else { console.dir(err); } -} +}; global.console = { log: jest.fn(), diff --git a/tests/e2e/helpers/weather-functions.js b/tests/e2e/helpers/weather-functions.js new file mode 100644 index 0000000000..5aa71c488a --- /dev/null +++ b/tests/e2e/helpers/weather-functions.js @@ -0,0 +1,29 @@ +const helpers = require("./global-setup"); +const path = require("path"); +const fs = require("fs"); +const { generateWeather, generateWeatherForecast } = require("../../mocks/weather_test"); + +exports.getText = async (element, result) => { + const elem = await helpers.waitForElement(element); + expect(elem).not.toBe(null); + expect( + elem.textContent + .trim() + .replace(/(\r\n|\n|\r)/gm, "") + .replace(/[ ]+/g, " ") + ).toBe(result); +}; + +exports.startApp = async (configFile, additionalMockData) => { + let mockWeather; + if (configFile.includes("forecast")) { + mockWeather = generateWeatherForecast(additionalMockData); + } else { + mockWeather = generateWeather(additionalMockData); + } + let content = fs.readFileSync(path.resolve(__dirname + "../../../../" + configFile)).toString(); + content = content.replace("#####WEATHERDATA#####", mockWeather); + fs.writeFileSync(path.resolve(__dirname + "../../../../config/config.js"), content); + await helpers.startApplication(""); + await helpers.getDocument(); +}; diff --git a/tests/e2e/ipWhitelist_spec.js b/tests/e2e/ipWhitelist_spec.js index 3c3a06c3e3..4b3d3c0ff2 100644 --- a/tests/e2e/ipWhitelist_spec.js +++ b/tests/e2e/ipWhitelist_spec.js @@ -1,36 +1,31 @@ -const fetch = require("fetch"); -const helpers = require("./global-setup"); +const helpers = require("./helpers/global-setup"); -describe("ipWhitelist directive configuration", function () { - describe("Set ipWhitelist without access", function () { - beforeAll(function () { - helpers.startApplication("tests/configs/noIpWhiteList.js"); +describe("ipWhitelist directive configuration", () => { + describe("Set ipWhitelist without access", () => { + beforeAll(async () => { + await helpers.startApplication("tests/configs/noIpWhiteList.js"); }); - afterAll(async function () { + afterAll(async () => { await helpers.stopApplication(); }); - it("should return 403", function (done) { - fetch("http://localhost:8080").then((res) => { - expect(res.status).toBe(403); - done(); - }); + it("should return 403", async () => { + const res = await helpers.fetch("http://localhost:8080"); + expect(res.status).toBe(403); }); }); - describe("Set ipWhitelist []", function () { - beforeAll(function () { - helpers.startApplication("tests/configs/empty_ipWhiteList.js"); + describe("Set ipWhitelist []", () => { + beforeAll(async () => { + await helpers.startApplication("tests/configs/empty_ipWhiteList.js"); }); - afterAll(async function () { + afterAll(async () => { await helpers.stopApplication(); }); - it("should return 200", function (done) { - fetch("http://localhost:8080").then((res) => { - expect(res.status).toBe(200); - done(); - }); + it("should return 200", async () => { + const res = await helpers.fetch("http://localhost:8080"); + expect(res.status).toBe(200); }); }); }); diff --git a/tests/e2e/modules/alert_spec.js b/tests/e2e/modules/alert_spec.js index 9d246ed5e3..c118e17ef3 100644 --- a/tests/e2e/modules/alert_spec.js +++ b/tests/e2e/modules/alert_spec.js @@ -1,19 +1,17 @@ -const helpers = require("../global-setup"); +const helpers = require("../helpers/global-setup"); describe("Alert module", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/alert/default.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/alert/default.js"); + await helpers.getDocument(); }); afterAll(async () => { await helpers.stopApplication(); }); - it("should show the welcome message", (done) => { - helpers.waitForElement(".ns-box .ns-box-inner .light.bright.small").then((elem) => { - done(); - expect(elem).not.toBe(null); - expect(elem.textContent).toContain("Welcome, start was successful!"); - }); + it("should show the welcome message", async () => { + const elem = await helpers.waitForElement(".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/calendar_spec.js b/tests/e2e/modules/calendar_spec.js index 97d42b2fd8..e1bee78e49 100644 --- a/tests/e2e/modules/calendar_spec.js +++ b/tests/e2e/modules/calendar_spec.js @@ -1,31 +1,26 @@ -const helpers = require("../global-setup"); -const serverBasicAuth = require("./basic-auth.js"); +const helpers = require("../helpers/global-setup"); +const serverBasicAuth = require("../helpers/basic-auth.js"); describe("Calendar module", () => { /** - * @param {string} done test done * @param {string} element css selector * @param {string} result expected number * @param {string} not reverse result */ - const testElementLength = (done, element, result, not) => { - helpers.waitForAllElements(element).then((elem) => { - done(); - expect(elem).not.toBe(null); - if (not === "not") { - expect(elem.length).not.toBe(result); - } else { - expect(elem.length).toBe(result); - } - }); + const testElementLength = async (element, result, not) => { + const elem = await helpers.waitForAllElements(element); + expect(elem).not.toBe(null); + if (not === "not") { + expect(elem.length).not.toBe(result); + } else { + expect(elem.length).toBe(result); + } }; - const testTextContain = (done, element, text) => { - helpers.waitForElement(element, "undefinedLoading").then((elem) => { - done(); - expect(elem).not.toBe(null); - expect(elem.textContent).toContain(text); - }); + const testTextContain = async (element, text) => { + const elem = await helpers.waitForElement(element, "undefinedLoading"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain(text); }; afterAll(async () => { @@ -33,133 +28,133 @@ describe("Calendar module", () => { }); describe("Default configuration", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/calendar/default.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/calendar/default.js"); + await helpers.getDocument(); }); - it("should show the default maximumEntries of 10", (done) => { - testElementLength(done, ".calendar .event", 10); + it("should show the default maximumEntries of 10", async () => { + await testElementLength(".calendar .event", 10); }); - it("should show the default calendar symbol in each event", (done) => { - testElementLength(done, ".calendar .event .fa-calendar-alt", 0, "not"); + it("should show the default calendar symbol in each event", async () => { + await testElementLength(".calendar .event .fa-calendar-alt", 0, "not"); }); }); describe("Custom configuration", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/calendar/custom.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/calendar/custom.js"); + await helpers.getDocument(); }); - it("should show the custom maximumEntries of 4", (done) => { - testElementLength(done, ".calendar .event", 4); + it("should show the custom maximumEntries of 4", async () => { + await testElementLength(".calendar .event", 4); }); - it("should show the custom calendar symbol in each event", (done) => { - testElementLength(done, ".calendar .event .fa-birthday-cake", 4); + it("should show the custom calendar symbol in each event", async () => { + await testElementLength(".calendar .event .fa-birthday-cake", 4); }); - it("should show two custom icons for repeating events", (done) => { - testElementLength(done, ".calendar .event .fa-undo", 2); + it("should show two custom icons for repeating events", async () => { + await testElementLength(".calendar .event .fa-undo", 2); }); - it("should show two custom icons for day events", (done) => { - testElementLength(done, ".calendar .event .fa-calendar-day", 2); + it("should show two custom icons for day events", async () => { + await testElementLength(".calendar .event .fa-calendar-day", 2); }); }); describe("Recurring event", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/calendar/recurring.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/calendar/recurring.js"); + await helpers.getDocument(); }); - it("should show the recurring birthday event 6 times", (done) => { - testElementLength(done, ".calendar .event", 6); + it("should show the recurring birthday event 6 times", async () => { + await testElementLength(".calendar .event", 6); }); }); process.setMaxListeners(0); for (let i = -12; i < 12; i++) { describe("Recurring event per timezone", () => { - beforeAll((done) => { + beforeAll(async () => { Date.prototype.getTimezoneOffset = () => { return i * 60; }; - helpers.startApplication("tests/configs/modules/calendar/recurring.js"); - helpers.getDocument(done); + await helpers.startApplication("tests/configs/modules/calendar/recurring.js"); + await helpers.getDocument(); }); - it('should contain text "Mar 25th" in timezone UTC ' + -i, (done) => { - testTextContain(done, ".calendar", "Mar 25th"); + it('should contain text "Mar 25th" in timezone UTC ' + -i, async () => { + await testTextContain(".calendar", "Mar 25th"); }); }); } describe("Changed port", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/calendar/changed-port.js"); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/calendar/changed-port.js"); serverBasicAuth.listen(8010); - helpers.getDocument(done); + await helpers.getDocument(); }); - afterAll((done) => { - serverBasicAuth.close(done()); + afterAll(async () => { + await serverBasicAuth.close(); }); - it("should return TestEvents", (done) => { - testElementLength(done, ".calendar .event", 0, "not"); + it("should return TestEvents", async () => { + await testElementLength(".calendar .event", 0, "not"); }); }); describe("Basic auth", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/calendar/basic-auth.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/calendar/basic-auth.js"); + await helpers.getDocument(); }); - it("should return TestEvents", (done) => { - testElementLength(done, ".calendar .event", 0, "not"); + it("should return TestEvents", async () => { + await testElementLength(".calendar .event", 0, "not"); }); }); describe("Basic auth by default", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/calendar/auth-default.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/calendar/auth-default.js"); + await helpers.getDocument(); }); - it("should return TestEvents", (done) => { - testElementLength(done, ".calendar .event", 0, "not"); + it("should return TestEvents", async () => { + await testElementLength(".calendar .event", 0, "not"); }); }); describe("Basic auth backward compatibility configuration: DEPRECATED", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/calendar/old-basic-auth.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/calendar/old-basic-auth.js"); + await helpers.getDocument(); }); - it("should return TestEvents", (done) => { - testElementLength(done, ".calendar .event", 0, "not"); + it("should return TestEvents", async () => { + await testElementLength(".calendar .event", 0, "not"); }); }); describe("Fail Basic auth", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/calendar/fail-basic-auth.js"); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/calendar/fail-basic-auth.js"); serverBasicAuth.listen(8020); - helpers.getDocument(done); + await helpers.getDocument(); }); - afterAll((done) => { - serverBasicAuth.close(done()); + afterAll(async () => { + await serverBasicAuth.close(); }); - it("should show Unauthorized error", (done) => { - testTextContain(done, ".calendar", "Error in the calendar module. Authorization failed"); + it("should show Unauthorized error", async () => { + await testTextContain(".calendar", "Error in the calendar module. Authorization failed"); }); }); }); diff --git a/tests/e2e/modules/clock_es_spec.js b/tests/e2e/modules/clock_es_spec.js index a02a39c8e9..4bdc4bccf7 100644 --- a/tests/e2e/modules/clock_es_spec.js +++ b/tests/e2e/modules/clock_es_spec.js @@ -1,73 +1,65 @@ -const helpers = require("../global-setup"); +const helpers = require("../helpers/global-setup"); describe("Clock set to spanish language module", () => { afterAll(async () => { await helpers.stopApplication(); }); - const testMatch = (done, element, regex) => { - helpers.waitForElement(element).then((elem) => { - done(); - expect(elem).not.toBe(null); - expect(elem.textContent).toMatch(regex); - }); - }; - describe("with default 24hr clock config", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/clock/es/clock_24hr.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/clock/es/clock_24hr.js"); + await helpers.getDocument(); }); - it("shows date with correct format", (done) => { + it("shows date with correct format", async () => { 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}$/; - testMatch(done, ".clock .date", dateRegex); + await helpers.testMatch(".clock .date", dateRegex); }); - it("shows time in 24hr format", (done) => { + it("shows time in 24hr format", async () => { const timeRegex = /^(?:2[0-3]|[01]\d):[0-5]\d[0-5]\d$/; - testMatch(done, ".clock .time", timeRegex); + await helpers.testMatch(".clock .time", timeRegex); }); }); describe("with default 12hr clock config", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/clock/es/clock_12hr.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/clock/es/clock_12hr.js"); + await helpers.getDocument(); }); - it("shows date with correct format", (done) => { + it("shows date with correct format", async () => { 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}$/; - testMatch(done, ".clock .date", dateRegex); + await helpers.testMatch(".clock .date", dateRegex); }); - it("shows time in 12hr format", (done) => { + it("shows time in 12hr format", async () => { const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[ap]m$/; - testMatch(done, ".clock .time", timeRegex); + await helpers.testMatch(".clock .time", timeRegex); }); }); describe("with showPeriodUpper config enabled", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/clock/es/clock_showPeriodUpper.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/clock/es/clock_showPeriodUpper.js"); + await helpers.getDocument(); }); - it("shows 12hr time with upper case AM/PM", (done) => { + it("shows 12hr time with upper case AM/PM", async () => { const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[AP]M$/; - testMatch(done, ".clock .time", timeRegex); + await helpers.testMatch(".clock .time", timeRegex); }); }); describe("with showWeek config enabled", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/clock/es/clock_showWeek.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/clock/es/clock_showWeek.js"); + await helpers.getDocument(); }); - it("shows week with correct format", (done) => { + it("shows week with correct format", async () => { const weekRegex = /^Semana [0-9]{1,2}$/; - testMatch(done, ".clock .week", weekRegex); + await helpers.testMatch(".clock .week", weekRegex); }); }); }); diff --git a/tests/e2e/modules/clock_spec.js b/tests/e2e/modules/clock_spec.js index 77ea8e6b90..e91237b248 100644 --- a/tests/e2e/modules/clock_spec.js +++ b/tests/e2e/modules/clock_spec.js @@ -1,4 +1,4 @@ -const helpers = require("../global-setup"); +const helpers = require("../helpers/global-setup"); const moment = require("moment"); describe("Clock module", () => { @@ -6,118 +6,105 @@ describe("Clock module", () => { await helpers.stopApplication(); }); - const testMatch = (done, element, regex) => { - helpers.waitForElement(element).then((elem) => { - done(); - expect(elem).not.toBe(null); - expect(elem.textContent).toMatch(regex); - }); - }; - describe("with default 24hr clock config", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/clock/clock_24hr.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/clock/clock_24hr.js"); + await helpers.getDocument(); }); - it("should show the date in the correct format", (done) => { + it("should show the date in the correct format", async () => { 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}$/; - testMatch(done, ".clock .date", dateRegex); + await helpers.testMatch(".clock .date", dateRegex); }); - it("should show the time in 24hr format", (done) => { + it("should show the time in 24hr format", async () => { const timeRegex = /^(?:2[0-3]|[01]\d):[0-5]\d[0-5]\d$/; - testMatch(done, ".clock .time", timeRegex); + await helpers.testMatch(".clock .time", timeRegex); }); }); describe("with default 12hr clock config", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/clock/clock_12hr.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/clock/clock_12hr.js"); + await helpers.getDocument(); }); - it("should show the date in the correct format", (done) => { + it("should show the date in the correct format", async () => { 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}$/; - testMatch(done, ".clock .date", dateRegex); + await helpers.testMatch(".clock .date", dateRegex); }); - it("should show the time in 12hr format", (done) => { + it("should show the time in 12hr format", async () => { const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[ap]m$/; - testMatch(done, ".clock .time", timeRegex); + await helpers.testMatch(".clock .time", timeRegex); }); }); describe("with showPeriodUpper config enabled", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/clock/clock_showPeriodUpper.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/clock/clock_showPeriodUpper.js"); + await helpers.getDocument(); }); - it("should show 12hr time with upper case AM/PM", (done) => { + it("should show 12hr time with upper case AM/PM", async () => { const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[AP]M$/; - testMatch(done, ".clock .time", timeRegex); + await helpers.testMatch(".clock .time", timeRegex); }); }); describe("with displaySeconds config disabled", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/clock/clock_displaySeconds_false.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/clock/clock_displaySeconds_false.js"); + await helpers.getDocument(); }); - it("should show 12hr time without seconds am/pm", (done) => { + it("should show 12hr time without seconds am/pm", async () => { const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[ap]m$/; - testMatch(done, ".clock .time", timeRegex); + await helpers.testMatch(".clock .time", timeRegex); }); }); describe("with showTime config disabled", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/clock/clock_showTime.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/clock/clock_showTime.js"); + await helpers.getDocument(); }); - it("should not show the time when digital clock is shown", (done) => { - const elem = document.querySelector(".clock .digital .time"); - done(); + it("should not show the time when digital clock is shown", async () => { + const elem = await document.querySelector(".clock .digital .time"); expect(elem).toBe(null); }); }); describe("with showWeek config enabled", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/clock/clock_showWeek.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/clock/clock_showWeek.js"); + await helpers.getDocument(); }); - it("should show the week in the correct format", (done) => { + it("should show the week in the correct format", async () => { const weekRegex = /^Week [0-9]{1,2}$/; - testMatch(done, ".clock .week", weekRegex); + await helpers.testMatch(".clock .week", weekRegex); }); - it("should show the week with the correct number of week of year", (done) => { + it("should show the week with the correct number of week of year", async () => { const currentWeekNumber = moment().week(); const weekToShow = "Week " + currentWeekNumber; - helpers.waitForElement(".clock .week").then((elem) => { - done(); - expect(elem).not.toBe(null); - expect(elem.textContent).toBe(weekToShow); - }); + const elem = await helpers.waitForElement(".clock .week"); + expect(elem).not.toBe(null); + expect(elem.textContent).toBe(weekToShow); }); }); describe("with analog clock face enabled", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/clock/clock_analog.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/clock/clock_analog.js"); + await helpers.getDocument(); }); - it("should show the analog clock face", (done) => { - helpers.waitForElement(".clockCircle").then((elem) => { - done(); - expect(elem).not.toBe(null); - }); + it("should show the analog clock face", async () => { + const elem = helpers.waitForElement(".clockCircle"); + expect(elem).not.toBe(null); }); }); }); diff --git a/tests/e2e/modules/compliments_spec.js b/tests/e2e/modules/compliments_spec.js index d53b968760..52d232e5dc 100644 --- a/tests/e2e/modules/compliments_spec.js +++ b/tests/e2e/modules/compliments_spec.js @@ -1,98 +1,55 @@ -const helpers = require("../global-setup"); +const helpers = require("../helpers/global-setup"); -/** - * move similar tests in function doTest - * - * @param {string} done test done - * @param {Array} complimentsArray The array of compliments. - */ -const doTest = (done, complimentsArray) => { - helpers.waitForElement(".compliments").then((elem) => { +describe("Compliments module", () => { + /** + * move similar tests in function doTest + * + * @param {Array} complimentsArray The array of compliments. + */ + const doTest = async (complimentsArray) => { + let elem = await helpers.waitForElement(".compliments"); expect(elem).not.toBe(null); - helpers.waitForElement(".module-content").then((elem) => { - done(); - expect(elem).not.toBe(null); - expect(complimentsArray).toContain(elem.textContent); - }); - }); -}; + elem = await helpers.waitForElement(".module-content"); + expect(elem).not.toBe(null); + expect(complimentsArray).toContain(elem.textContent); + }; -describe("Compliments module", () => { afterAll(async () => { await helpers.stopApplication(); }); - describe("parts of days", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/compliments/compliments_parts_day.js"); - helpers.getDocument(done); - }); - - it("if Morning compliments for that part of day", (done) => { - const hour = new Date().getHours(); - if (hour >= 3 && hour < 12) { - // if morning check - doTest(done, ["Hi", "Good Morning", "Morning test"]); - } else { - done(); - } - }); - - it("if Afternoon show Compliments for that part of day", (done) => { - const hour = new Date().getHours(); - if (hour >= 12 && hour < 17) { - // if afternoon check - doTest(done, ["Hello", "Good Afternoon", "Afternoon test"]); - } else { - done(); - } - }); - - it("if Evening show Compliments for that part of day", (done) => { - const hour = new Date().getHours(); - if (!(hour >= 3 && hour < 12) && !(hour >= 12 && hour < 17)) { - // if evening check - doTest(done, ["Hello There", "Good Evening", "Evening test"]); - } else { - done(); - } - }); - }); - describe("Feature anytime in compliments module", () => { describe("Set anytime and empty compliments for morning, evening and afternoon ", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/compliments/compliments_anytime.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/compliments/compliments_anytime.js"); + await helpers.getDocument(); }); - it("Show anytime because if configure empty parts of day compliments and set anytime compliments", (done) => { - doTest(done, ["Anytime here"]); + it("Show anytime because if configure empty parts of day compliments and set anytime compliments", async () => { + await doTest(["Anytime here"]); }); }); describe("Only anytime present in configuration compliments", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/compliments/compliments_only_anytime.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/compliments/compliments_only_anytime.js"); + await helpers.getDocument(); }); - it("Show anytime compliments", (done) => { - doTest(done, ["Anytime here"]); + it("Show anytime compliments", async () => { + await doTest(["Anytime here"]); }); }); }); - describe("Feature date in compliments module", () => { - describe("Set date and empty compliments for anytime, morning, evening and afternoon", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/compliments/compliments_date.js"); - helpers.getDocument(done); - }); + describe("remoteFile option", () => { + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/compliments/compliments_remote.js"); + await helpers.getDocument(); + }); - it("Show happy new year compliment on new years day", (done) => { - doTest(done, ["Happy new year!"]); - }); + it("should show compliments from a remote file", async () => { + await doTest(["Remote compliment file works!"]); }); }); }); diff --git a/tests/e2e/modules/helloworld_spec.js b/tests/e2e/modules/helloworld_spec.js index cba9afb452..ecdcdf2076 100644 --- a/tests/e2e/modules/helloworld_spec.js +++ b/tests/e2e/modules/helloworld_spec.js @@ -1,4 +1,4 @@ -const helpers = require("../global-setup"); +const helpers = require("../helpers/global-setup"); describe("Test helloworld module", () => { afterAll(async () => { @@ -6,32 +6,28 @@ describe("Test helloworld module", () => { }); describe("helloworld set config text", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/helloworld/helloworld.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/helloworld/helloworld.js"); + await helpers.getDocument(); }); - it("Test message helloworld module", (done) => { - helpers.waitForElement(".helloworld").then((elem) => { - done(); - expect(elem).not.toBe(null); - expect(elem.textContent).toContain("Test HelloWorld Module"); - }); + it("Test message helloworld module", async () => { + const elem = await helpers.waitForElement(".helloworld"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("Test HelloWorld Module"); }); }); describe("helloworld default config text", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/helloworld/helloworld_default.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/helloworld/helloworld_default.js"); + await helpers.getDocument(); }); - it("Test message helloworld module", (done) => { - helpers.waitForElement(".helloworld").then((elem) => { - done(); - expect(elem).not.toBe(null); - expect(elem.textContent).toContain("Hello World!"); - }); + it("Test message helloworld module", async () => { + const elem = await helpers.waitForElement(".helloworld"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("Hello World!"); }); }); }); diff --git a/tests/e2e/modules/mocks/index.js b/tests/e2e/modules/mocks/index.js deleted file mode 100644 index c708263857..0000000000 --- a/tests/e2e/modules/mocks/index.js +++ /dev/null @@ -1,4 +0,0 @@ -const generateWeather = require("./weather_current"); -const generateWeatherForecast = require("./weather_forecast"); - -module.exports = { generateWeather, generateWeatherForecast }; diff --git a/tests/e2e/modules/mocks/weather_current.js b/tests/e2e/modules/mocks/weather_current.js deleted file mode 100644 index c466129afc..0000000000 --- a/tests/e2e/modules/mocks/weather_current.js +++ /dev/null @@ -1,64 +0,0 @@ -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( - {}, - { - coord: { - lon: 11.58, - lat: 48.14 - }, - weather: [ - { - id: 615, - main: "Snow", - description: "light rain and snow", - icon: "13d" - }, - { - id: 500, - main: "Rain", - description: "light rain", - icon: "10d" - } - ], - base: "stations", - main: { - temp: 1.49, - pressure: 1005, - humidity: 93.7, - temp_min: 1, - temp_max: 2 - }, - visibility: 7000, - wind: { - speed: 11.8, - deg: 250 - }, - clouds: { - all: 75 - }, - dt: 1547387400, - sys: { - type: 1, - id: 1267, - message: 0.0031, - country: "DE", - sunrise: 1547362817, - sunset: 1547394301 - }, - id: 2867714, - name: "Munich", - cod: 200 - }, - extendedData - ) - ); -} - -module.exports = generateWeather; diff --git a/tests/e2e/modules/newsfeed_spec.js b/tests/e2e/modules/newsfeed_spec.js index 11ef59121c..bf3066e753 100644 --- a/tests/e2e/modules/newsfeed_spec.js +++ b/tests/e2e/modules/newsfeed_spec.js @@ -1,4 +1,4 @@ -const helpers = require("../global-setup"); +const helpers = require("../helpers/global-setup"); describe("Newsfeed module", () => { afterAll(async () => { @@ -6,86 +6,72 @@ describe("Newsfeed module", () => { }); describe("Default configuration", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/newsfeed/default.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/newsfeed/default.js"); + await helpers.getDocument(); }); - it("should show the newsfeed title", (done) => { - helpers.waitForElement(".newsfeed .newsfeed-source").then((elem) => { - done(); - expect(elem).not.toBe(null); - expect(elem.textContent).toContain("Rodrigo Ramirez Blog"); - }); + it("should show the newsfeed title", async () => { + const elem = await helpers.waitForElement(".newsfeed .newsfeed-source"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("Rodrigo Ramirez Blog"); }); - it("should show the newsfeed article", (done) => { - helpers.waitForElement(".newsfeed .newsfeed-title").then((elem) => { - done(); - expect(elem).not.toBe(null); - expect(elem.textContent).toContain("QPanel"); - }); + it("should show the newsfeed article", async () => { + const elem = await helpers.waitForElement(".newsfeed .newsfeed-title"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("QPanel"); }); - it("should NOT show the newsfeed description", (done) => { - helpers.waitForElement(".newsfeed").then((elem) => { - const element = document.querySelector(".newsfeed .newsfeed-desc"); - done(); - expect(element).toBe(null); - }); + it("should NOT show the newsfeed description", async () => { + await helpers.waitForElement(".newsfeed"); + const element = document.querySelector(".newsfeed .newsfeed-desc"); + expect(element).toBe(null); }); }); describe("Custom configuration", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/newsfeed/prohibited_words.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/newsfeed/prohibited_words.js"); + await helpers.getDocument(); }); - it("should not show articles with prohibited words", (done) => { - helpers.waitForElement(".newsfeed .newsfeed-title").then((elem) => { - done(); - expect(elem).not.toBe(null); - expect(elem.textContent).toContain("Problema VirtualBox"); - }); + it("should not show articles with prohibited words", async () => { + const elem = await helpers.waitForElement(".newsfeed .newsfeed-title"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("Problema VirtualBox"); }); - it("should show the newsfeed description", (done) => { - helpers.waitForElement(".newsfeed .newsfeed-desc").then((elem) => { - done(); - expect(elem).not.toBe(null); - expect(elem.textContent.length).not.toBe(0); - }); + it("should show the newsfeed description", async () => { + const elem = await helpers.waitForElement(".newsfeed .newsfeed-desc"); + expect(elem).not.toBe(null); + expect(elem.textContent.length).not.toBe(0); }); }); describe("Invalid configuration", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/newsfeed/incorrect_url.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/newsfeed/incorrect_url.js"); + await helpers.getDocument(); }); - it("should show malformed url warning", (done) => { - helpers.waitForElement(".newsfeed .small", "No news at the moment.").then((elem) => { - done(); - expect(elem).not.toBe(null); - expect(elem.textContent).toContain("Error in the Newsfeed module. Malformed url."); - }); + it("should show malformed url warning", async () => { + const elem = await helpers.waitForElement(".newsfeed .small", "No news at the moment."); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("Error in the Newsfeed module. Malformed url."); }); }); describe("Ignore items", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/newsfeed/ignore_items.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/newsfeed/ignore_items.js"); + await helpers.getDocument(); }); - it("should show empty items info message", (done) => { - helpers.waitForElement(".newsfeed .small").then((elem) => { - done(); - expect(elem).not.toBe(null); - expect(elem.textContent).toContain("No news at the moment."); - }); + it("should show empty items info message", async () => { + const elem = await helpers.waitForElement(".newsfeed .small"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("No news at the moment."); }); }); }); diff --git a/tests/e2e/modules/weather_current_spec.js b/tests/e2e/modules/weather_current_spec.js new file mode 100644 index 0000000000..97ae3eec85 --- /dev/null +++ b/tests/e2e/modules/weather_current_spec.js @@ -0,0 +1,84 @@ +const helpers = require("../helpers/global-setup"); +const weatherFunc = require("../helpers/weather-functions"); + +describe("Weather module", () => { + afterAll(async () => { + await helpers.stopApplication(); + }); + + describe("Current weather", () => { + describe("Default configuration", () => { + beforeAll(async () => { + await weatherFunc.startApp("tests/configs/modules/weather/currentweather_default.js", {}); + }); + + it("should render wind speed and wind direction", async () => { + await weatherFunc.getText(".weather .normal.medium span:nth-child(2)", "12 WSW"); + }); + + it("should render temperature with icon", async () => { + await weatherFunc.getText(".weather .large.light span.bright", "1.5°"); + }); + + it("should render feels like temperature", async () => { + await weatherFunc.getText(".weather .normal.medium.feelslike span.dimmed", "Feels like -5.6°"); + }); + }); + }); + + describe("Compliments Integration", () => { + beforeAll(async () => { + await weatherFunc.startApp("tests/configs/modules/weather/currentweather_compliments.js", {}); + }); + + it("should render a compliment based on the current weather", async () => { + await weatherFunc.getText(".compliments .module-content span", "snow"); + }); + }); + + describe("Configuration Options", () => { + beforeAll(async () => { + await weatherFunc.startApp("tests/configs/modules/weather/currentweather_options.js", {}); + }); + + it("should render windUnits in beaufort", async () => { + await weatherFunc.getText(".weather .normal.medium span:nth-child(2)", "6"); + }); + + it("should render windDirection with an arrow", async () => { + const elem = await helpers.waitForElement(".weather .normal.medium sup i.fa-long-arrow-alt-up"); + expect(elem).not.toBe(null); + expect(elem.outerHTML).toContain("transform:rotate(250deg);"); + }); + + it("should render humidity", async () => { + await weatherFunc.getText(".weather .normal.medium span:nth-child(3)", "93.7"); + }); + + it("should render degreeLabel for temp", async () => { + await weatherFunc.getText(".weather .large.light span.bright", "1°C"); + }); + + it("should render degreeLabel for feels like", async () => { + await weatherFunc.getText(".weather .normal.medium.feelslike span.dimmed", "Feels like -6°C"); + }); + }); + + describe("Current weather with imperial units", () => { + beforeAll(async () => { + await weatherFunc.startApp("tests/configs/modules/weather/currentweather_units.js", {}); + }); + + it("should render wind in imperial units", async () => { + await weatherFunc.getText(".weather .normal.medium span:nth-child(2)", "26 WSW"); + }); + + it("should render temperatures in fahrenheit", async () => { + await weatherFunc.getText(".weather .large.light span.bright", "34,7°"); + }); + + it("should render 'feels like' in fahrenheit", async () => { + await weatherFunc.getText(".weather .normal.medium.feelslike span.dimmed", "Feels like 21,9°"); + }); + }); +}); diff --git a/tests/e2e/modules/weather_forecast_spec.js b/tests/e2e/modules/weather_forecast_spec.js new file mode 100644 index 0000000000..cd03691609 --- /dev/null +++ b/tests/e2e/modules/weather_forecast_spec.js @@ -0,0 +1,96 @@ +const helpers = require("../helpers/global-setup"); +const weatherFunc = require("../helpers/weather-functions"); + +describe("Weather module: Weather Forecast", () => { + afterAll(async () => { + await helpers.stopApplication(); + }); + + describe("Default configuration", () => { + beforeAll(async () => { + await weatherFunc.startApp("tests/configs/modules/weather/forecastweather_default.js", {}); + }); + + const days = ["Today", "Tomorrow", "Sun", "Mon", "Tue"]; + for (const [index, day] of days.entries()) { + it("should render day " + day, async () => { + await weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(1)`, day); + }); + } + + const icons = ["day-cloudy", "rain", "day-sunny", "day-sunny", "day-sunny"]; + for (const [index, icon] of icons.entries()) { + it("should render icon " + icon, async () => { + const elem = await helpers.waitForElement(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(2) span.wi-${icon}`); + expect(elem).not.toBe(null); + }); + } + + const maxTemps = ["24.4°", "21.0°", "22.9°", "23.4°", "20.6°"]; + for (const [index, temp] of maxTemps.entries()) { + it("should render max temperature " + temp, async () => { + await weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(3)`, temp); + }); + } + + const minTemps = ["15.3°", "13.6°", "13.8°", "13.9°", "10.9°"]; + for (const [index, temp] of minTemps.entries()) { + it("should render min temperature " + temp, async () => { + await weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(4)`, temp); + }); + } + + const opacities = [1, 1, 0.8, 0.5333333333333333, 0.2666666666666667]; + for (const [index, opacity] of opacities.entries()) { + it("should render fading of rows with opacity=" + opacity, async () => { + const elem = await helpers.waitForElement(`.weather table.small tr:nth-child(${index + 1})`); + expect(elem).not.toBe(null); + expect(elem.outerHTML).toContain(``); + }); + } + }); + + describe("Absolute configuration", () => { + beforeAll(async () => { + await weatherFunc.startApp("tests/configs/modules/weather/forecastweather_absolute.js", {}); + }); + + const days = ["Fri", "Sat", "Sun", "Mon", "Tue"]; + for (const [index, day] of days.entries()) { + it("should render day " + day, async () => { + await weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(1)`, day); + }); + } + }); + + describe("Configuration Options", () => { + beforeAll(async () => { + await weatherFunc.startApp("tests/configs/modules/weather/forecastweather_options.js", {}); + }); + + it("should render custom table class", async () => { + const elem = await helpers.waitForElement(".weather table.myTableClass"); + expect(elem).not.toBe(null); + }); + + it("should render colored rows", async () => { + const table = await helpers.waitForElement(".weather table.myTableClass"); + expect(table).not.toBe(null); + expect(table.rows).not.toBe(null); + expect(table.rows.length).toBe(5); + }); + }); + + describe("Forecast weather units", () => { + beforeAll(async () => { + await weatherFunc.startApp("tests/configs/modules/weather/forecastweather_units.js", {}); + }); + + const temperatures = ["75_9°", "69_8°", "73_2°", "74_1°", "69_1°"]; + for (const [index, temp] of temperatures.entries()) { + it("should render custom decimalSymbol = '_' for temp " + temp, async () => { + await weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(3)`, temp); + }); + } + }); +}); diff --git a/tests/e2e/modules/weather_spec.js b/tests/e2e/modules/weather_spec.js deleted file mode 100644 index 9816e153a3..0000000000 --- a/tests/e2e/modules/weather_spec.js +++ /dev/null @@ -1,273 +0,0 @@ -const moment = require("moment"); -const helpers = require("../global-setup"); -const path = require("path"); -const fs = require("fs"); -const { generateWeather, generateWeatherForecast } = require("./mocks"); - -describe("Weather module", () => { - /** - * @param {string} done test done - * @param {string} element css selector - * @param {string} result Expected text in given selector - */ - const getText = (done, element, result) => { - helpers.waitForElement(element).then((elem) => { - done(); - expect(elem).not.toBe(null); - expect( - elem.textContent - .trim() - .replace(/(\r\n|\n|\r)/gm, "") - .replace(/[ ]+/g, " ") - ).toBe(result); - }); - }; - - /** - * @param {string} configFile path to configuration file - * @param {string} additionalMockData special data for mocking - * @param {string} callback callback - */ - const startApp = (configFile, additionalMockData, callback) => { - let mockWeather; - if (configFile.includes("forecast")) { - mockWeather = generateWeatherForecast(additionalMockData); - } else { - mockWeather = generateWeather(additionalMockData); - } - let content = fs.readFileSync(path.resolve(__dirname + "../../../../" + configFile)).toString(); - content = content.replace("#####WEATHERDATA#####", mockWeather); - fs.writeFileSync(path.resolve(__dirname + "../../../../config/config.js"), content); - helpers.startApplication(""); - helpers.getDocument(callback); - }; - - afterAll(async () => { - await helpers.stopApplication(); - }); - - describe("Current weather", () => { - describe("Default configuration", () => { - beforeAll((done) => { - startApp("tests/configs/modules/weather/currentweather_default.js", {}, done); - }); - - it("should render wind speed and wind direction", (done) => { - getText(done, ".weather .normal.medium span:nth-child(2)", "6 WSW"); // now "12" - }); - - it("should render temperature with icon", (done) => { - getText(done, ".weather .large.light span.bright", "1.5°"); // now "1°C" - }); - - it("should render feels like temperature", (done) => { - getText(done, ".weather .normal.medium.feelslike span.dimmed", "Feels like -5.6°"); // now "Feels like -6°C" - }); - }); - - describe("Default configuration with sunrise", () => { - beforeAll((done) => { - const sunrise = moment().startOf("day").unix(); - const sunset = moment().startOf("day").unix(); - startApp("tests/configs/modules/weather/currentweather_default.js", { sys: { sunrise, sunset } }, done); - }); - - it("should render sunrise", (done) => { - getText(done, ".weather .normal.medium span:nth-child(4)", "12:00 am"); - }); - }); - - describe("Default configuration with sunset", () => { - beforeAll((done) => { - const sunrise = moment().startOf("day").unix(); - const sunset = moment().endOf("day").unix(); - startApp("tests/configs/modules/weather/currentweather_default.js", { sys: { sunrise, sunset } }, done); - }); - - it("should render sunset", (done) => { - getText(done, ".weather .normal.medium span:nth-child(4)", "11:59 pm"); - }); - }); - }); - - describe("Compliments Integration", () => { - beforeAll((done) => { - startApp("tests/configs/modules/weather/currentweather_compliments.js", {}, done); - }); - - it("should render a compliment based on the current weather", (done) => { - getText(done, ".compliments .module-content span", "snow"); - }); - }); - - describe("Configuration Options", () => { - beforeAll((done) => { - startApp("tests/configs/modules/weather/currentweather_options.js", {}, done); - }); - - it("should render useBeaufort = false", (done) => { - getText(done, ".weather .normal.medium span:nth-child(2)", "12"); - }); - - it("should render showWindDirectionAsArrow = true", (done) => { - helpers.waitForElement(".weather .normal.medium sup i.fa-long-arrow-alt-up").then((elem) => { - done(); - expect(elem).not.toBe(null); - expect(elem.outerHTML).toContain("transform:rotate(250deg);"); - }); - }); - - it("should render showHumidity = true", (done) => { - getText(done, ".weather .normal.medium span:nth-child(3)", "93.7"); - }); - - it("should render degreeLabel = true for temp", (done) => { - getText(done, ".weather .large.light span.bright", "1°C"); - }); - - it("should render degreeLabel = true for feels like", (done) => { - getText(done, ".weather .normal.medium.feelslike span.dimmed", "Feels like -6°C"); - }); - }); - - describe("Current weather units", () => { - beforeAll((done) => { - startApp( - "tests/configs/modules/weather/currentweather_units.js", - { - main: { - temp: (1.49 * 9) / 5 + 32, - temp_min: (1 * 9) / 5 + 32, - temp_max: (2 * 9) / 5 + 32 - }, - wind: { - speed: 11.8 * 2.23694 - } - }, - done - ); - }); - - it("should render imperial units for wind", (done) => { - getText(done, ".weather .normal.medium span:nth-child(2)", "6 WSW"); - }); - - it("should render imperial units for temp", (done) => { - getText(done, ".weather .large.light span.bright", "34,7°"); - }); - - it("should render imperial units for feels like", (done) => { - getText(done, ".weather .normal.medium.feelslike span.dimmed", "Feels like 22,0°"); - }); - - it("should render custom decimalSymbol = ',' for humidity", (done) => { - getText(done, ".weather .normal.medium span:nth-child(3)", "93,7"); - }); - - it("should render custom decimalSymbol = ',' for temp", (done) => { - getText(done, ".weather .large.light span.bright", "34,7°"); - }); - - it("should render custom decimalSymbol = ',' for feels like", (done) => { - getText(done, ".weather .normal.medium.feelslike span.dimmed", "Feels like 22,0°"); - }); - }); - - describe("Weather Forecast", () => { - describe("Default configuration", () => { - beforeAll((done) => { - startApp("tests/configs/modules/weather/forecastweather_default.js", {}, done); - }); - - const days = ["Today", "Tomorrow", "Sun", "Mon", "Tue"]; - for (const [index, day] of days.entries()) { - it("should render day " + day, (done) => { - getText(done, `.weather table.small tr:nth-child(${index + 1}) td:nth-child(1)`, day); - }); - } - - const icons = ["day-cloudy", "rain", "day-sunny", "day-sunny", "day-sunny"]; - for (const [index, icon] of icons.entries()) { - it("should render icon " + icon, (done) => { - helpers.waitForElement(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(2) span.wi-${icon}`).then((elem) => { - done(); - expect(elem).not.toBe(null); - }); - }); - } - - const maxTemps = ["24.4°", "21.0°", "22.9°", "23.4°", "20.6°"]; - for (const [index, temp] of maxTemps.entries()) { - it("should render max temperature " + temp, (done) => { - getText(done, `.weather table.small tr:nth-child(${index + 1}) td:nth-child(3)`, temp); - }); - } - - const minTemps = ["15.3°", "13.6°", "13.8°", "13.9°", "10.9°"]; - for (const [index, temp] of minTemps.entries()) { - it("should render min temperature " + temp, (done) => { - getText(done, `.weather table.small tr:nth-child(${index + 1}) td:nth-child(4)`, temp); - }); - } - - const opacities = [1, 1, 0.8, 0.5333333333333333, 0.2666666666666667]; - for (const [index, opacity] of opacities.entries()) { - it("should render fading of rows with opacity=" + opacity, (done) => { - helpers.waitForElement(`.weather table.small tr:nth-child(${index + 1})`).then((elem) => { - done(); - expect(elem).not.toBe(null); - expect(elem.outerHTML).toContain(``); - }); - }); - } - }); - - describe("Absolute configuration", () => { - beforeAll((done) => { - startApp("tests/configs/modules/weather/forecastweather_absolute.js", {}, done); - }); - - const days = ["Fri", "Sat", "Sun", "Mon", "Tue"]; - for (const [index, day] of days.entries()) { - it("should render day " + day, (done) => { - getText(done, `.weather table.small tr:nth-child(${index + 1}) td:nth-child(1)`, day); - }); - } - }); - - describe("Configuration Options", () => { - beforeAll((done) => { - startApp("tests/configs/modules/weather/forecastweather_options.js", {}, done); - }); - - it("should render custom table class", (done) => { - helpers.waitForElement(".weather table.myTableClass").then((elem) => { - done(); - expect(elem).not.toBe(null); - }); - }); - - it("should render colored rows", (done) => { - helpers.waitForElement(".weather table.myTableClass").then((table) => { - done(); - expect(table).not.toBe(null); - expect(table.rows).not.toBe(null); - expect(table.rows.length).toBe(5); - }); - }); - }); - - describe("Forecast weather units", () => { - beforeAll((done) => { - startApp("tests/configs/modules/weather/forecastweather_units.js", {}, done); - }); - - const temperatures = ["24_4°", "21_0°", "22_9°", "23_4°", "20_6°"]; - for (const [index, temp] of temperatures.entries()) { - it("should render custom decimalSymbol = '_' for temp " + temp, (done) => { - getText(done, `.weather table.small tr:nth-child(${index + 1}) td:nth-child(3)`, temp); - }); - } - }); - }); -}); diff --git a/tests/e2e/modules_display_spec.js b/tests/e2e/modules_display_spec.js index e907df3663..15520d05c9 100644 --- a/tests/e2e/modules_display_spec.js +++ b/tests/e2e/modules_display_spec.js @@ -1,28 +1,24 @@ -const helpers = require("./global-setup"); +const helpers = require("./helpers/global-setup"); describe("Display of modules", () => { - beforeAll(function (done) { - helpers.startApplication("tests/configs/modules/display.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/display.js"); + await helpers.getDocument(); }); afterAll(async () => { await helpers.stopApplication(); }); - it("should show the test header", (done) => { - helpers.waitForElement("#module_0_helloworld .module-header").then((elem) => { - done(); - 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"); - }); + it("should show the test header", async () => { + const elem = await helpers.waitForElement("#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"); }); - it("should show no header if no header text is specified", (done) => { - helpers.waitForElement("#module_1_helloworld .module-header").then((elem) => { - done(); - expect(elem).not.toBe(null); - expect(elem.textContent).toBe("undefined"); - }); + it("should show no header if no header text is specified", async () => { + const elem = await helpers.waitForElement("#module_1_helloworld .module-header"); + expect(elem).not.toBe(null); + expect(elem.textContent).toBe("undefined"); }); }); diff --git a/tests/e2e/modules_empty_spec.js b/tests/e2e/modules_empty_spec.js new file mode 100644 index 0000000000..ddd08e821e --- /dev/null +++ b/tests/e2e/modules_empty_spec.js @@ -0,0 +1,23 @@ +const helpers = require("./helpers/global-setup"); + +describe("Check configuration without modules", () => { + beforeAll(async () => { + await helpers.startApplication("tests/configs/without_modules.js"); + await helpers.getDocument(); + }); + afterAll(async () => { + await helpers.stopApplication(); + }); + + it("Show the message MagicMirror² title", async () => { + const elem = await helpers.waitForElement("#module_1_helloworld .module-content"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("MagicMirror²"); + }); + + it("Show the url of michael's website", async () => { + const elem = await helpers.waitForElement("#module_5_helloworld .module-content"); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("www.michaelteeuw.nl"); + }); +}); diff --git a/tests/e2e/modules_position_spec.js b/tests/e2e/modules_position_spec.js index 3b6149d37a..606c95a2bc 100644 --- a/tests/e2e/modules_position_spec.js +++ b/tests/e2e/modules_position_spec.js @@ -1,9 +1,9 @@ -const helpers = require("./global-setup"); +const helpers = require("./helpers/global-setup"); describe("Position of modules", () => { - beforeAll((done) => { - helpers.startApplication("tests/configs/modules/positions.js"); - helpers.getDocument(done); + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/positions.js"); + await helpers.getDocument(); }); afterAll(async () => { await helpers.stopApplication(); @@ -13,12 +13,10 @@ describe("Position of modules", () => { for (const position of positions) { const className = position.replace("_", "."); - it("should show text in " + position, (done) => { - helpers.waitForElement("." + className).then((elem) => { - done(); - expect(elem).not.toBe(null); - expect(elem.textContent).toContain("Text in " + position); - }); + it("should show text in " + position, async () => { + const elem = await helpers.waitForElement("." + className); + expect(elem).not.toBe(null); + expect(elem.textContent).toContain("Text in " + position); }); } }); diff --git a/tests/e2e/port_config.js b/tests/e2e/port_config.js deleted file mode 100644 index 4a168d91f7..0000000000 --- a/tests/e2e/port_config.js +++ /dev/null @@ -1,36 +0,0 @@ -const fetch = require("fetch"); -const helpers = require("./global-setup"); - -describe("port directive configuration", function () { - describe("Set port 8090", function () { - beforeAll(function () { - helpers.startApplication("tests/configs/port_8090.js"); - }); - afterAll(async function () { - await helpers.stopApplication(); - }); - - it("should return 200", function (done) { - fetch("http://localhost:8090").then((res) => { - expect(res.status).toBe(200); - done(); - }); - }); - }); - - describe("Set port 8100 on environment variable MM_PORT", function () { - beforeAll(function () { - helpers.startApplication("tests/configs/port_8090.js", (process.env.MM_PORT = 8100)); - }); - afterAll(async function () { - await helpers.stopApplication(); - }); - - it("should return 200", function (done) { - fetch("http://localhost:8100").then((res) => { - expect(res.status).toBe(200); - done(); - }); - }); - }); -}); diff --git a/tests/e2e/port_spec.js b/tests/e2e/port_spec.js new file mode 100644 index 0000000000..104b9373dc --- /dev/null +++ b/tests/e2e/port_spec.js @@ -0,0 +1,31 @@ +const helpers = require("./helpers/global-setup"); + +describe("port directive configuration", () => { + describe("Set port 8090", () => { + beforeAll(async () => { + await helpers.startApplication("tests/configs/port_8090.js"); + }); + afterAll(async () => { + await helpers.stopApplication(); + }); + + it("should return 200", async () => { + const res = await helpers.fetch("http://localhost:8090"); + expect(res.status).toBe(200); + }); + }); + + describe("Set port 8100 on environment variable MM_PORT", () => { + beforeAll(async () => { + await helpers.startApplication("tests/configs/port_8090.js", (process.env.MM_PORT = 8100)); + }); + afterAll(async () => { + await helpers.stopApplication(); + }); + + it("should return 200", async () => { + const res = await helpers.fetch("http://localhost:8100"); + expect(res.status).toBe(200); + }); + }); +}); diff --git a/tests/e2e/translations_spec.js b/tests/e2e/translations_spec.js index 89ae60d918..4d2d1c1e9d 100644 --- a/tests/e2e/translations_spec.js +++ b/tests/e2e/translations_spec.js @@ -6,13 +6,13 @@ const { JSDOM } = require("jsdom"); const express = require("express"); const sinon = require("sinon"); -describe("Translations", function () { +describe("Translations", () => { let server; - beforeAll(function () { + beforeAll(() => { const app = express(); app.use(helmet()); - app.use(function (req, res, next) { + app.use((req, res, next) => { res.header("Access-Control-Allow-Origin", "*"); next(); }); @@ -21,11 +21,11 @@ describe("Translations", function () { server = app.listen(3000); }); - afterAll(function () { + afterAll(() => { server.close(); }); - it("should have a translation file in the specified path", function () { + it("should have a translation file in the specified path", () => { for (let language in translations) { const file = fs.statSync(translations[language]); expect(file.isFile()).toBe(true); @@ -37,7 +37,7 @@ describe("Translations", function () { beforeEach(() => { dom = new JSDOM( - `\ + `\ \ `, { runScripts: "dangerously", resources: "usable" } @@ -45,7 +45,7 @@ describe("Translations", function () { }); it("should load translation file", (done) => { - dom.window.onload = async function () { + dom.window.onload = async () => { const { Translator, Module, config } = dom.window; config.language = "en"; Translator.load = sinon.stub().callsFake((_m, _f, _fb, callback) => callback()); @@ -65,7 +65,7 @@ describe("Translations", function () { }); it("should load translation + fallback file", (done) => { - dom.window.onload = async function () { + dom.window.onload = async () => { const { Translator, Module } = dom.window; Translator.load = sinon.stub().callsFake((_m, _f, _fb, callback) => callback()); @@ -85,7 +85,7 @@ describe("Translations", function () { }); it("should load translation fallback file", (done) => { - dom.window.onload = async function () { + dom.window.onload = async () => { const { Translator, Module, config } = dom.window; config.language = "--"; Translator.load = sinon.stub().callsFake((_m, _f, _fb, callback) => callback()); @@ -105,7 +105,7 @@ describe("Translations", function () { }); it("should load no file", (done) => { - dom.window.onload = async function () { + dom.window.onload = async () => { const { Translator, Module } = dom.window; Translator.load = sinon.stub(); @@ -130,18 +130,18 @@ describe("Translations", function () { } }; - describe("Parsing language files through the Translator class", function () { + describe("Parsing language files through the Translator class", () => { for (let language in translations) { - it(`should parse ${language}`, function (done) { + it(`should parse ${language}`, (done) => { const dom = new JSDOM( - `\ + `\ \ + `\ \ + `\ \ + `\ \ + `\ \ + `\ \ + `\ \ + `\ \ + `\