diff --git a/.eslintignore b/.eslintignore index fa7668825a..24f4f1f599 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1 +1,2 @@ -modules/default/calendar/vendor/* +modules/* +!modules/default/ \ No newline at end of file diff --git a/.eslintrc.json b/.eslintrc.json index 9d40203bee..dccd2ee2dc 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,9 +1,9 @@ { - "extends": ["eslint:recommended", "plugin:prettier/recommended", "plugin:jsdoc/recommended"], - "plugins": ["prettier", "jsdoc", "jest"], + "extends": ["eslint:recommended", "plugin:@stylistic/all-extends", "plugin:import/recommended", "plugin:jest/recommended", "plugin:jsdoc/recommended"], + "plugins": ["unicorn"], "env": { "browser": true, - "es6": true, + "es2024": true, "jest/globals": true, "node": true }, @@ -16,16 +16,78 @@ }, "parserOptions": { "sourceType": "module", - "ecmaVersion": 2020, + "ecmaVersion": "latest", "ecmaFeatures": { "globalReturn": true } }, "rules": { - "prettier/prettier": "error", "eqeqeq": "error", + "import/order": "error", + "import/extensions": "error", + "import/newline-after-import": "error", + "jest/consistent-test-it": "warn", + "jest/expect-expect": "warn", + "jest/no-done-callback": "warn", + "jest/prefer-expect-resolves": "warn", + "jest/prefer-mock-promise-shorthand": "warn", + "jest/prefer-to-be": "warn", + "jest/prefer-to-have-length": "warn", + "no-param-reassign": "error", "no-prototype-builtins": "off", + "no-throw-literal": "error", "no-unused-vars": "off", - "no-useless-return": "error" - } + "no-useless-return": "error", + "object-shorthand": ["error", "methods"], + "prefer-template": "error", + "@stylistic/array-element-newline": ["error", "consistent"], + "@stylistic/arrow-parens": ["error", "always"], + "@stylistic/brace-style": "off", + "@stylistic/comma-dangle": ["error", "never"], + "@stylistic/dot-location": ["error", "property"], + "@stylistic/function-call-argument-newline": ["error", "consistent"], + "@stylistic/function-paren-newline": ["error", "consistent"], + "@stylistic/implicit-arrow-linebreak": ["error", "beside"], + "@stylistic/max-statements-per-line": ["error", { "max": 2 }], + "@stylistic/multiline-ternary": ["error", "always-multiline"], + "@stylistic/newline-per-chained-call": ["error", { "ignoreChainWithDepth": 4 }], + "@stylistic/no-extra-parens": "off", + "@stylistic/no-tabs": "off", + "@stylistic/object-curly-spacing": ["error", "always"], + "@stylistic/object-property-newline": ["error", { "allowAllPropertiesOnSameLine": true }], + "@stylistic/operator-linebreak": ["error", "before"], + "@stylistic/padded-blocks": "off", + "@stylistic/quote-props": ["error", "as-needed"], + "@stylistic/quotes": ["error", "double"], + "@stylistic/indent": ["error", "tab"], + "@stylistic/semi": ["error", "always"], + "@stylistic/space-before-function-paren": ["error", "always"], + "@stylistic/spaced-comment": "off", + "unicorn/prefer-node-protocol": "error" + }, + "overrides": [ + { + "files": ["config/config.js*"], + "rules": { + "@stylistic/comma-dangle": "off", + "@stylistic/indent": "off", + "@stylistic/no-multi-spaces": "off" + } + }, + { + "files": ["tests/configs/modules/weather/*.js"], + "rules": { + "@stylistic/quotes": "off" + } + }, + { + "extends": ["plugin:package-json/recommended"], + "files": ["package.json"], + "parser": "jsonc-eslint-parser", + "plugins": ["package-json"], + "rules": { + "package-json/sort-collections": ["error", ["devDependencies", "dependencies", "peerDependencies", "config"]] + } + } + ] } diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..e65801a77e --- /dev/null +++ b/.gitattributes @@ -0,0 +1,56 @@ +# .gitattributes snippet to force users to use same line endings for project. +# +# Handle line endings automatically for files detected as text +# and leave all files detected as binary untouched. +* text=auto + +# +# The above will handle all files NOT found below +# https://help.github.com/articles/dealing-with-line-endings/ +# https://github.com/Danimoth/gitattributes/blob/master/Web.gitattributes + + + +# These files are text and should be normalized (Convert crlf => lf) +*.php text +*.css text +*.scss text +*.js text +*.json text +*.htm text +*.html text +*.xml text +*.txt text +*.ini text +*.inc text +*.pl text +*.rb text +*.py text +*.scm text +*.sql text +.htaccess text +*.sh text +Dockerfile* text +*.yml text +*.yaml text +*.md text +*.markdown text + +# These files are binary and should be left untouched +# (binary is a macro for -text -diff) +*.png binary +*.jpg binary +*.jpeg binary +*.gif binary +*.ico binary +*.mov binary +*.mp4 binary +*.mp3 binary +*.flv binary +*.fla binary +*.swf binary +*.gz binary +*.zip binary +*.7z binary +*.ttf binary +*.pyc binary \ No newline at end of file diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 0cd23540e3..9fd4d4a921 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -6,7 +6,7 @@ We hold our code to standard, and these standards are documented below. ## Linters -If you wish to run our linters, use `npm run lint` without any arguments. +We use prettier for automatic linting of all our files: `npm run lint:prettier`. ### JavaScript: Run ESLint @@ -18,7 +18,7 @@ To run ESLint, use `npm run lint:js`. ### CSS: Run StyleLint -We use [StyleLint](https://stylelint.io) to lint our CSS. Our configuration is in our .stylelintrc file. +We use [StyleLint](https://stylelint.io) to lint our CSS. Our configuration is in our `.stylelintrc` file. To run StyleLint, use `npm run lint:css`. @@ -28,7 +28,8 @@ We use [Jest](https://jestjs.io) for JavaScript testing. To run all tests, use `npm run test`. -The specific test commands are defined in `package.json`. So you can also run the specific tests with other commands, e.g. `npm run test:unit` or `npx jest tests/e2e/env_spec.js`. +The specific test commands are defined in `package.json`. +So you can also run the specific tests with other commands, e.g. `npm run test:unit` or `npx jest tests/e2e/env_spec.js`. ## Submitting Issues @@ -42,7 +43,7 @@ When submitting a new issue, please supply the following information: **Platform**: Place your platform here... give us your web browser/Electron version _and_ your hardware (Raspberry Pi 2/3/4, Windows, Mac, Linux, System V UNIX). -**Node Version**: Make sure it's version 14 or later (recommended is 16). +**Node Version**: Make sure it's version 18 or later (recommended is 20). **MagicMirror² Version**: Please let us know which version of MagicMirror² you are running. It can be found in the `package.json` file. diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md index 087f41f13a..f24edfc4b0 100644 --- a/.github/ISSUE_TEMPLATE.md +++ b/.github/ISSUE_TEMPLATE.md @@ -1,6 +1,6 @@ Hello and thank you for opening an issue. -**Please make sure that you have read the following lines before submitting your Issue:** +**⚠️ Please make sure that you have read the following lines before submitting your Issue:** ## I'm not sure if this is a bug @@ -22,6 +22,10 @@ If you are facing an issue or found a bug while trying to install MagicMirror² If you are facing an issue or found a bug while running MagicMirror² inside a Docker container please create an issue in the corresponding repository: [https://gitlab.com/khassel/magicmirror](https://gitlab.com/khassel/magicmirror) +## I'm having troubles installing or configuring foreign modules + +Please open an issue in the module repository or ask for help in the [forum](https://forum.magicmirror.builders/) + --- ## I found a bug in MagicMirror @@ -31,7 +35,7 @@ When submitting a new issue, please supply the following information: **Platform**: Place your platform here... give us your web browser/Electron version _and_ your hardware (Raspberry Pi 2/3/4, Windows, Mac, Linux, System V UNIX). -**Node Version**: Make sure it's version 14 or later (recommended is 16). +**Node Version**: Make sure it's version 18 or later (recommended is 20). **MagicMirror² Version**: Please let us know which version of MagicMirror² you are running. It can be found in the `package.json` file. diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md index da43f700a5..ace1e86435 100644 --- a/.github/PULL_REQUEST_TEMPLATE.md +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -3,7 +3,6 @@ Hello and thank you for wanting to contribute to the MagicMirror² project **Please make sure that you have followed these 4 rules before submitting your Pull Request:** > 1. Base your pull requests against the `develop` branch. -> > 2. Include these infos in the description: > > - Does the pull request solve a **related** issue? @@ -13,7 +12,6 @@ Hello and thank you for wanting to contribute to the MagicMirror² project > > 3. Please run `npm run lint:prettier` before submitting so that > style issues are fixed. -> > 4. Don't forget to add an entry about your changes to > the CHANGELOG.md file. diff --git a/.github/codecov.yaml b/.github/codecov.yaml deleted file mode 100644 index 3f76e9b50d..0000000000 --- a/.github/codecov.yaml +++ /dev/null @@ -1,6 +0,0 @@ -coverage: - status: - project: - default: - # advanced settings - informational: true diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml index 5ace4600a1..4f7b4405cb 100644 --- a/.github/dependabot.yaml +++ b/.github/dependabot.yaml @@ -4,3 +4,37 @@ updates: directory: "/" schedule: interval: "weekly" + target-branch: "develop" + labels: + - "Skip Changelog" + - "dependencies" + + - package-ecosystem: "npm" + directory: "/" + schedule: + interval: "monthly" + target-branch: "develop" + labels: + - "Skip Changelog" + - "dependencies" + - "javascript" + + - package-ecosystem: "npm" + directory: "/vendor" + schedule: + interval: "monthly" + target-branch: "develop" + labels: + - "Skip Changelog" + - "dependencies" + - "javascript" + + - package-ecosystem: "npm" + directory: "/fonts" + schedule: + interval: "monthly" + target-branch: "develop" + labels: + - "Skip Changelog" + - "dependencies" + - "javascript" diff --git a/.github/workflows/automated-tests.yaml b/.github/workflows/automated-tests.yaml index 05ce5e455e..301b08d47b 100644 --- a/.github/workflows/automated-tests.yaml +++ b/.github/workflows/automated-tests.yaml @@ -18,20 +18,22 @@ jobs: timeout-minutes: 30 strategy: matrix: - node-version: [14.x, 16.x, 18.x] + node-version: [20.x, 22.x] steps: - - name: Checkout code - uses: actions/checkout@v3 - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 + - name: "Checkout code" + uses: actions/checkout@v4 + - name: "Use Node.js ${{ matrix.node-version }}" + uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} cache: "npm" - - name: Install dependencies and run tests + - name: "Install dependencies" + run: | + npm run install-mm:dev + - name: "Run tests" run: | Xvfb :99 -screen 0 1024x768x16 & export DISPLAY=:99 - npm run install-mm:dev touch css/custom.css npm run test:prettier npm run test:js diff --git a/.github/workflows/codecov-test-suites.yaml b/.github/workflows/codecov-test-suites.yaml deleted file mode 100644 index b46a4724c8..0000000000 --- a/.github/workflows/codecov-test-suites.yaml +++ /dev/null @@ -1,33 +0,0 @@ -# This workflow runs the automated test and uploads the coverage results to codecov.io -# For more information see: https://github.com/codecov/codecov-action - -name: "Run Codecov Tests" - -on: - push: - branches: [master, develop] - pull_request: - branches: [master, develop] - -permissions: - contents: read - -jobs: - run-and-upload-coverage-report: - runs-on: ubuntu-latest - timeout-minutes: 30 - steps: - - name: Checkout code - uses: actions/checkout@v3 - - name: Install dependencies and run coverage - run: | - Xvfb :99 -screen 0 1024x768x16 & - export DISPLAY=:99 - npm ci - touch css/custom.css - npm run test:coverage - - name: Upload coverage results to codecov - uses: codecov/codecov-action@v3 - with: - files: ./coverage/lcov.info - fail_ci_if_error: true diff --git a/.github/workflows/depsreview.yaml b/.github/workflows/depsreview.yaml index 745f4c5eee..141e821b9c 100644 --- a/.github/workflows/depsreview.yaml +++ b/.github/workflows/depsreview.yaml @@ -1,4 +1,8 @@ -name: "Dependency Review" +# This workflow scans your pull requests for dependency changes, and will raise an error if any vulnerabilities or invalid licenses are being introduced. +# For more information see: https://github.com/actions/dependency-review-action + +name: "Review Dependencies" + on: [pull_request] permissions: @@ -8,7 +12,7 @@ jobs: dependency-review: runs-on: ubuntu-latest steps: - - name: "Checkout Repository" - uses: actions/checkout@v3 + - name: "Checkout code" + uses: actions/checkout@v4 - name: "Dependency Review" - uses: actions/dependency-review-action@v2 + uses: actions/dependency-review-action@v4 diff --git a/.github/workflows/electronRebuild.yaml b/.github/workflows/electronRebuild.yaml new file mode 100644 index 0000000000..f9cc50957f --- /dev/null +++ b/.github/workflows/electronRebuild.yaml @@ -0,0 +1,28 @@ +name: "Electron Rebuild Testing" + +on: [pull_request] + +jobs: + rebuild: + name: Run electron-rebuild + runs-on: ubuntu-latest + strategy: + matrix: + node-version: [20.x, 22.x] + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: "Use Node.js ${{ matrix.node-version }}" + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + check-latest: true + - name: Install MagicMirror + run: npm run install-mm + - name: Install @electron/rebuild + run: npm install @electron/rebuild + - name: Install some test library to be rebuilded + run: npm install onoff node-pty drivelist + - name: Run electron-rebuild + run: npx electron-rebuild + continue-on-error: false diff --git a/.github/workflows/enforce-changelog.yaml b/.github/workflows/enforce-changelog.yaml deleted file mode 100644 index 9632ac2d29..0000000000 --- a/.github/workflows/enforce-changelog.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# This workflow enforces the update of a changelog file on every pull request -# For more information see: https://github.com/dangoslen/changelog-enforcer - -name: "Enforce Changelog" - -on: - pull_request: - types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled] - -jobs: - check: - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - name: Enforce changelog️ - uses: dangoslen/changelog-enforcer@v3 - with: - changeLogPath: "CHANGELOG.md" - skipLabels: "Skip Changelog" diff --git a/.github/workflows/enforce-pullrequest-rules.yaml b/.github/workflows/enforce-pullrequest-rules.yaml new file mode 100644 index 0000000000..30c0d0ca08 --- /dev/null +++ b/.github/workflows/enforce-pullrequest-rules.yaml @@ -0,0 +1,28 @@ +# This workflow enforces on every pull request: +# - the update of our CHANGELOG.md file, see: https://github.com/dangoslen/changelog-enforcer +# - that the PR is not based against master, taken from https://github.com/oppia/oppia-android/pull/2832/files + +name: "Enforce Pull-Request Rules" + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled] + +jobs: + check: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - name: "Enforce changelog" + uses: dangoslen/changelog-enforcer@v3 + with: + changeLogPath: "CHANGELOG.md" + skipLabels: "Skip Changelog" + - name: "Enforce develop branch" + if: ${{ github.event.pull_request.base.ref == 'master' && !contains(github.event.pull_request.labels.*.name, 'mastermerge') }} + run: | + echo "This PR is based against the master branch and not a release or hotfix." + echo "Please don't do this. Switch the branch to 'develop'." + exit 1 + env: + BASE_BRANCH: ${{ github.base_ref }} diff --git a/.gitignore b/.gitignore index 861213ce73..945c6c244b 100644 --- a/.gitignore +++ b/.gitignore @@ -63,8 +63,10 @@ Temporary Items !/modules/default/** !/modules/README.md** -# Ignore changes to the custom css files. -/css/custom.css +# Ignore changes to the custom css files but keep the sample and main. +/css/* +!/css/custom.css.sample +!/css/main.css # Ignore users config file but keep the sample. /config/* diff --git a/.husky/pre-commit b/.husky/pre-commit index 7ee201c6c7..d949a3eb50 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,7 +1,5 @@ #!/bin/sh -[ -f "$(dirname "$0")/_/husky.sh" ] && . "$(dirname "$0")/_/husky.sh" - if command -v npm &> /dev/null; then npm run lint:staged fi diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000000..7d713a90a1 --- /dev/null +++ b/.npmrc @@ -0,0 +1,3 @@ +engine-strict=true +audit=false +loglevel="error" diff --git a/.prettierignore b/.prettierignore index b92f216692..daa42fbebb 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,3 +1,8 @@ +*.js +.eslintignore +.husky/pre-commit +.prettierignore /config /coverage package-lock.json +**.ics diff --git a/.stylelintrc.json b/.stylelintrc.json index d450c732dc..18ff23e703 100644 --- a/.stylelintrc.json +++ b/.stylelintrc.json @@ -1,5 +1,5 @@ { - "extends": ["stylelint-prettier/recommended"], + "extends": ["stylelint-config-standard"], "plugins": ["stylelint-prettier"], "rules": { "prettier/prettier": true diff --git a/CHANGELOG.md b/CHANGELOG.md index aae4292565..2b409873de 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,28 +3,320 @@ All notable changes to this project will be documented in this file. 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². +❤️ **Donate:** Enjoying MagicMirror²? [Please consider a donation!](https://magicmirror.builders/#donate) With your help we can continue to improve the MagicMirror². -## [2.22.0] - Unreleased (Develop) +## [2.28.0] - Unreleased (`develop` branch) -_This release is scheduled to be released on 2023-01-01._ +_This release is scheduled to be released on 2024-07-01._ -Special thanks to: @rejas, @sdetweil, @MagMar94 +### Added + +- [calendar] Added config option "showEndsOnlyWithDuration" for default calendar + +### Removed + +- [test suite] delete node v18 support + +### Updated + +- [core] Update dependencies including electron to v31 +- [core] use node >= v20 +- [core] Update `config.js.sample` to use openmeteo as weather provider which needs no api key + +### Fixed + +- [weather] Fixed precipitationProbability in forecast for provider openmeteo (#3446) +- [weather] Fixed type=daily for provider openmeteo having no data when running after 23:00 (#3449) +- [weather] Fixed type=daily for provider openmeteo showing nightly icons in forecast when current time is "nightly" (#3458) + +## [2.27.0] - 2024-04-01 + +Thanks to: @bugsounet, @crazyscot, @illimarkangur, @jkriegshauser, @khassel, @KristjanESPERANTO, @Paranoid93, @rejas, @sdetweil and @vppencilsharpener. + +This release marks the first release without Michael Teeuw (@michmich). A very special thanks to him for creating MagicMirror and leading the project for so many years. + +For more info, please read the following post: [A New Chapter for MagicMirror: The Community Takes the Lead](https://forum.magicmirror.builders/topic/18329/a-new-chapter-for-magicmirror-the-community-takes-the-lead). + +### Added + +- Output of system information to the console for troubleshooting (#3328 and #3337), ignore errors under aarch64 (#3349) +- [core] Add `eslint-plugin-package-json` to lint the `package.json` files (#3368) +- [weather] `showHumidity` config is now a string describing where to show this element. Supported values: "wind", "temp", "feelslike", "below", "none". (#3330) +- electron-rebuild test suite for electron and 3rd party modules compatibility (#3392) +- Create MM² icon and attach it to electron process (#3407) + +### Updated + +- Update updatenotification (update_helper.js): Recode with pm2 library (#3332) +- Removing lodash dependency by replacing merge by spread operator (#3339) +- Use node prefix for build-in modules (#3340) +- Rework logging colors (#3350) +- Update pm2 to v5.3.1 with no allow-ghsas (#3364) +- [core] Update husky and let lint-staged fix ESLint issues +- [core] Update dependencies including electron to v29 (#3357) and node-ical +- Update translations for estonian (#3371) +- Update electron to v29 and update other dependencies +- [calendar] fullDay events over several days now show the left days from the first day on and 'today' on the last day +- Update layout of current weather indoor values + +### Fixed + +- Correct apibase of weathergov weatherprovider to match documentation (#2926) +- Worked around several issues in the RRULE library that were causing deleted calender events to still show, some + initial and recurring events to not show, and some event times to be off an hour. (#3291) +- Skip changelog requirement when running tests for dependency updates (#3320) +- Display precipitation probability when it is 0% instead of blank/empty (#3345) +- [newsfeed] Suppress unsightly animation cases when there are 0 or 1 active news items (#3336) +- [newsfeed] Always compute the feed item URL using the same helper function (#3336) +- Ignore all custom css files (#3359) +- [newsfeed] Fix newsfeed stall issue introduced by #3336 (#3361) +- Changed `log.debug` to `log.log` in `app.js` where logLevel is not set because config is not loaded at this time (#3353) +- [calendar] deny fetch interval < 60000 and set 60000 in this case (prevent fetch loop failed) (#3382) +- added message in case where config.js is missing the module.export line PR #3383 +- Fixed an issue where recurring events could extend past their recurrence end date (#3393) +- Don't display any `npm WARN <....>` on install (#3399) +- [core] Moved suncalc dependency to production from dev, as it is used by clock module +- [compliments] Fix mirror not responding anymore when no compliments are to be shown (#3385) +- [core] Fixed mastermerge workflow (#3415) + +### Deleted + +- Unneeded file headers (#3358) +- Removed codecov.yaml + +## [2.26.0] - 2024-01-01 + +Thanks to: @bnitkin, @bugsounet, @dependabot, @jkriegshauser, @kaennchenstruggle, @KristjanESPERANTO and @Ybbet. + +Special thanks to @khassel, @rejas and @sdetweil for taking over most (if not all) of the work on this release as project collaborators. This version would not be there without their effort. Thank you guys! You are awesome! + +This release also marks the latest release by Michael Teeuw. For more info, please read the following post: [A New Chapter for MagicMirror: The Community Takes the Lead](https://forum.magicmirror.builders/topic/18329/a-new-chapter-for-magicmirror-the-community-takes-the-lead). ### Added +- Added update notification updater (for 3rd party modules) +- Added node 21 to the test matrix +- Added transform object to calendar:customEvents +- Added ESLint rules for jest (including jest/expect-expect and jest/no-done-callback) + +### Removed + +- Removed Codecov workflow (not working anymore, other workflow required) (#3107) +- Removed titleReplace from calendar, replaced + extended by customEvents (backward compatibility included) (#3249) +- Removed failing unit test (#3254) +- Removed some unused variables + +### Updated + +- Update electron to v27 and update other dependencies as well as github actions +- Update newsfeed: Use `html-to-text` instead of regex for transform description +- Review ESLint config (#3269) +- Update dependencies +- Clock module: optionally display current moon phase in addition to rise/set times +- electron is now per default started without gpu, if needed it must be enabled with new env var `ELECTRON_ENABLE_GPU=1` on startup (#3226) +- Replace prettier by stylistic in ESLint config to lint JavaScript (and disable some rules for `config/config.js*` files) +- Update node-ical to v0.17.1 and fix tests + +### Fixed + +- Avoid fade out/in on updateDom when many calendars are used +- Fix the option eventClass on customEvents. +- Fix yr API version in locationforecast and sunrise call (#3227) +- Fix cloneObject() function to respect RegExp (#3237) +- Fix newsfeed module for feeds using "a10:updated" tag (#3238) +- Fix issue template (#3167) +- Fix #3256 filter out bad results from rrule.between +- Fix calendar events sometimes not respecting deleted events (#3250) +- Fix electron loadurl locally on Windows when address "0.0.0.0" (#2550) +- Fix updatanotification (update_helper.js): catch error if response is not an JSON format (check PM2) +- Fix missing typeof in calendar module +- Fix style issues after prettier update +- Fix calendar test (#3291) by moving "Exdate check" from e2e to electron to run on a Thursday +- Fix calendar config params `fetchInterval` and `excludedEvents` were never used from single calendar config (#3297) +- Fix MM_PORT variable not used in electron and allow full path for MM_CONFIG_FILE variable (#3302) + +## [2.25.0] - 2023-10-01 + +Thanks to: @bugsounet, @dgoth, @dependabot, @kenzal, @Knapoc, @KristjanESPERANTO, @martingron, @NolanKingdon, @Paranoid93, @TeddyStarinvest and @Ybbet. + +Special thanks to @khassel, @rejas and @sdetweil for taking over most (if not all) of the work on this release as project collaborators. This version would not be there without their effort. Thank you guys! You are awesome! + +> ⚠️ This release needs nodejs version >= `v18`, older releases have reached end of life and will not work! + +### Added + +- Added UV Index support to OpenWeatherMap +- Added 'hideDuplicates' flag to the calendar module +- Added `allowOverrideNotification` to weather module to enable sending current weather objects with the `CURRENT_WEATHER_OVERRIDE` notification to supplement/replace the current weather displayed +- Added optional AnimateCSS animate for `hide()`, `show()`, `updateDom()` +- Added AnimateIn and animateOut in module config definition +- Apply AnimateIn rules on the first start +- Added automatic client page reload when server was restarted by setting `reloadAfterServerRestart: true` in `config.js`, per default `false` (#3105) +- Added eventClass option for customEvents on the default calendar +- Added AnimateCSS integration in tests suite (#3206) +- Added npm dependabot [Reserved to developer] (#3210) +- Added improved logging for calendar (#3110) + +### Removed + +- **Breaking Change**: Removed `digest` authentication method from calendar module (which was already broken since release `2.15.0`) + +### Updated + +- Update roboto fonts to version v5 +- Update issue template +- Update dev/dependencies incl. electron to v26 +- Replace pretty-quick by lint-staged () +- Update engine node >=18. v16 reached its end of life. (#3170) +- Update typescript definition for modules +- Cleaned up nunjuck templates +- Replace `node-fetch` with internal fetch (#2649) and remove `digest-fetch` +- Update the French translation according to the English file. +- Update dependabot incl. vendor/fonts (monthly check) +- Renew `package-lock.json` for release + +### Fixed + +- Fix engine check on npm install (#3135) +- Fix undefined formatTime method in clock module (#3143) +- Fix clientonly startup fails after async added (#3151) +- Fix electron width/height when using xrandr under bullseye +- Fix time issue with certain recurring events in calendar module +- Fix ipWhiteList test (#3179) +- Fix newsfeed: Convert HTML entities, codes and tag in description (#3191) +- Respect width/height (no fullscreen) if set in electronOptions (together with `fullscreen: false`) in `config.js` (#3174) +- Fix: AnimateCSS merge hide() and show() animated css class when we do multiple call +- Fix `Uncaught SyntaxError: Identifier 'getCorsUrl' has already been declared (at utils.js:1:1)` when using `clock` and `weather` module (#3204) +- Fix overriding `config.js` when running tests (#3201) +- Fix issue in weathergov provider with probability of precipitation not showing up on hourly or daily forecast +- Fix yr weather provider after changes in yr API (#3189) + +## [2.24.0] - 2023-07-01 + +Thanks to: @angeldeejay, @bugsounet, @buxxi, @CarJem, @dariom, @DaveChild, @dWoolridge, @eddiehung, @grenagit, @Hirschberger, @ismarslomic, @JakeBinney, @KristjanESPERANTO, @MagMar94, @naveensrinivasan, @nfogal, @oscarb, @OWL4C, @psieg, @rajniszp, @retroflex, @SkySails and @tomzt + +Special thanks to @khassel, @rejas and @sdetweil for taking over most (if not all) of the work on this release as project collaborators. This version would not be there without their effort. Thank you guys! You are awesome! + +### Added + +- Added UV Index to hourly and current Weather, with support for Openmeteo +- Added tests for serveronly +- Set Timezone `Europe/Berlin` in unit tests (needed for new formatTime tests) +- Added no-param-reassign eslint rule and fix warnings +- [updatenotification] Added `sendUpdatesNotifications` feature. Broadcast update with `UPDATES` notification to other modules +- [updatenotification] Allow force scanning with `SCAN_UPDATES` notification from other modules +- Added per-calendar fetchInterval + +### Removed + +- Removed unneeded (and unwanted) '.' after the year in calendar repeatingCountTitle (#2896, second attempt ...) + +### Updated + +- Added support for precipitation probability with openmeteo weather-provider +- Update electron to v25.2 and other dependencies +- Use node v20 in github workflow (replacing v14) +- Refactor formatTime into common util function for default modules +- Refactor some calendar methods into own class and added tests for them +- Split install and run commands in github actions +- Changed `fetchInterval` of calendar in `config.js.sample` to 7 days so we not to request example calendar too frequently +- Changed default calendar fetchInterval to one hour +- Changed calendar url in sample config + +### Fixed + +- Fix envcanada hourly forecast time (#3080) +- Fix electron not running under windows after async changes (#3083) +- Fix style issues after eslint-plugin-jsdoc update +- Fix don't filter out ongoing full day events (#3095) +- Fix date not shown when clock in analog mode (#3100) +- Fix envcanada today percentage-of-precipitation (#3106) +- Fix updatenotification where no branch is checked out but e.g. a version tag (#3130) + +## [2.23.0] - 2023-04-04 + +Thanks to: @angeldeejay, @buxxi, @CarJem, @dariom, @DaveChild, @dWoolridge, @grenagit, @Hirschberger, @KristjanESPERANTO, @MagMar94, @naveensrinivasan, @nfogal, @psieg, @rajniszp, @retroflex, @SkySails and @tomzt. + +Special thanks to @khassel, @rejas and @sdetweil for taking over most (if not all) of the work on this release as project collaborators. This version would not be there without their effort. Thank you guys! You are awesome! + +### Added + +- Added increments for hourly forecasts in weather module (#2996) +- Added tests for hourly weather forecast +- Added possibility to ignore MagicMirror repo in updatenotification module +- Added Pirate Weather as new weather-provider (#3005) +- Added possibility to use your own templates in Alert module +- Added error message if `.js` file is missing in module folder to get a hint in the logs (#2403) +- Added possibility to use environment variables in `config.js` (#1756) +- Added option `pastDaysCount` to default calendar module to control of how many days past events should be displayed +- Added thai language to alert module +- Added option `sendNotifications` in clock module (#3056) +- Added tests for some weather utils + +### Removed + +- Removed darksky weather-provider +- Removed unneeded (and unwanted) '.' after the year in calendar repeatingCountTitle (#2896) + +### Updated + +- Use develop as target branch for dependabot +- Update issue template, contributing doc and sample config +- The weather modules clearly separates precipitation amount and probability (risk of rain/snow) + - This requires all providers that only supports probability to change the config from `showPrecipitationAmount` to `showPrecipitationProbability`. +- Update tests for weather and calendar module +- Changed updatenotification module for MagicMirror repo only: Send only notifications for `master` if there is a tag on a newer commit +- Update dates in Calendar widgets every minute +- Cleanup jest coverage for patches +- Update `stylelint` dependencies, switch to `stylelint-config-standard` and handle `stylelint` issues, update `main.css` matching new rules +- Update Eslint config, add new rule and handle issue +- Convert lots of callbacks to async/await +- Revise require imports (#3071 and #3072) +- Use `config.js-old` instead of file with timestamp suffix when backing up config with a `config.template` in use (#3104) + +### Fixed + +- Fix wrong day labels in envcanada forecast (#2987) +- Fix for missing default class name prefix for customEvents in calendar +- Fix electron flashing white screen on startup (#1919) +- Fix weathergov provider hourly forecast (#3008) +- Fix message display with HTML code into alert module (#2828) +- Fix typo in french translation +- Yr wind direction is no longer inverted +- Fix async node_helper stopping electron start (#2487) +- The wind direction arrow now points in the direction the wind is flowing, not into the wind (#3019) +- Fix precipitation css styles and rounding value +- Fix wrong vertical alignment of calendar title column when wrapEvents is true (#3053) +- Fix empty news feed stopping the reload forever +- Fix e2e tests (failed after async changes) by running calendar and newsfeed tests last +- Lint: Use template literals instead of string concatenation +- Fix default alert module to render HTML for title and message +- Fix Open-Meteo wind speed units + +## [2.22.0] - 2023-01-01 + +Thanks to: @angeldeejay, @buxxi, @dariom, @dWoolridge, @KristjanESPERANTO, @MagMar94, @naveensrinivasan, @retroflex, @SkySails and @Tom. + +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 new calendar options for colored entries and improved styling (#3033) - Added test for remoteFile option in compliments module -- Added hourlyWeather functionality to Weather.gov weather provider -- Removed weatherEndpoint definition from weathergov.js (not used) +- Added hourlyWeather functionality to Weather.gov weather-provider - Added css class names "today" and "tomorrow" for default calendar - Added Collaboration.md - Added new github action for dependency review (#2862) -- Added Yr as a weather provider +- Added a WeatherProvider for Open-Meteo +- Added Yr as a weather-provider - Added config options "ignoreXOriginHeader" and "ignoreContentSecurityPolicy" +- Added thai language +- Added workflow rule to make sure PRs are based against develop ### Removed -- Removed usage of internal fetch function of node until it is more stable. +- Removed usage of internal fetch function of node until it is more stable +- Removed weatherEndpoint definition from weathergov.js (not used) ### Updated @@ -34,20 +326,26 @@ Special thanks to: @rejas, @sdetweil, @MagMar94 - 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 fetch instead of XMLHttpRequest in weather-provider (#2935) + - Reworked how weather-providers handle units (#2849) - Use unix() method for parsing times, fix suntimes on the way (#2950) - Refactor conversion functions into utils class (#2958) -- The `cors`-method in `server.js` now supports sending and recieving HTTP headers. +- The `cors`-method in `server.js` now supports sending and receiving HTTP headers +- Replace `…` by `…` +- Cleanup compliments module +- Updated dependencies including electron to v22 (#2903) ### Fixed -- Correctly show apparent temperature in SMHI weather provider +- 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 @@ -58,7 +356,7 @@ Special thanks to: @BKeyport, @buxxi, @davide125, @khassel, @kolbyjack, @krukle, - 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"`. -- Added 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 @@ -114,7 +412,7 @@ Special thanks to the following contributors: @10bias, @CFenner, @JHWelch, @k1rd - Added test for new weather forecast `absoluteDates` property. - The modules get a class hidden added/removed if they get hidden/shown which will also toggle pointer-events. - Added new config option `showTitleAsUrl` to newsfeed module. If set, the displayed title is a link to the article which is useful when running in a browser and you want to read this article. -- Added internal cors proxy to get weather providers working without public proxies (fixes #2714). The new url `http(s)://address:port/cors?url=https://whatever-to-proxy` can be used in other modules too. +- Added internal cors proxy to get weather-providers working without public proxies (fixes #2714). The new url `http(s)://address:port/cors?url=https://whatever-to-proxy` can be used in other modules too. - Added a WeatherProvider for Weatherflow. - Added new env var `ELECTRON_DISABLE_GPU` which disable gpu under electron if set (fixes #2831). - Added missing Czech translations. @@ -208,7 +506,7 @@ Special thanks to the following contributors: @apiontek, @eouia, @jupadin, @khas - Updated jsdocs and print warnings during testing too. - Updated weathergov provider to try fetching not just current, but also foreacst, when API URLs available. - Refactored clock layout. -- Refactored methods from weatherproviders into weatherobject (isDaytime, updateSunTime). +- Refactored methods from weather-providers into weatherobject (isDaytime, updateSunTime). - Use of `logger.js` in jest tests. - Run prettier over all relevant files. - Move tests needing electron in new category `electron`, use `server only` mode in `e2e` tests. @@ -306,7 +604,7 @@ Special thanks to the following contributors: @EdgardosReis, @MystaraTheGreat, @ - Code cleanup for FEELS like and added {DEGREE} placeholder for FEELSLIKE for each language. - Converted newsfeed module to use templates. - Updated documentation and help screen about invalid config files. -- Moving weather provider specific code and configuration into each provider and making hourly part of the interface. +- Moving weather-provider specific code and configuration into each provider and making hourly part of the interface. - Bump electron to v11 and enable contextIsolation. - Don't update the DOM when a module is not displayed. - Cleaned up jsdoc and tests. @@ -388,7 +686,7 @@ Special thanks to the following contributors: @Alvinger, @AndyPoms, @ashishtank, - Rename Greek translation to correct ISO 639-1 alpha-2 code (gr > el). (#2155) - Add a space after icons of sunrise and sunset. (#2169) - Fix calendar when no DTEND record found in event, startDate overlay when endDate set. (#2177) -- Fix windspeed conversion error in ukmetoffice weather provider. (#2189) +- Fix windspeed conversion error in ukmetoffice weather-provider. (#2189) - Fix console.debug not having timestamps. (#2199) - Fix calendar full day event east of UTC start time. (#2200) - Fix non-fullday recurring rule processing. (#2216) @@ -433,12 +731,12 @@ Special thanks to the following contributors: @bryanzzhu, @bugsounet, @chamakura ### Fixed - Fix backward compatibility issues for Safari < 11. -- Fix the use of "maxNumberOfDays" in the module "weatherforecast depending on the endpoint (forecast/daily or forecast)". [#2018](https://github.com/MichMich/MagicMirror/issues/2018) -- Fix calendar display. Account for current timezone. [#2068](https://github.com/MichMich/MagicMirror/issues/2068) +- Fix the use of "maxNumberOfDays" in the module "weatherforecast depending on the endpoint (forecast/daily or forecast)". [#2018](https://github.com/MagicMirrorOrg/MagicMirror/issues/2018) +- Fix calendar display. Account for current timezone. [#2068](https://github.com/MagicMirrorOrg/MagicMirror/issues/2068) - Fix logLevel being set before loading config. -- Fix incorrect namespace links in svg clockfaces. [#2072](https://github.com/MichMich/MagicMirror/issues/2072) -- Fix weather/providers/weathergov for API guidelines. [#2045](https://github.com/MichMich/MagicMirror/issues/2045) -- Fix "undefined" in weather modules header. [#1985](https://github.com/MichMich/MagicMirror/issues/1985) +- Fix incorrect namespace links in svg clockfaces. [#2072](https://github.com/MagicMirrorOrg/MagicMirror/issues/2072) +- Fix weather/providers/weathergov for API guidelines. [#2045](https://github.com/MagicMirrorOrg/MagicMirror/issues/2045) +- Fix "undefined" in weather modules header. [#1985](https://github.com/MagicMirrorOrg/MagicMirror/issues/1985) - Fix #2110, #2111, #2118: Recurring full day events should not use timezone adjustment. Just compare month/day. ## [2.12.0] - 2020-07-01 @@ -472,14 +770,14 @@ Special thanks to the following contributors: @AndreKoepke, @andrezibaia, @bryan ### Fixed -- The broken modules due to Socket.io change from last release. [#1973](https://github.com/MichMich/MagicMirror/issues/1973) -- Add backward compatibility for old module code in socketclient.js. [#1973](https://github.com/MichMich/MagicMirror/issues/1973) -- Support multiple instances of calendar module with different config. [#1109](https://github.com/MichMich/MagicMirror/issues/1109) -- Fix the use of "maxNumberOfDays" in the module "weatherforecast". [#2018](https://github.com/MichMich/MagicMirror/issues/2018) -- Throw error when check_config fails. [#1928](https://github.com/MichMich/MagicMirror/issues/1928) -- Bug fix related to 'maxEntries' not displaying Calendar events. [#2050](https://github.com/MichMich/MagicMirror/issues/2050) -- Updated ical library to the latest version. [#1926](https://github.com/MichMich/MagicMirror/issues/1926) -- Fix config check after merge of prettier [#2109](https://github.com/MichMich/MagicMirror/issues/2109) +- The broken modules due to Socket.io change from last release. [#1973](https://github.com/MagicMirrorOrg/MagicMirror/issues/1973) +- Add backward compatibility for old module code in socketclient.js. [#1973](https://github.com/MagicMirrorOrg/MagicMirror/issues/1973) +- Support multiple instances of calendar module with different config. [#1109](https://github.com/MagicMirrorOrg/MagicMirror/issues/1109) +- Fix the use of "maxNumberOfDays" in the module "weatherforecast". [#2018](https://github.com/MagicMirrorOrg/MagicMirror/issues/2018) +- Throw error when check_config fails. [#1928](https://github.com/MagicMirrorOrg/MagicMirror/issues/1928) +- Bug fix related to 'maxEntries' not displaying Calendar events. [#2050](https://github.com/MagicMirrorOrg/MagicMirror/issues/2050) +- Updated ical library to the latest version. [#1926](https://github.com/MagicMirrorOrg/MagicMirror/issues/1926) +- Fix config check after merge of prettier [#2109](https://github.com/MagicMirrorOrg/MagicMirror/issues/2109) ## [2.11.0] - 2020-04-01 @@ -487,7 +785,7 @@ Special thanks to the following contributors: @AndreKoepke, @andrezibaia, @bryan In the past years the project has grown a lot. This came with a huge downside: poor maintainability. If I let the project continue the way it was, it would eventually crash and burn. More important: I would completely lose the drive and interest to continue the project. Because of this the decision was made to simplify the core by removing all side features like automatic installers and support for exotic platforms. This release (2.11.0) is the first real release that will reflect (parts) of these changes. As a result of this, some things might break. So before you continue make sure to backup your installation. Your config, your modules or better yet: your full MagicMirror² folder. In other words: update at your own risk. -For more information regarding this major change, please check issue [#1860](https://github.com/MichMich/MagicMirror/issues/1860). +For more information regarding this major change, please check issue [#1860](https://github.com/MagicMirrorOrg/MagicMirror/issues/1860). ### Deleted @@ -517,8 +815,8 @@ For more information regarding this major change, please check issue [#1860](htt - Fix calendar time offset for recurring events crossing Daylight Savings Time (ISSUE #1798) - Fix regression in currentweather module causing 'undefined' to show up when config.hideTemp is false - Fix FEELS translation for Croatian -- Fixed weather tests [#1840](https://github.com/MichMich/MagicMirror/issues/1840) -- Fixed Socket.io can't be used with Reverse Proxy in serveronly mode [#1934](https://github.com/MichMich/MagicMirror/issues/1934) +- Fixed weather tests [#1840](https://github.com/MagicMirrorOrg/MagicMirror/issues/1840) +- Fixed Socket.io can't be used with Reverse Proxy in serveronly mode [#1934](https://github.com/MagicMirrorOrg/MagicMirror/issues/1934) - Fix update checking skipping 3rd party modules the first time ### Changed @@ -586,14 +884,14 @@ Special thanks to @sdetweil for all his great contributions! - Updatenotification module: Display update notification for a limited (configurable) time. - Enabled e2e/vendor_spec.js tests. -- The css/custom.css will be renamed after the next release. We've added into `run-start.sh` an instruction by GIT to ignore with `--skip-worktree` and `rm --cached`. [#1540](https://github.com/MichMich/MagicMirror/issues/1540) +- The css/custom.css will be renamed after the next release. We've added into `run-start.sh` an instruction by GIT to ignore with `--skip-worktree` and `rm --cached`. [#1540](https://github.com/MagicMirrorOrg/MagicMirror/issues/1540) - Disable sending of notification CLOCK_SECOND when displaySeconds is false. ### Fixed - Updatenotification module: Properly handle race conditions, prevent crash. - Send `NEWS_FEED` notification also for the first news messages which are shown. -- Fixed issue where weather module would not refresh data after a network or API outage. [#1722](https://github.com/MichMich/MagicMirror/issues/1722) +- Fixed issue where weather module would not refresh data after a network or API outage. [#1722](https://github.com/MagicMirrorOrg/MagicMirror/issues/1722) - Fixed weatherforecast module not displaying rain amount on fallback endpoint. - Notifications CLOCK_SECOND & CLOCK_MINUTE being from startup instead of matched against the clock and avoid drifting. @@ -608,7 +906,7 @@ Special thanks to @sdetweil for all his great contributions! - Russian translation for “Feels” - Calendar module: added `nextDaysRelative` config option - Add `broadcastPastEvents` config option for calendars to include events from the past `maximumNumberOfDays` in event broadcasts -- Added feature to broadcast news feed items `NEWS_FEED` and updated news items `NEWS_FEED_UPDATED` in default [newsfeed](https://github.com/MichMich/MagicMirror/tree/develop/modules/default/newsfeed) module (when news is updated) with documented default and `config.js` options in [README.md](https://github.com/MichMich/MagicMirror/blob/develop/modules/default/newsfeed/README.md) +- Added feature to broadcast news feed items `NEWS_FEED` and updated news items `NEWS_FEED_UPDATED` in default [newsfeed](https://github.com/MagicMirrorOrg/MagicMirror/tree/develop/modules/default/newsfeed) module (when news is updated) with documented default and `config.js` options in [README.md](https://github.com/MagicMirrorOrg/MagicMirror/blob/develop/modules/default/newsfeed/README.md) - Added notifications to default `clock` module broadcasting `CLOCK_SECOND` and `CLOCK_MINUTE` for the respective time elapsed. - Added UK Met Office Datapoint feed as a provider in the default weather module. - Added new provider class @@ -617,7 +915,7 @@ Special thanks to @sdetweil for all his great contributions! - Use Feels Like temp from feed if present - Optionally display probability of precipitation (PoP) in current weather (UK Met Office data) - Automatically try to fix eslint errors by passing `--fix` option to it -- Added sunrise and sunset times to weathergov weather provider [#1705](https://github.com/MichMich/MagicMirror/issues/1705) +- Added sunrise and sunset times to weathergov weather-provider [#1705](https://github.com/MagicMirrorOrg/MagicMirror/issues/1705) - Added "useLocationAsHeader" to display "location" in `config.js` as header when location name is not returned - Added to `newsfeed.js`: in order to design the news article better with css, three more class-names were introduced: newsfeed-desc, newsfeed-desc, newsfeed-desc @@ -626,18 +924,18 @@ Special thanks to @sdetweil for all his great contributions! - English translation for "Feels" to "Feels like" - Fixed the example calendar url in `config.js.sample` - Updated `ical.js` to solve various calendar issues. -- Updated weather city list url [#1676](https://github.com/MichMich/MagicMirror/issues/1676) +- Updated weather city list url [#1676](https://github.com/MagicMirrorOrg/MagicMirror/issues/1676) - Only update clock once per minute when seconds aren't shown -- Updated weatherprovider documentation. +- Updated weather-provider documentation. ### Fixed - Fixed uncaught exception, race condition on module update -- Fixed issue [#1696](https://github.com/MichMich/MagicMirror/issues/1696), some ical files start date to not parse to date type +- Fixed issue [#1696](https://github.com/MagicMirrorOrg/MagicMirror/issues/1696), some ical files start date to not parse to date type - Allowance HTML5 autoplay-policy (policy is changed from Chrome 66 updates) - Handle SIGTERM messages - Fixes sliceMultiDayEvents so it respects maximumNumberOfDays -- Minor types in default NewsFeed [README.md](https://github.com/MichMich/MagicMirror/blob/develop/modules/default/newsfeed/README.md) +- Minor types in default NewsFeed [README.md](https://github.com/MagicMirrorOrg/MagicMirror/blob/develop/modules/default/newsfeed/README.md) - Fix typos and small syntax errors, cleanup dependencies, remove multiple-empty-lines, add semi-rule - Fixed issues with calendar not displaying one-time changes to repeating events - Updated the fetchedLocationName variable in currentweather.js so that city shows up in the header @@ -675,42 +973,42 @@ Fixed `package.json` version number. ### Updated -- Bumped the Electron dependency to v3.0.13 to support the most recent Raspbian. [#1500](https://github.com/MichMich/MagicMirror/issues/1500) +- Bumped the Electron dependency to v3.0.13 to support the most recent Raspbian. [#1500](https://github.com/MagicMirrorOrg/MagicMirror/issues/1500) - Updated modernizr code in alert module, fixed a small typo there too - More verbose error message on console if the config is malformed - Updated installer script to install Node.js version 10.x ### Fixed -- Fixed temperature displays in currentweather and weatherforecast modules [#1503](https://github.com/MichMich/MagicMirror/issues/1503), [#1511](https://github.com/MichMich/MagicMirror/issues/1511). -- Fixed unhandled error on bad git data in updatenotification module [#1285](https://github.com/MichMich/MagicMirror/issues/1285). -- Weather forecast now works with openweathermap in new weather module. Daily data are displayed, see issue [#1504](https://github.com/MichMich/MagicMirror/issues/1504). +- Fixed temperature displays in currentweather and weatherforecast modules [#1503](https://github.com/MagicMirrorOrg/MagicMirror/issues/1503), [#1511](https://github.com/MagicMirrorOrg/MagicMirror/issues/1511). +- Fixed unhandled error on bad git data in updatenotification module [#1285](https://github.com/MagicMirrorOrg/MagicMirror/issues/1285). +- Weather forecast now works with openweathermap in new weather module. Daily data are displayed, see issue [#1504](https://github.com/MagicMirrorOrg/MagicMirror/issues/1504). - Fixed analogue clock border display issue where non-black backgrounds used (previous fix for issue 611) -- Fixed compatibility issues caused when modules request different versions of Font Awesome, see issue [#1522](https://github.com/MichMich/MagicMirror/issues/1522). MagicMirror² now uses [Font Awesome 5 with v4 shims included for backwards compatibility](https://fontawesome.com/how-to-use/on-the-web/setup/upgrading-from-version-4#shims). +- Fixed compatibility issues caused when modules request different versions of Font Awesome, see issue [#1522](https://github.com/MagicMirrorOrg/MagicMirror/issues/1522). MagicMirror² now uses [Font Awesome 5 with v4 shims included for backwards compatibility](https://fontawesome.com/how-to-use/on-the-web/setup/upgrading-from-version-4#shims). - Installation script problems with raspbian -- Calendar: only show repeating count if the event is actually repeating [#1534](https://github.com/MichMich/MagicMirror/pull/1534) +- Calendar: only show repeating count if the event is actually repeating [#1534](https://github.com/MagicMirrorOrg/MagicMirror/pull/1534) - Calendar: Fix exdate handling when multiple values are specified (comma separated) -- Calendar: Fix relative date handling for fulldate events, calculate difference always from start of day [#1572](https://github.com/MichMich/MagicMirror/issues/1572) +- Calendar: Fix relative date handling for fulldate events, calculate difference always from start of day [#1572](https://github.com/MagicMirrorOrg/MagicMirror/issues/1572) - Fix null dereference in moduleNeedsUpdate when the module isn't visible - Calendar: Fixed event end times by setting default calendarEndTime to "LT" (Local time format). [#1479] -- Calendar: Fixed missing calendar fetchers after server process restarts [#1589](https://github.com/MichMich/MagicMirror/issues/1589) +- Calendar: Fixed missing calendar fetchers after server process restarts [#1589](https://github.com/MagicMirrorOrg/MagicMirror/issues/1589) - Notification: fixed background color (was white text on white background) - Use getHeader instead of data.header when creating the DOM so overwriting the function also propagates into it - Fix documentation of `useKMPHwind` option in currentweather ### New weather module -- Fixed weather forecast table display [#1499](https://github.com/MichMich/MagicMirror/issues/1499). +- Fixed weather forecast table display [#1499](https://github.com/MagicMirrorOrg/MagicMirror/issues/1499). - Dimmed loading indicator for weather forecast. -- Implemented config option `decimalSymbol` [#1499](https://github.com/MichMich/MagicMirror/issues/1499). -- Aligned indoor values in current weather vertical [#1499](https://github.com/MichMich/MagicMirror/issues/1499). +- Implemented config option `decimalSymbol` [#1499](https://github.com/MagicMirrorOrg/MagicMirror/issues/1499). +- Aligned indoor values in current weather vertical [#1499](https://github.com/MagicMirrorOrg/MagicMirror/issues/1499). - Added humidity support to nunjuck unit filter. -- Do not display degree symbol for temperature in Kelvin [#1503](https://github.com/MichMich/MagicMirror/issues/1503). -- Weather forecast now works with openweathermap for both, `/forecast` and `/forecast/daily`, in new weather module. If you use the `/forecast`-weatherEndpoint, the hourly data are converted to daily data, see issues [#1504](https://github.com/MichMich/MagicMirror/issues/1504), [#1513](https://github.com/MichMich/MagicMirror/issues/1513). -- Added fade, fadePoint and maxNumberOfDays properties to the forecast mode [#1516](https://github.com/MichMich/MagicMirror/issues/1516) -- Fixed Loading string and decimalSymbol string replace [#1538](https://github.com/MichMich/MagicMirror/issues/1538) -- Show Snow amounts in new weather module [#1545](https://github.com/MichMich/MagicMirror/issues/1545) -- Added weather.gov as a new weather provider for US locations +- Do not display degree symbol for temperature in Kelvin [#1503](https://github.com/MagicMirrorOrg/MagicMirror/issues/1503). +- Weather forecast now works with openweathermap for both, `/forecast` and `/forecast/daily`, in new weather module. If you use the `/forecast`-weatherEndpoint, the hourly data are converted to daily data, see issues [#1504](https://github.com/MagicMirrorOrg/MagicMirror/issues/1504), [#1513](https://github.com/MagicMirrorOrg/MagicMirror/issues/1513). +- Added fade, fadePoint and maxNumberOfDays properties to the forecast mode [#1516](https://github.com/MagicMirrorOrg/MagicMirror/issues/1516) +- Fixed Loading string and decimalSymbol string replace [#1538](https://github.com/MagicMirrorOrg/MagicMirror/issues/1538) +- Show Snow amounts in new weather module [#1545](https://github.com/MagicMirrorOrg/MagicMirror/issues/1545) +- Added weather.gov as a new weather-provider for US locations ## [2.6.0] - 2019-01-01 @@ -734,7 +1032,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Screenshot for the weather forecast module - Portuguese translation for "Feels" - Croatian translation -- Fading for dateheaders timeFormat in Calendar [#1464](https://github.com/MichMich/MagicMirror/issues/1464) +- Fading for dateheaders timeFormat in Calendar [#1464](https://github.com/MagicMirrorOrg/MagicMirror/issues/1464) - Documentation for the existing `scale` option in the Weather Forecast module. ### Fixed @@ -743,7 +1041,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Fixed Polish translation for Single Update Info - Ignore entries with unparseable details in the calendar module - Bug showing FullDayEvents one day too long in calendar fixed -- Bug in newsfeed when `removeStartTags` is used on the description [#1478](https://github.com/MichMich/MagicMirror/issues/1478) +- Bug in newsfeed when `removeStartTags` is used on the description [#1478](https://github.com/MagicMirrorOrg/MagicMirror/issues/1478) ### Updated @@ -776,7 +1074,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Fixed mixup between german and spanish translation for newsfeed. - Fixed close dates to be absolute, if no configured in the config.js - module Calendar - Fixed the updatenotification module message about new commits in the repository, so they can be correctly localized in singular and plural form. -- Fix for weatherforecast rainfall rounding [#1374](https://github.com/MichMich/MagicMirror/issues/1374) +- Fix for weatherforecast rainfall rounding [#1374](https://github.com/MagicMirrorOrg/MagicMirror/issues/1374) - Fix calendar parsing issue for Midori on RasperryPi Zero w, related to issue #694. - Fix weather city ID link in sample config - Fixed issue with clientonly not updating with IP address and port provided on command line. @@ -798,7 +1096,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we ## [2.4.0] - 2018-07-01 -⚠️ **Warning:** This release includes an updated version of Electron. This requires a Raspberry Pi configuration change to allow the best performance and prevent the CPU from overheating. Please read the information on the [MagicMirror² Wiki](https://github.com/michmich/magicmirror/wiki/configuring-the-raspberry-pi#enable-the-open-gl-driver-to-decrease-electrons-cpu-usage). +⚠️ **Warning:** This release includes an updated version of Electron. This requires a Raspberry Pi configuration change to allow the best performance and prevent the CPU from overheating. Please read the information on the [MagicMirror² Wiki](https://github.com/MagicMirrorOrg/MagicMirror/wiki/configuring-the-raspberry-pi#enable-the-open-gl-driver-to-decrease-electrons-cpu-usage). ℹ️ **Note:** This update uses new dependencies. Please update using the following command: `git pull && npm install` @@ -820,20 +1118,20 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Upgrade to Electron 2.0.0. - Remove yarn-or-npm which breaks production builds. -- Invoke module suspend even if no dom content. [#1308](https://github.com/MichMich/MagicMirror/issues/1308) +- Invoke module suspend even if no dom content. [#1308](https://github.com/MagicMirrorOrg/MagicMirror/issues/1308) ### Fixed -- Fixed issue where wind chill could not be displayed in Fahrenheit. [#1247](https://github.com/MichMich/MagicMirror/issues/1247) -- Fixed issues where a module crashes when it tries to dismiss a non existing alert. [#1240](https://github.com/MichMich/MagicMirror/issues/1240) +- Fixed issue where wind chill could not be displayed in Fahrenheit. [#1247](https://github.com/MagicMirrorOrg/MagicMirror/issues/1247) +- Fixed issues where a module crashes when it tries to dismiss a non existing alert. [#1240](https://github.com/MagicMirrorOrg/MagicMirror/issues/1240) - In default module currentWeather/currentWeather.js line 296, 300, self.config.animationSpeed can not be found because the notificationReceived function does not have "self" variable. - Fixed browser-side code to work on the Midori browser. -- Fixed issue where heat index was reporting incorrect values in Celsius and Fahrenheit. [#1263](https://github.com/MichMich/MagicMirror/issues/1263) +- Fixed issue where heat index was reporting incorrect values in Celsius and Fahrenheit. [#1263](https://github.com/MagicMirrorOrg/MagicMirror/issues/1263) - Fixed weatherforecast to use dt_txt field instead of dt to handle timezones better -- Newsfeed now remembers to show the description when `"ARTICLE_LESS_DETAILS"` is called if the user wants to always show the description. [#1282](https://github.com/MichMich/MagicMirror/issues/1282) +- Newsfeed now remembers to show the description when `"ARTICLE_LESS_DETAILS"` is called if the user wants to always show the description. [#1282](https://github.com/MagicMirrorOrg/MagicMirror/issues/1282) - `clientonly/*.js` is now linted, and one linting error is fixed - Fix issue #1196 by changing underscore to hyphen in locale id, in align with momentjs. -- Fixed issue where heat index and wind chill were reporting incorrect values in Kelvin. [#1263](https://github.com/MichMich/MagicMirror/issues/1263) +- Fixed issue where heat index and wind chill were reporting incorrect values in Kelvin. [#1263](https://github.com/MagicMirrorOrg/MagicMirror/issues/1263) ### Updated @@ -845,7 +1143,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we ### Fixed -- Downgrade electron to 1.4.15 to solve the black screen issue.[#1243](https://github.com/MichMich/MagicMirror/issues/1243) +- Downgrade electron to 1.4.15 to solve the black screen issue.[#1243](https://github.com/MagicMirrorOrg/MagicMirror/issues/1243) ## [2.3.0] - 2018-04-01 @@ -971,8 +1269,8 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we ### Changed -- Revert Docker related changes in favor of [docker-MagicMirror](https://github.com/bastilimbach/docker-MagicMirror). All Docker images are outsourced. ([#856](https://github.com/MichMich/MagicMirror/pull/856)) -- Change Docker base image (Debian + Node) to an arm based distro (AlpineARM + Node) ([#846](https://github.com/MichMich/MagicMirror/pull/846)) +- Revert Docker related changes in favor of [docker-MagicMirror](https://github.com/bastilimbach/docker-MagicMirror). All Docker images are outsourced. ([#856](https://github.com/MagicMirrorOrg/MagicMirror/pull/856)) +- Change Docker base image (Debian + Node) to an arm based distro (AlpineARM + Node) ([#846](https://github.com/MagicMirrorOrg/MagicMirror/pull/846)) - Fix the dockerfile to have it running from the first time. ### Added @@ -1019,7 +1317,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Add `anytime` group for Compliments module. - Compliments module can use remoteFile without default daytime arrays defined. - Installer: Use init config.js from config.js.sample. -- Switched out `rrule` package for `rrule-alt` and fixes in `ical.js` in order to fix calendar issues. ([#565](https://github.com/MichMich/MagicMirror/issues/565)) +- Switched out `rrule` package for `rrule-alt` and fixes in `ical.js` in order to fix calendar issues. ([#565](https://github.com/MagicMirrorOrg/MagicMirror/issues/565)) - Make mouse events pass through the region fullscreen_above to modules below. - Scaled the splash screen down to make it a bit more subtle. - Replace HTML tables with markdown tables in README files. @@ -1032,7 +1330,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we ### Added -- Added Docker support (Pull Request [#673](https://github.com/MichMich/MagicMirror/pull/673)). +- Added Docker support (Pull Request [#673](https://github.com/MagicMirrorOrg/MagicMirror/pull/673)). - Calendar-specific support for `maximumEntries`, and `maximumNumberOfDays`. - Add loaded function to modules, providing an async callback. - Made default newsfeed module aware of gesture events from [MMM-Gestures](https://github.com/thobach/MMM-Gestures) @@ -1078,7 +1376,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Updated .gitignore to not ignore default modules folder. - Remove white flash on boot up. - Added `update` in Raspberry Pi installation script. -- Fix an issue where the analog clock looked scrambled. ([#611](https://github.com/MichMich/MagicMirror/issues/611)) +- Fix an issue where the analog clock looked scrambled. ([#611](https://github.com/MagicMirrorOrg/MagicMirror/issues/611)) - If units are set to imperial, the showRainAmount option of weatherforecast will show the correct unit. - Module currentWeather: check if temperature received from api is defined. - Fix an issue with module hidden status changing to `true` although lock string prevented showing it. @@ -1095,18 +1393,18 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we - Finnish translation. - Danish translation. - Turkish translation. -- Option to limit access to certain IP addresses based on the value of `ipWhitelist` in the `config.js`, default is access from localhost only (Issue [#456](https://github.com/MichMich/MagicMirror/issues/456)). +- Option to limit access to certain IP addresses based on the value of `ipWhitelist` in the `config.js`, default is access from localhost only (Issue [#456](https://github.com/MagicMirrorOrg/MagicMirror/issues/456)). - Added ability to change the point of time when calendar events get relative. - Add Splash screen on boot. - Add option to show humidity in currentWeather module. - Add VSCode IntelliSense support. -- Module API: Add Visibility locking to module system. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules#visibility-locking) for more information. -- Module API: Method to overwrite the module's header. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules#getheader) for more information. -- Module API: Option to define the minimum MagicMirror² version to run a module. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules#requiresversion) for more information. -- Calendar module now broadcasts the event list to all other modules using the notification system. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules/default/calendar) for more information. -- Possibility to use the calendar feed as the source for the weather (currentweather & weatherforecast) location data. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules/default/weatherforecast) for more information. +- Module API: Add Visibility locking to module system. [See documentation](https://github.com/MagicMirrorOrg/MagicMirror/tree/develop/modules#visibility-locking) for more information. +- Module API: Method to overwrite the module's header. [See documentation](https://github.com/MagicMirrorOrg/MagicMirror/tree/develop/modules#getheader) for more information. +- Module API: Option to define the minimum MagicMirror² version to run a module. [See documentation](https://github.com/MagicMirrorOrg/MagicMirror/tree/develop/modules#requiresversion) for more information. +- Calendar module now broadcasts the event list to all other modules using the notification system. [See documentation](https://github.com/MagicMirrorOrg/MagicMirror/tree/develop/modules/default/calendar) for more information. +- Possibility to use the calendar feed as the source for the weather (currentweather & weatherforecast) location data. [See documentation](https://github.com/MagicMirrorOrg/MagicMirror/tree/develop/modules/default/weatherforecast) for more information. - Added option to show rain amount in the weatherforecast default module -- Add module `updatenotification` to get an update whenever a new version is available. [See documentation](https://github.com/MichMich/MagicMirror/tree/develop/modules/default/updatenotification) for more information. +- Add module `updatenotification` to get an update whenever a new version is available. [See documentation](https://github.com/MagicMirrorOrg/MagicMirror/tree/develop/modules/default/updatenotification) for more information. - Add the ability to set timezone on the date display in the Clock Module - Ability to set date format in calendar module - Possibility to use currentweather for the compliments @@ -1176,11 +1474,11 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we ### Fixed - Prevent `getModules()` selectors from returning duplicate entries. -- Append endpoints of weather modules with `/` to retrieve the correct data. (Issue [#337](https://github.com/MichMich/MagicMirror/issues/337)) +- Append endpoints of weather modules with `/` to retrieve the correct data. (Issue [#337](https://github.com/MagicMirrorOrg/MagicMirror/issues/337)) - Corrected grammar in `module.js` from 'suspend' to 'suspended'. - Fixed openweathermap.org URL in config sample. - Prevent currentweather module from crashing when received data object is incorrect. -- Fix issue where translation loading prevented the UI start-up when the language was set to 'en'. (Issue [#388](https://github.com/MichMich/MagicMirror/issues/388)) +- Fix issue where translation loading prevented the UI start-up when the language was set to 'en'. (Issue [#388](https://github.com/MagicMirrorOrg/MagicMirror/issues/388)) ### Updated @@ -1200,8 +1498,8 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we ### Fixed -- Edit Alert Module to display title & message if they are provided in the notification (Issue [#300](https://github.com/MichMich/MagicMirror/issues/300)) -- Removed 'null' reference from updateModuleContent(). This fixes recent Edge and Internet Explorer browser displays (Issue [#319](https://github.com/MichMich/MagicMirror/issues/319)) +- Edit Alert Module to display title & message if they are provided in the notification (Issue [#300](https://github.com/MagicMirrorOrg/MagicMirror/issues/300)) +- Removed 'null' reference from updateModuleContent(). This fixes recent Edge and Internet Explorer browser displays (Issue [#319](https://github.com/MagicMirrorOrg/MagicMirror/issues/319)) ### Changed @@ -1218,7 +1516,7 @@ A huge, huge, huge thanks to user @fewieden for all his hard work on the new `we ### Fixed - Added reference to Italian Translation. -- Added the missing NE translation to all languages. [#344](https://github.com/MichMich/MagicMirror/issues/344) +- Added the missing NE translation to all languages. [#344](https://github.com/MagicMirrorOrg/MagicMirror/issues/344) - Added proper User-Agent string to calendar call. ### Changed diff --git a/Collaboration.md b/Collaboration.md index 6be3fecb2a..6d2da4d6a3 100644 --- a/Collaboration.md +++ b/Collaboration.md @@ -5,8 +5,34 @@ This document describes how collaborators of this repository should work togethe - never merge your own PR's - never merge without someone having approved (approving and merging from same person is allowed) - wait for all approvals requested (or the author decides something different in the comments) +- merge to `master` only for releases or other urgent issues (update notification is only triggered by tags) +- merges to master should be tagged with the "mastermerge" label so that the test runs through ## Issues - "real" Issues are closed if the problem is solved and the fix is released - unrelated Issues (e.g. related to a foreign module) are closed immediately with a comment to open an issue in the module repository or to discuss this further in the forum or discord + +## Releases + +Are done by @rejas or @khassel. + +### Deployment steps + +- pull latest `develop` branch +- update `package.json` to reflect correct version number +- run `npm install` to generate new `package-lock.json` +- test `develop` branch +- update `CHANGELOG.md` (don't forget to add all contributor names) +- commit and push all changes +- after successful test run via github actions: create pull request to `master` branch +- after PR tests run without issues, merge PR +- create new release with corresponding version tag +- publish release notes with link to github release on forum in new locked topic + +### Draft new development release + +- checkout `develop` branch +- update `package.json` to reflect correct version number `2.xx.0-develop` +- draft new section in `CHANGELOG.md` +- commit and publish `develop` branch diff --git a/LICENSE.md b/LICENSE.md index e3fe88029f..506207e0c4 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -1,6 +1,6 @@ # The MIT License (MIT) -Copyright © 2016-2022 Michael Teeuw +Copyright © 2016-2024 Michael Teeuw Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation diff --git a/README.md b/README.md index e64bb9baec..0221b79f40 100644 --- a/README.md +++ b/README.md @@ -4,17 +4,14 @@ License - GitHub Actions - Build Status - - CodeCov Status - - - + GitHub Actions + Build Status + +

-**MagicMirror²** is an open source modular smart mirror platform. With a growing list of installable modules, the **MagicMirror²** allows you to convert your hallway or bathroom mirror into your personal assistant. **MagicMirror²** is built by the creator of [the original MagicMirror](https://michaelteeuw.nl/tagged/magicmirror) with the incredible help of a [growing community of contributors](https://github.com/MichMich/MagicMirror/graphs/contributors). +**MagicMirror²** is an open source modular smart mirror platform. With a growing list of installable modules, the **MagicMirror²** allows you to convert your hallway or bathroom mirror into your personal assistant. **MagicMirror²** is built by the creator of [the original MagicMirror](https://michaelteeuw.nl/tagged/magicmirror) with the incredible help of a [growing community of contributors](https://github.com/MagicMirrorOrg/MagicMirror/graphs/contributors). MagicMirror² focuses on a modular plugin system and uses [Electron](https://www.electronjs.org/) as an application wrapper. So no more web server or browser installs necessary! diff --git a/clientonly/index.js b/clientonly/index.js index 1a0a797009..b9a354832b 100644 --- a/clientonly/index.js +++ b/clientonly/index.js @@ -7,16 +7,16 @@ /** * Helper function to get server address/hostname from either the commandline or env */ - function getServerAddress() { + function getServerAddress () { + /** * Get command line parameters * Assumes that a cmdline parameter is defined with `--key [value]` - * * @param {string} key key to look for at the command line * @param {string} defaultValue value if no key is given at the command line * @returns {string} the value of the parameter */ - function getCommandLineParameter(key, defaultValue = undefined) { + function getCommandLineParameter (key, defaultValue = undefined) { const index = process.argv.indexOf(`--${key}`); const value = index > -1 ? process.argv[index + 1] : undefined; return value !== undefined ? String(value) : defaultValue; @@ -33,15 +33,14 @@ /** * Gets the config from the specified server url - * * @param {string} url location where the server is running. * @returns {Promise} the config */ - function getServerConfig(url) { + function getServerConfig (url) { // Return new pending promise return new Promise((resolve, reject) => { // Select http or https module, depending on requested url - const lib = url.startsWith("https") ? require("https") : require("http"); + const lib = url.startsWith("https") ? require("node:https") : require("node:http"); const request = lib.get(url, (response) => { let configData = ""; @@ -63,11 +62,10 @@ /** * Print a message to the console in case of errors - * * @param {string} message error message to print * @param {number} code error code for the exit call */ - function fail(message, code = 1) { + function fail (message, code = 1) { if (message !== undefined && typeof message === "string") { console.log(message); } else { @@ -87,6 +85,7 @@ .then(function (configReturn) { // Pass along the server config via an environment variable const env = Object.create(process.env); + env.clientonly = true; // set to pass to electron.js const options = { env: env }; configReturn.address = config.address; configReturn.port = config.port; @@ -95,7 +94,7 @@ // Spawn electron application const electron = require("electron"); - const child = require("child_process").spawn(electron, ["js/electron.js"], options); + const child = require("node:child_process").spawn(electron, ["js/electron.js"], options); // Pipe all child process output to current stdout child.stdout.on("data", function (buf) { @@ -123,4 +122,4 @@ } else { fail(); } -})(); +}()); diff --git a/config/config.js.sample b/config/config.js.sample index a3460d6faf..56edb59df8 100644 --- a/config/config.js.sample +++ b/config/config.js.sample @@ -1,41 +1,37 @@ -/* MagicMirror² Config Sample - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. +/* Config Sample * * For more information on how you can configure this file * see https://docs.magicmirror.builders/configuration/introduction.html * and https://docs.magicmirror.builders/modules/configuration.html + * + * You can use environment variables using a `config.js.template` file instead of `config.js` + * which will be converted to `config.js` while starting. For more information + * see https://docs.magicmirror.builders/configuration/introduction.html#enviromnent-variables */ let config = { - address: "localhost", // Address to listen on, can be: + address: "localhost", // Address to listen on, can be: // - "localhost", "127.0.0.1", "::1" to listen on loopback interface // - another specific IPv4/6 to listen on a specific interface // - "0.0.0.0", "::" to listen on any interface // Default, when address config is left out or empty, is "localhost" port: 8080, - basePath: "/", // The URL path where MagicMirror² is hosted. If you are using a Reverse proxy - // you must set the sub path here. basePath must end with a / - ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], // Set [] to allow all IP addresses - // or add a specific IPv4 of 192.168.1.5 : - // ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.1.5"], - // or IPv4 range of 192.168.3.0 --> 192.168.3.15 use CIDR format : - // ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.3.0/28"], + basePath: "/", // The URL path where MagicMirror² is hosted. If you are using a Reverse proxy + // you must set the sub path here. basePath must end with a / + ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1"], // Set [] to allow all IP addresses + // or add a specific IPv4 of 192.168.1.5 : + // ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.1.5"], + // or IPv4 range of 192.168.3.0 --> 192.168.3.15 use CIDR format : + // ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.3.0/28"], - useHttps: false, // Support HTTPS or not, default "false" will use HTTP - httpsPrivateKey: "", // HTTPS private key path, only require when useHttps is true - httpsCertificate: "", // HTTPS Certificate path, only require when useHttps is true + useHttps: false, // Support HTTPS or not, default "false" will use HTTP + httpsPrivateKey: "", // HTTPS private key path, only require when useHttps is true + httpsCertificate: "", // HTTPS Certificate path, only require when useHttps is true language: "en", locale: "en-US", logLevel: ["INFO", "LOG", "WARN", "ERROR"], // Add "DEBUG" for even more logging timeFormat: 24, units: "metric", - // serverOnly: true/false/"local" , - // local for armv6l processors, default - // starts serveronly and then starts chrome browser - // false, default for all NON-armv6l devices - // true, force serveronly mode, because you want to.. no UI on this device modules: [ { @@ -56,8 +52,9 @@ let config = { config: { calendars: [ { + fetchInterval: 7 * 24 * 60 * 60 * 1000, symbol: "calendar-check", - url: "webcal://www.calendarlabs.com/ical-calendar/ics/76/US_Holidays.ics" + url: "https://ics.calendarlabs.com/76/mm3137/US_Holidays.ics" } ] } @@ -70,11 +67,10 @@ let config = { module: "weather", position: "top_right", config: { - weatherProvider: "openweathermap", + weatherProvider: "openmeteo", type: "current", - location: "New York", - locationID: "5128581", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city - apiKey: "YOUR_OPENWEATHER_API_KEY" + lat: 40.776676, + lon: -73.971321 } }, { @@ -82,11 +78,10 @@ let config = { position: "top_right", header: "Weather Forecast", config: { - weatherProvider: "openweathermap", + weatherProvider: "openmeteo", type: "forecast", - location: "New York", - locationID: "5128581", //ID from http://bulk.openweathermap.org/sample/city.list.json.gz; unzip the gz file and find your city - apiKey: "YOUR_OPENWEATHER_API_KEY" + lat: 40.776676, + lon: -73.971321 } }, { @@ -109,4 +104,4 @@ let config = { }; /*************** DO NOT EDIT THE LINE BELOW ***************/ -if (typeof module !== "undefined") {module.exports = config;} +if (typeof module !== "undefined") { module.exports = config; } diff --git a/css/custom.css.sample b/css/custom.css.sample index 48cc17a0af..29590206a7 100644 --- a/css/custom.css.sample +++ b/css/custom.css.sample @@ -1,10 +1,8 @@ -/* MagicMirror² Custom CSS Sample +/* Custom CSS Sample * * Change color and fonts here. * * Beware that properties cannot be unitless, so for example write '--gap-body: 0px;' instead of just '--gap-body: 0;' - * - * MIT Licensed. */ /* Uncomment and adjust accordingly if you want to import another font from the google-fonts-api: */ @@ -18,7 +16,7 @@ --font-primary: "Roboto Condensed"; --font-secondary: "Roboto"; - + --font-size: 20px; --font-size-small: 0.75rem; @@ -26,6 +24,6 @@ --gap-body-right: 60px; --gap-body-bottom: 60px; --gap-body-left: 60px; - + --gap-modules: 30px; } diff --git a/css/main.css b/css/main.css index 9206abca45..0aa5c3418e 100644 --- a/css/main.css +++ b/css/main.css @@ -3,22 +3,18 @@ --color-text-dimmed: #666; --color-text-bright: #fff; --color-background: #000; - --font-primary: "Roboto Condensed"; --font-secondary: "Roboto"; - --font-size: 20px; --font-size-xsmall: 0.75rem; --font-size-small: 1rem; --font-size-medium: 1.5rem; --font-size-large: 3.25rem; --font-size-xlarge: 3.75rem; - --gap-body-top: 60px; --gap-body-right: 60px; --gap-body-bottom: 60px; --gap-body-left: 60px; - --gap-modules: 30px; } @@ -175,10 +171,7 @@ sup { .region.fullscreen { position: absolute; - top: calc(-1 * var(--gap-body-top)); - left: calc(-1 * var(--gap-body-left)); - right: calc(-1 * var(--gap-body-right)); - bottom: calc(-1 * var(--gap-body-bottom)); + inset: calc(-1 * var(--gap-body-top)) calc(-1 * var(--gap-body-right)) calc(-1 * var(--gap-body-bottom)) calc(-1 * var(--gap-body-left)); pointer-events: none; } diff --git a/fonts/package-lock.json b/fonts/package-lock.json index c35712f59c..287cd90e62 100644 --- a/fonts/package-lock.json +++ b/fonts/package-lock.json @@ -1,37 +1,27 @@ { "name": "magicmirror-fonts", - "lockfileVersion": 2, + "version": "1.0.0", + "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "magicmirror-fonts", + "version": "1.0.0", "license": "MIT", "dependencies": { - "@fontsource/roboto": "^4.5.8", - "@fontsource/roboto-condensed": "^4.5.9" + "@fontsource/roboto": "^5.0.13", + "@fontsource/roboto-condensed": "^5.0.16" } }, "node_modules/@fontsource/roboto": { - "version": "4.5.8", - "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-4.5.8.tgz", - "integrity": "sha512-CnD7zLItIzt86q4Sj3kZUiLcBk1dSk81qcqgMGaZe7SQ1P8hFNxhMl5AZthK1zrDM5m74VVhaOpuMGIL4gagaA==" + "version": "5.0.13", + "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-5.0.13.tgz", + "integrity": "sha512-j61DHjsdUCKMXSdNLTOxcG701FWnF0jcqNNQi2iPCDxU8seN/sMxeh62dC++UiagCWq9ghTypX+Pcy7kX+QOeQ==" }, "node_modules/@fontsource/roboto-condensed": { - "version": "4.5.9", - "resolved": "https://registry.npmjs.org/@fontsource/roboto-condensed/-/roboto-condensed-4.5.9.tgz", - "integrity": "sha512-ql4sQq+h8puBVildZ5ssjYf8DWDONYDe3PD3Bu/p1ZW9GnRETRNPPcCTs/q62HIl3QimwwkiKWynn6wZhQaetg==" - } - }, - "dependencies": { - "@fontsource/roboto": { - "version": "4.5.8", - "resolved": "https://registry.npmjs.org/@fontsource/roboto/-/roboto-4.5.8.tgz", - "integrity": "sha512-CnD7zLItIzt86q4Sj3kZUiLcBk1dSk81qcqgMGaZe7SQ1P8hFNxhMl5AZthK1zrDM5m74VVhaOpuMGIL4gagaA==" - }, - "@fontsource/roboto-condensed": { - "version": "4.5.9", - "resolved": "https://registry.npmjs.org/@fontsource/roboto-condensed/-/roboto-condensed-4.5.9.tgz", - "integrity": "sha512-ql4sQq+h8puBVildZ5ssjYf8DWDONYDe3PD3Bu/p1ZW9GnRETRNPPcCTs/q62HIl3QimwwkiKWynn6wZhQaetg==" + "version": "5.0.16", + "resolved": "https://registry.npmjs.org/@fontsource/roboto-condensed/-/roboto-condensed-5.0.16.tgz", + "integrity": "sha512-pjO80g5x/hkqzWCIafvkS3JrkBDxSiTjEy4LdqQKJYrmoGx8x2AlhSUMgzIzG/ge4kT98bA7+gmm7yquzrrZ/w==" } } } diff --git a/fonts/package.json b/fonts/package.json index 2d09468939..09d7c153e6 100644 --- a/fonts/package.json +++ b/fonts/package.json @@ -1,16 +1,17 @@ { "name": "magicmirror-fonts", - "description": "Package for fonts use by MagicMirror² Core.", + "version": "1.0.0", + "description": "Package for fonts use by MagicMirror² core.", + "bugs": { + "url": "https://github.com/MagicMirrorOrg/MagicMirror/issues" + }, "repository": { "type": "git", - "url": "git+https://github.com/MichMich/MagicMirror.git" + "url": "https://github.com/MagicMirrorOrg/MagicMirror" }, "license": "MIT", - "bugs": { - "url": "https://github.com/MichMich/MagicMirror/issues" - }, "dependencies": { - "@fontsource/roboto": "^4.5.8", - "@fontsource/roboto-condensed": "^4.5.9" + "@fontsource/roboto": "^5.0.13", + "@fontsource/roboto-condensed": "^5.0.16" } } diff --git a/fonts/roboto.css b/fonts/roboto.css index 40c643903c..bb760f8d8e 100644 --- a/fonts/roboto.css +++ b/fonts/roboto.css @@ -1,55 +1,671 @@ +/* roboto-cyrillic-ext-100-normal */ @font-face { font-family: Roboto; font-style: normal; + font-display: var(--fontsource-display, swap); font-weight: 100; - src: local("Roboto Thin"), local("Roboto-Thin"), url("node_modules/@fontsource/roboto/files/roboto-all-100-normal.woff") format("woff"); + src: + url("node_modules/@fontsource/roboto/files/roboto-cyrillic-ext-100-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-cyrillic-ext-100-normal.woff") format("woff"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; } +/* roboto-cyrillic-100-normal */ @font-face { - font-family: "Roboto Condensed"; + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 100; + src: + url("node_modules/@fontsource/roboto/files/roboto-cyrillic-100-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-cyrillic-100-normal.woff") format("woff"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} + +/* roboto-greek-ext-100-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 100; + src: + url("node_modules/@fontsource/roboto/files/roboto-greek-ext-100-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-greek-ext-100-normal.woff") format("woff"); + unicode-range: U+1F00-1FFF; +} + +/* roboto-greek-100-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 100; + src: + url("node_modules/@fontsource/roboto/files/roboto-greek-100-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-greek-100-normal.woff") format("woff"); + unicode-range: U+0370-03FF; +} + +/* roboto-vietnamese-100-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 100; + src: + url("node_modules/@fontsource/roboto/files/roboto-vietnamese-100-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-vietnamese-100-normal.woff") format("woff"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; +} + +/* roboto-latin-ext-100-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 100; + src: + url("node_modules/@fontsource/roboto/files/roboto-latin-ext-100-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-latin-ext-100-normal.woff") format("woff"); + unicode-range: U+0100-02AF, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} + +/* roboto-latin-100-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 100; + src: + url("node_modules/@fontsource/roboto/files/roboto-latin-100-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-latin-100-normal.woff") format("woff"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} + +/* roboto-cyrillic-ext-300-normal */ +@font-face { + font-family: Roboto; font-style: normal; + font-display: var(--fontsource-display, swap); font-weight: 300; - src: local("Roboto Condensed Light"), local("RobotoCondensed-Light"), url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-all-300-normal.woff") format("woff"); + src: + url("node_modules/@fontsource/roboto/files/roboto-cyrillic-ext-300-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-cyrillic-ext-300-normal.woff") format("woff"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; } +/* roboto-cyrillic-300-normal */ @font-face { - font-family: "Roboto Condensed"; + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 300; + src: + url("node_modules/@fontsource/roboto/files/roboto-cyrillic-300-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-cyrillic-300-normal.woff") format("woff"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} + +/* roboto-greek-ext-300-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 300; + src: + url("node_modules/@fontsource/roboto/files/roboto-greek-ext-300-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-greek-ext-300-normal.woff") format("woff"); + unicode-range: U+1F00-1FFF; +} + +/* roboto-greek-300-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 300; + src: + url("node_modules/@fontsource/roboto/files/roboto-greek-300-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-greek-300-normal.woff") format("woff"); + unicode-range: U+0370-03FF; +} + +/* roboto-vietnamese-300-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 300; + src: + url("node_modules/@fontsource/roboto/files/roboto-vietnamese-300-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-vietnamese-300-normal.woff") format("woff"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; +} + +/* roboto-latin-ext-300-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 300; + src: + url("node_modules/@fontsource/roboto/files/roboto-latin-ext-300-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-latin-ext-300-normal.woff") format("woff"); + unicode-range: U+0100-02AF, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} + +/* roboto-latin-300-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 300; + src: + url("node_modules/@fontsource/roboto/files/roboto-latin-300-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-latin-300-normal.woff") format("woff"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} + +/* roboto-cyrillic-ext-400-normal */ +@font-face { + font-family: Roboto; font-style: normal; + font-display: var(--fontsource-display, swap); font-weight: 400; - src: local("Roboto Condensed"), local("RobotoCondensed-Regular"), url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-all-400-normal.woff") format("woff"); + src: + url("node_modules/@fontsource/roboto/files/roboto-cyrillic-ext-400-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-cyrillic-ext-400-normal.woff") format("woff"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; } +/* roboto-cyrillic-400-normal */ @font-face { - font-family: "Roboto Condensed"; + font-family: Roboto; font-style: normal; - font-weight: 700; - src: local("Roboto Condensed Bold"), local("RobotoCondensed-Bold"), url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-all-700-normal.woff") format("woff"); + font-display: var(--fontsource-display, swap); + font-weight: 400; + src: + url("node_modules/@fontsource/roboto/files/roboto-cyrillic-400-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-cyrillic-400-normal.woff") format("woff"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; } +/* roboto-greek-ext-400-normal */ @font-face { font-family: Roboto; font-style: normal; + font-display: var(--fontsource-display, swap); font-weight: 400; - src: local("Roboto"), local("Roboto-Regular"), url("node_modules/@fontsource/roboto/files/roboto-all-400-normal.woff") format("woff"); + src: + url("node_modules/@fontsource/roboto/files/roboto-greek-ext-400-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-greek-ext-400-normal.woff") format("woff"); + unicode-range: U+1F00-1FFF; +} + +/* roboto-greek-400-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 400; + src: + url("node_modules/@fontsource/roboto/files/roboto-greek-400-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-greek-400-normal.woff") format("woff"); + unicode-range: U+0370-03FF; +} + +/* roboto-vietnamese-400-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 400; + src: + url("node_modules/@fontsource/roboto/files/roboto-vietnamese-400-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-vietnamese-400-normal.woff") format("woff"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; +} + +/* roboto-latin-ext-400-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 400; + src: + url("node_modules/@fontsource/roboto/files/roboto-latin-ext-400-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-latin-ext-400-normal.woff") format("woff"); + unicode-range: U+0100-02AF, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} + +/* roboto-latin-400-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 400; + src: + url("node_modules/@fontsource/roboto/files/roboto-latin-400-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-latin-400-normal.woff") format("woff"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} + +/* roboto-cyrillic-ext-500-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 500; + src: + url("node_modules/@fontsource/roboto/files/roboto-cyrillic-ext-500-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-cyrillic-ext-500-normal.woff") format("woff"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} + +/* roboto-cyrillic-500-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 500; + src: + url("node_modules/@fontsource/roboto/files/roboto-cyrillic-500-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-cyrillic-500-normal.woff") format("woff"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; } +/* roboto-greek-ext-500-normal */ @font-face { font-family: Roboto; font-style: normal; + font-display: var(--fontsource-display, swap); font-weight: 500; - src: local("Roboto Medium"), local("Roboto-Medium"), url("node_modules/@fontsource/roboto/files/roboto-all-500-normal.woff") format("woff"); + src: + url("node_modules/@fontsource/roboto/files/roboto-greek-ext-500-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-greek-ext-500-normal.woff") format("woff"); + unicode-range: U+1F00-1FFF; +} + +/* roboto-greek-500-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 500; + src: + url("node_modules/@fontsource/roboto/files/roboto-greek-500-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-greek-500-normal.woff") format("woff"); + unicode-range: U+0370-03FF; +} + +/* roboto-vietnamese-500-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 500; + src: + url("node_modules/@fontsource/roboto/files/roboto-vietnamese-500-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-vietnamese-500-normal.woff") format("woff"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; +} + +/* roboto-latin-ext-500-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 500; + src: + url("node_modules/@fontsource/roboto/files/roboto-latin-ext-500-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-latin-ext-500-normal.woff") format("woff"); + unicode-range: U+0100-02AF, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} + +/* roboto-latin-500-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 500; + src: + url("node_modules/@fontsource/roboto/files/roboto-latin-500-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-latin-500-normal.woff") format("woff"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} + +/* roboto-cyrillic-ext-700-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 700; + src: + url("node_modules/@fontsource/roboto/files/roboto-cyrillic-ext-700-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-cyrillic-ext-700-normal.woff") format("woff"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} + +/* roboto-cyrillic-700-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 700; + src: + url("node_modules/@fontsource/roboto/files/roboto-cyrillic-700-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-cyrillic-700-normal.woff") format("woff"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} + +/* roboto-greek-ext-700-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 700; + src: + url("node_modules/@fontsource/roboto/files/roboto-greek-ext-700-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-greek-ext-700-normal.woff") format("woff"); + unicode-range: U+1F00-1FFF; } +/* roboto-greek-700-normal */ @font-face { font-family: Roboto; font-style: normal; + font-display: var(--fontsource-display, swap); font-weight: 700; - src: local("Roboto Bold"), local("Roboto-Bold"), url("node_modules/@fontsource/roboto/files/roboto-all-700-normal.woff") format("woff"); + src: + url("node_modules/@fontsource/roboto/files/roboto-greek-700-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-greek-700-normal.woff") format("woff"); + unicode-range: U+0370-03FF; } +/* roboto-vietnamese-700-normal */ @font-face { font-family: Roboto; font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 700; + src: + url("node_modules/@fontsource/roboto/files/roboto-vietnamese-700-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-vietnamese-700-normal.woff") format("woff"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; +} + +/* roboto-latin-ext-700-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 700; + src: + url("node_modules/@fontsource/roboto/files/roboto-latin-ext-700-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-latin-ext-700-normal.woff") format("woff"); + unicode-range: U+0100-02AF, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} + +/* roboto-latin-700-normal */ +@font-face { + font-family: Roboto; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 700; + src: + url("node_modules/@fontsource/roboto/files/roboto-latin-700-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto/files/roboto-latin-700-normal.woff") format("woff"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} + +/* roboto-condensed-cyrillic-ext-300-normal */ +@font-face { + font-family: "Roboto Condensed"; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 300; + src: + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-cyrillic-ext-300-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-cyrillic-ext-300-normal.woff") format("woff"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} + +/* roboto-condensed-cyrillic-300-normal */ +@font-face { + font-family: "Roboto Condensed"; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 300; + src: + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-cyrillic-300-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-cyrillic-300-normal.woff") format("woff"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} + +/* roboto-condensed-greek-ext-300-normal */ +@font-face { + font-family: "Roboto Condensed"; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 300; + src: + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-greek-ext-300-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-greek-ext-300-normal.woff") format("woff"); + unicode-range: U+1F00-1FFF; +} + +/* roboto-condensed-greek-300-normal */ +@font-face { + font-family: "Roboto Condensed"; + font-style: normal; + font-display: var(--fontsource-display, swap); font-weight: 300; - src: local("Roboto Light"), local("Roboto-Light"), url("node_modules/@fontsource/roboto/files/roboto-all-300-normal.woff") format("woff"); + src: + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-greek-300-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-greek-300-normal.woff") format("woff"); + unicode-range: U+0370-03FF; +} + +/* roboto-condensed-vietnamese-300-normal */ +@font-face { + font-family: "Roboto Condensed"; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 300; + src: + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-vietnamese-300-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-vietnamese-300-normal.woff") format("woff"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; +} + +/* roboto-condensed-latin-ext-300-normal */ +@font-face { + font-family: "Roboto Condensed"; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 300; + src: + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-latin-ext-300-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-latin-ext-300-normal.woff") format("woff"); + unicode-range: U+0100-02AF, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} + +/* roboto-condensed-latin-300-normal */ +@font-face { + font-family: "Roboto Condensed"; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 300; + src: + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-latin-300-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-latin-300-normal.woff") format("woff"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} + +/* roboto-condensed-cyrillic-ext-400-normal */ +@font-face { + font-family: "Roboto Condensed"; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 400; + src: + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-cyrillic-ext-400-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-cyrillic-ext-400-normal.woff") format("woff"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} + +/* roboto-condensed-cyrillic-400-normal */ +@font-face { + font-family: "Roboto Condensed"; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 400; + src: + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-cyrillic-400-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-cyrillic-400-normal.woff") format("woff"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} + +/* roboto-condensed-greek-ext-400-normal */ +@font-face { + font-family: "Roboto Condensed"; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 400; + src: + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-greek-ext-400-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-greek-ext-400-normal.woff") format("woff"); + unicode-range: U+1F00-1FFF; +} + +/* roboto-condensed-greek-400-normal */ +@font-face { + font-family: "Roboto Condensed"; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 400; + src: + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-greek-400-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-greek-400-normal.woff") format("woff"); + unicode-range: U+0370-03FF; +} + +/* roboto-condensed-vietnamese-400-normal */ +@font-face { + font-family: "Roboto Condensed"; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 400; + src: + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-vietnamese-400-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-vietnamese-400-normal.woff") format("woff"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; +} + +/* roboto-condensed-latin-ext-400-normal */ +@font-face { + font-family: "Roboto Condensed"; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 400; + src: + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-latin-ext-400-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-latin-ext-400-normal.woff") format("woff"); + unicode-range: U+0100-02AF, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} + +/* roboto-condensed-latin-400-normal */ +@font-face { + font-family: "Roboto Condensed"; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 400; + src: + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-latin-400-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-latin-400-normal.woff") format("woff"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; +} + +/* roboto-condensed-cyrillic-ext-700-normal */ +@font-face { + font-family: "Roboto Condensed"; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 700; + src: + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-cyrillic-ext-700-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-cyrillic-ext-700-normal.woff") format("woff"); + unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F; +} + +/* roboto-condensed-cyrillic-700-normal */ +@font-face { + font-family: "Roboto Condensed"; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 700; + src: + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-cyrillic-700-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-cyrillic-700-normal.woff") format("woff"); + unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116; +} + +/* roboto-condensed-greek-ext-700-normal */ +@font-face { + font-family: "Roboto Condensed"; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 700; + src: + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-greek-ext-700-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-greek-ext-700-normal.woff") format("woff"); + unicode-range: U+1F00-1FFF; +} + +/* roboto-condensed-greek-700-normal */ +@font-face { + font-family: "Roboto Condensed"; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 700; + src: + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-greek-700-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-greek-700-normal.woff") format("woff"); + unicode-range: U+0370-03FF; +} + +/* roboto-condensed-vietnamese-700-normal */ +@font-face { + font-family: "Roboto Condensed"; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 700; + src: + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-vietnamese-700-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-vietnamese-700-normal.woff") format("woff"); + unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1EA0-1EF9, U+20AB; +} + +/* roboto-condensed-latin-ext-700-normal */ +@font-face { + font-family: "Roboto Condensed"; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 700; + src: + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-latin-ext-700-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-latin-ext-700-normal.woff") format("woff"); + unicode-range: U+0100-02AF, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF; +} + +/* roboto-condensed-latin-700-normal */ +@font-face { + font-family: "Roboto Condensed"; + font-style: normal; + font-display: var(--fontsource-display, swap); + font-weight: 700; + src: + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-latin-700-normal.woff2") format("woff2"), + url("node_modules/@fontsource/roboto-condensed/files/roboto-condensed-latin-700-normal.woff") format("woff"); + unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0300-0301, U+0303-0304, U+0308-0309, U+0323, U+0329, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD; } diff --git a/index.html b/index.html index 37fc2f6efb..b97124be10 100644 --- a/index.html +++ b/index.html @@ -1,4 +1,4 @@ - + MagicMirror² @@ -13,6 +13,7 @@ + + @@ -52,6 +54,7 @@ + diff --git a/jest.config.js b/jest.config.js index a36db006fc..fde44c9639 100644 --- a/jest.config.js +++ b/jest.config.js @@ -2,30 +2,31 @@ module.exports = async () => { return { verbose: true, testTimeout: 20000, - testSequencer: "/tests/configs/test_sequencer.js", + testSequencer: "/tests/utils/test_sequencer.js", projects: [ { displayName: "unit", + globalSetup: "/tests/unit/helpers/global-setup.js", moduleNameMapper: { logger: "/js/logger.js" }, testMatch: ["**/tests/unit/**/*.[jt]s?(x)"], - testPathIgnorePatterns: ["/tests/unit/mocks"] + testPathIgnorePatterns: ["/tests/unit/mocks", "/tests/unit/helpers"] }, { displayName: "electron", testMatch: ["**/tests/electron/**/*.[jt]s?(x)"], - testPathIgnorePatterns: ["/tests/electron/helpers/"] + 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"] + testPathIgnorePatterns: ["/tests/e2e/helpers", "/tests/e2e/mocks"] } ], - collectCoverageFrom: ["./clientonly/**/*.js", "./js/**/*.js", "./modules/**/*.js", "./serveronly/**/*.js"], + collectCoverageFrom: ["./clientonly/**/*.js", "./js/**/*.js", "./modules/default/**/*.js", "./serveronly/**/*.js"], coverageReporters: ["lcov", "text"], coverageProvider: "v8" }; diff --git a/js/animateCSS.js b/js/animateCSS.js new file mode 100644 index 0000000000..057d53c72d --- /dev/null +++ b/js/animateCSS.js @@ -0,0 +1,157 @@ +/* enumeration of animations in Array **/ +const AnimateCSSIn = [ + // Attention seekers + "bounce", + "flash", + "pulse", + "rubberBand", + "shakeX", + "shakeY", + "headShake", + "swing", + "tada", + "wobble", + "jello", + "heartBeat", + // Back entrances + "backInDown", + "backInLeft", + "backInRight", + "backInUp", + // Bouncing entrances + "bounceIn", + "bounceInDown", + "bounceInLeft", + "bounceInRight", + "bounceInUp", + // Fading entrances + "fadeIn", + "fadeInDown", + "fadeInDownBig", + "fadeInLeft", + "fadeInLeftBig", + "fadeInRight", + "fadeInRightBig", + "fadeInUp", + "fadeInUpBig", + "fadeInTopLeft", + "fadeInTopRight", + "fadeInBottomLeft", + "fadeInBottomRight", + // Flippers + "flip", + "flipInX", + "flipInY", + // Lightspeed + "lightSpeedInRight", + "lightSpeedInLeft", + // Rotating entrances + "rotateIn", + "rotateInDownLeft", + "rotateInDownRight", + "rotateInUpLeft", + "rotateInUpRight", + // Specials + "jackInTheBox", + "rollIn", + // Zooming entrances + "zoomIn", + "zoomInDown", + "zoomInLeft", + "zoomInRight", + "zoomInUp", + // Sliding entrances + "slideInDown", + "slideInLeft", + "slideInRight", + "slideInUp" +]; + +const AnimateCSSOut = [ + // Back exits + "backOutDown", + "backOutLeft", + "backOutRight", + "backOutUp", + // Bouncing exits + "bounceOut", + "bounceOutDown", + "bounceOutLeft", + "bounceOutRight", + "bounceOutUp", + // Fading exits + "fadeOut", + "fadeOutDown", + "fadeOutDownBig", + "fadeOutLeft", + "fadeOutLeftBig", + "fadeOutRight", + "fadeOutRightBig", + "fadeOutUp", + "fadeOutUpBig", + "fadeOutTopLeft", + "fadeOutTopRight", + "fadeOutBottomRight", + "fadeOutBottomLeft", + // Flippers + "flipOutX", + "flipOutY", + // Lightspeed + "lightSpeedOutRight", + "lightSpeedOutLeft", + // Rotating exits + "rotateOut", + "rotateOutDownLeft", + "rotateOutDownRight", + "rotateOutUpLeft", + "rotateOutUpRight", + // Specials + "hinge", + "rollOut", + // Zooming exits + "zoomOut", + "zoomOutDown", + "zoomOutLeft", + "zoomOutRight", + "zoomOutUp", + // Sliding exits + "slideOutDown", + "slideOutLeft", + "slideOutRight", + "slideOutUp" +]; + +/** + * Create an animation with Animate CSS + * @param {string} [element] div element to animate. + * @param {string} [animation] animation name. + * @param {number} [animationTime] animation duration. + */ +function addAnimateCSS (element, animation, animationTime) { + const animationName = `animate__${animation}`; + const node = document.getElementById(element); + if (!node) { + // don't execute animate: we don't find div + Log.warn("addAnimateCSS: node not found for", element); + return; + } + node.style.setProperty("--animate-duration", `${animationTime}s`); + node.classList.add("animate__animated", animationName); +} + +/** + * Remove an animation with Animate CSS + * @param {string} [element] div element to animate. + * @param {string} [animation] animation name. + */ +function removeAnimateCSS (element, animation) { + const animationName = `animate__${animation}`; + const node = document.getElementById(element); + if (!node) { + // don't execute animate: we don't find div + Log.warn("removeAnimateCSS: node not found for", element); + return; + } + node.classList.remove("animate__animated", animationName); + node.style.removeProperty("--animate-duration"); +} diff --git a/js/app.js b/js/app.js index ae2d76f4df..77d0dc206f 100644 --- a/js/app.js +++ b/js/app.js @@ -1,33 +1,31 @@ -/* MagicMirror² - * The Core App (Server) - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. - */ - // Alias modules mentioned in package.js under _moduleAliases. require("module-alias/register"); -const fs = require("fs"); -const path = require("path"); +const fs = require("node:fs"); +const path = require("node:path"); +const envsub = require("envsub"); const Log = require("logger"); + const Server = require(`${__dirname}/server`); const Utils = require(`${__dirname}/utils`); const defaultModules = require(`${__dirname}/../modules/default/defaultmodules`); // Get version number. global.version = require(`${__dirname}/../package.json`).version; -Log.log("Starting MagicMirror: v" + global.version); +Log.log(`Starting MagicMirror: v${global.version}`); + +// Log system information. +Utils.logSystemInformation(); // global absolute root path global.root_path = path.resolve(`${__dirname}/../`); if (process.env.MM_CONFIG_FILE) { - global.configuration_file = process.env.MM_CONFIG_FILE; + global.configuration_file = process.env.MM_CONFIG_FILE.replace(`${global.root_path}/`, ""); } // FIXME: Hotfix Pull Request -// https://github.com/MichMich/MagicMirror/pull/673 +// https://github.com/MagicMirrorOrg/MagicMirror/pull/673 if (process.env.MM_PORT) { global.mmPort = process.env.MM_PORT; } @@ -35,76 +33,126 @@ if (process.env.MM_PORT) { // The next part is here to prevent a major exception when there // is no internet connection. This could probable be solved better. process.on("uncaughtException", function (err) { - Log.error("Whoops! There was an uncaught exception..."); - Log.error(err); - Log.error("MagicMirror² will not quit, but it might be a good idea to check why this happened. Maybe no internet connection?"); - Log.error("If you think this really is an issue, please open an issue on GitHub: https://github.com/MichMich/MagicMirror/issues"); + // ignore strange exceptions under aarch64 coming from systeminformation: + if (!err.stack.includes("node_modules/systeminformation")) { + Log.error("Whoops! There was an uncaught exception..."); + Log.error(err); + Log.error("MagicMirror² will not quit, but it might be a good idea to check why this happened. Maybe no internet connection?"); + Log.error("If you think this really is an issue, please open an issue on GitHub: https://github.com/MagicMirrorOrg/MagicMirror/issues"); + } }); /** * The core app. - * * @class */ -function App() { +function App () { let nodeHelpers = []; let httpServer; /** - * Loads the config file. Combines it with the defaults, and runs the - * callback with the found config as argument. - * - * @param {Function} callback Function to be called after loading the config + * Loads the config file. Combines it with the defaults and returns the config + * @async + * @returns {Promise} the loaded config or the defaults if something goes wrong */ - function loadConfig(callback) { + async function loadConfig () { Log.log("Loading config ..."); const defaults = require(`${__dirname}/defaults`); // For this check proposed to TestSuite // https://forum.magicmirror.builders/topic/1456/test-suite-for-magicmirror/8 const configFilename = path.resolve(global.configuration_file || `${global.root_path}/config/config.js`); + let templateFile = `${configFilename}.template`; + + // check if templateFile exists + try { + fs.accessSync(templateFile, fs.F_OK); + } catch (err) { + templateFile = null; + Log.log("config template file not exists, no envsubst"); + } + + if (templateFile) { + // save current config.js + try { + if (fs.existsSync(configFilename)) { + fs.copyFileSync(configFilename, `${configFilename}-old`); + } + } catch (err) { + Log.warn(`Could not copy ${configFilename}: ${err.message}`); + } + + // check if config.env exists + const envFiles = []; + const configEnvFile = `${configFilename.substr(0, configFilename.lastIndexOf("."))}.env`; + try { + if (fs.existsSync(configEnvFile)) { + envFiles.push(configEnvFile); + } + } catch (err) { + Log.log(`${configEnvFile} does not exist. ${err.message}`); + } + + let options = { + all: true, + diff: false, + envFiles: envFiles, + protect: false, + syntax: "default", + system: true + }; + + // envsubst variables in templateFile and create new config.js + // naming for envsub must be templateFile and outputFile + const outputFile = configFilename; + try { + await envsub({ templateFile, outputFile, options }); + } catch (err) { + Log.error(`Could not envsubst variables: ${err.message}`); + } + } try { fs.accessSync(configFilename, fs.F_OK); const c = require(configFilename); + if (Object.keys(c).length === 0) { + Log.error("WARNING! Config file appears empty, maybe missing module.exports last line?"); + } checkDeprecatedOptions(c); - const config = Object.assign(defaults, c); - callback(config); + return Object.assign(defaults, c); } catch (e) { if (e.code === "ENOENT") { - Log.error(Utils.colors.error("WARNING! Could not find config file. Please create one. Starting with default configuration.")); + Log.error("WARNING! Could not find config file. Please create one. Starting with default configuration."); } else if (e instanceof ReferenceError || e instanceof SyntaxError) { - Log.error(Utils.colors.error(`WARNING! Could not validate config file. Starting with default configuration. Please correct syntax errors at or above this line: ${e.stack}`)); + Log.error(`WARNING! Could not validate config file. Starting with default configuration. Please correct syntax errors at or above this line: ${e.stack}`); } else { - Log.error(Utils.colors.error(`WARNING! Could not load config file. Starting with default configuration. Error found: ${e}`)); + Log.error(`WARNING! Could not load config file. Starting with default configuration. Error found: ${e}`); } - callback(defaults); } + + return defaults; } /** * Checks the config for deprecated options and throws a warning in the logs * if it encounters one option from the deprecated.js list - * * @param {object} userConfig The user config */ - function checkDeprecatedOptions(userConfig) { + function checkDeprecatedOptions (userConfig) { const deprecated = require(`${global.root_path}/js/deprecated`); const deprecatedOptions = deprecated.configs; const usedDeprecated = deprecatedOptions.filter((option) => userConfig.hasOwnProperty(option)); if (usedDeprecated.length > 0) { - Log.warn(Utils.colors.warn(`WARNING! Your config is using deprecated options: ${usedDeprecated.join(", ")}. Check README and CHANGELOG for more up-to-date ways of getting the same functionality.`)); + Log.warn(`WARNING! Your config is using deprecated options: ${usedDeprecated.join(", ")}. Check README and CHANGELOG for more up-to-date ways of getting the same functionality.`); } } /** * Loads a specific module. - * * @param {string} module The name of the module (including subpath). - * @param {Function} callback Function to be called after loading */ - function loadModule(module, callback) { + function loadModule (module) { const elements = module.split("/"); const moduleName = elements[elements.length - 1]; let moduleFolder = `${__dirname}/../modules/${module}`; @@ -113,6 +161,14 @@ function App() { moduleFolder = `${__dirname}/../modules/default/${module}`; } + const moduleFile = `${moduleFolder}/${module}.js`; + + try { + fs.accessSync(moduleFile, fs.R_OK); + } catch (e) { + Log.warn(`No ${moduleFile} found for module: ${moduleName}.`); + } + const helperPath = `${moduleFolder}/node_helper.js`; let loadHelper = true; @@ -141,50 +197,33 @@ function App() { m.setPath(path.resolve(moduleFolder)); nodeHelpers.push(m); - m.loaded(callback); - } else { - callback(); + m.loaded(); } } /** * Loads all modules. - * * @param {Module[]} modules All modules to be loaded - * @param {Function} callback Function to be called after loading + * @returns {Promise} A promise that is resolved when all modules been loaded */ - function loadModules(modules, callback) { + async function loadModules (modules) { Log.log("Loading module helpers ..."); - /** - * - */ - function loadNextModule() { - if (modules.length > 0) { - const nextModule = modules[0]; - loadModule(nextModule, function () { - modules = modules.slice(1); - loadNextModule(); - }); - } else { - // All modules are loaded - Log.log("All module helpers loaded."); - callback(); - } + for (let module of modules) { + await loadModule(module); } - loadNextModule(); + Log.log("All module helpers loaded."); } /** * Compare two semantic version numbers and return the difference. - * * @param {string} a Version number a. * @param {string} b Version number b. * @returns {number} A positive number if a is larger than b, a negative * number if a is smaller and 0 if they are the same */ - function cmpVersions(a, b) { + function cmpVersions (a, b) { let i, diff; const regExStrip0 = /(\.0+)+$/; const segmentsA = a.replace(regExStrip0, "").split("."); @@ -203,58 +242,53 @@ function App() { /** * Start the core app. * - * It loads the config, then it loads all modules. When it's done it - * executes the callback with the config as argument. - * - * @param {Function} callback Function to be called after start + * It loads the config, then it loads all modules. + * @async + * @returns {Promise} the config used */ - this.start = function (callback) { - loadConfig(function (c) { - config = c; + this.start = async function () { + config = await loadConfig(); - Log.setLogLevel(config.logLevel); + Log.setLogLevel(config.logLevel); - let modules = []; + let modules = []; + for (const module of config.modules) { + if (!modules.includes(module.module) && !module.disabled) { + modules.push(module.module); + } + } - for (const module of config.modules) { - if (!modules.includes(module.module) && !module.disabled) { - modules.push(module.module); - } + await loadModules(modules); + + httpServer = new Server(config); + const { app, io } = await httpServer.open(); + Log.log("Server started ..."); + + const nodePromises = []; + for (let nodeHelper of nodeHelpers) { + nodeHelper.setExpressApp(app); + nodeHelper.setSocketIO(io); + + try { + nodePromises.push(nodeHelper.start()); + } catch (error) { + Log.error(`Error when starting node_helper for module ${nodeHelper.name}:`); + Log.error(error); } + } - loadModules(modules, async function () { - httpServer = new Server(config); - const { app, io } = await httpServer.open(); - Log.log("Server started ..."); - - const nodePromises = []; - for (let nodeHelper of nodeHelpers) { - nodeHelper.setExpressApp(app); - nodeHelper.setSocketIO(io); - - try { - nodePromises.push(nodeHelper.start()); - } catch (error) { - Log.error(`Error when starting node_helper for module ${nodeHelper.name}:`); - Log.error(error); - } - } + const results = await Promise.allSettled(nodePromises); - Promise.allSettled(nodePromises).then((results) => { - // Log errors that happened during async node_helper startup - results.forEach((result) => { - if (result.status === "rejected") { - Log.error(result.reason); - } - }); - - Log.log("Sockets connected & modules started ..."); - if (typeof callback === "function") { - callback(config); - } - }); - }); + // Log errors that happened during async node_helper startup + results.forEach((result) => { + if (result.status === "rejected") { + Log.error(result.reason); + } }); + + Log.log("Sockets connected & modules started ..."); + + return config; }; /** @@ -262,16 +296,40 @@ function App() { * exists. * * Added to fix #1056 - * - * @param {Function} callback Function to be called after the app has stopped + * @returns {Promise} A promise that is resolved when all node_helpers and + * the http server has been closed */ - this.stop = function (callback) { - for (const nodeHelper of nodeHelpers) { - if (typeof nodeHelper.stop === "function") { - nodeHelper.stop(); + this.stop = async function () { + const nodePromises = []; + for (let nodeHelper of nodeHelpers) { + try { + if (typeof nodeHelper.stop === "function") { + nodePromises.push(nodeHelper.stop()); + } + } catch (error) { + Log.error(`Error when stopping node_helper for module ${nodeHelper.name}:`); + console.error(error); } } - httpServer.close().then(callback); + + const results = await Promise.allSettled(nodePromises); + + // Log errors that happened during async node_helper stopping + results.forEach((result) => { + if (result.status === "rejected") { + Log.error(result.reason); + } + }); + + Log.log("Node_helpers stopped ..."); + + // To be able to stop the app even if it hasn't been started (when + // running with Electron against another server) + if (!httpServer) { + return Promise.resolve(); + } + + return httpServer.close(); }; /** @@ -281,12 +339,12 @@ function App() { * Note: this is only used if running `server-only`. Otherwise * this.stop() is called by app.on("before-quit"... in `electron.js` */ - process.on("SIGINT", () => { + process.on("SIGINT", async () => { Log.log("[SIGINT] Received. Shutting down server..."); setTimeout(() => { process.exit(0); }, 3000); // Force quit after 3 seconds - this.stop(); + await this.stop(); process.exit(0); }); @@ -294,12 +352,12 @@ function App() { * Listen to SIGTERM signals so we can stop everything when we * are asked to stop by the OS. */ - process.on("SIGTERM", () => { + process.on("SIGTERM", async () => { Log.log("[SIGTERM] Received. Shutting down server..."); setTimeout(() => { process.exit(0); }, 3000); // Force quit after 3 seconds - this.stop(); + await this.stop(); process.exit(0); }); } diff --git a/js/check_config.js b/js/check_config.js index abc0940b09..ec5ebcae66 100644 --- a/js/check_config.js +++ b/js/check_config.js @@ -1,27 +1,19 @@ -/* MagicMirror² - * - * Check the configuration file for errors - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ -const Linter = require("eslint").Linter; -const linter = new Linter(); +const path = require("node:path"); +const fs = require("node:fs"); +const colors = require("ansis"); +const { Linter } = require("eslint"); -const path = require("path"); -const fs = require("fs"); +const linter = new Linter(); const rootPath = path.resolve(`${__dirname}/../`); const Log = require(`${rootPath}/js/logger.js`); -const Utils = require(`${rootPath}/js/utils.js`); /** * Returns a string with path of configuration file. * Check if set by environment variable MM_CONFIG_FILE - * * @returns {string} path and filename of the config file */ -function getConfigFile() { +function getConfigFile () { // FIXME: This function should be in core. Do you want refactor me ;) ?, be good! return path.resolve(process.env.MM_CONFIG_FILE || `${rootPath}/config/config.js`); } @@ -29,12 +21,12 @@ function getConfigFile() { /** * Checks the config file using eslint. */ -function checkConfigFile() { +function checkConfigFile () { const configFileName = getConfigFile(); // Check if file is present if (fs.existsSync(configFileName) === false) { - Log.error(Utils.colors.error("File not found: "), configFileName); + Log.error(`File not found: ${configFileName}`); throw new Error("No config file present!"); } @@ -42,12 +34,12 @@ function checkConfigFile() { try { fs.accessSync(configFileName, fs.F_OK); } catch (e) { - Log.error(Utils.colors.error(e)); + Log.error(e); throw new Error("No permission to access config file!"); } // Validate syntax of the configuration file. - Log.info(Utils.colors.info("Checking file... "), configFileName); + Log.info("Checking file... ", configFileName); // I'm not sure if all ever is utf-8 const configFile = fs.readFileSync(configFileName, "utf-8"); @@ -60,9 +52,9 @@ function checkConfigFile() { }); if (errors.length === 0) { - Log.info(Utils.colors.pass("Your configuration file doesn't contain syntax errors :)")); + Log.info(colors.green("Your configuration file doesn't contain syntax errors :)")); } else { - Log.error(Utils.colors.error("Your configuration file contains syntax errors :(")); + Log.error(colors.red("Your configuration file contains syntax errors :(")); for (const error of errors) { Log.error(`Line ${error.line} column ${error.column}: ${error.message}`); diff --git a/js/class.js b/js/class.js index 339e24b2a6..c3a0ab22eb 100644 --- a/js/class.js +++ b/js/class.js @@ -9,7 +9,7 @@ */ (function () { let initializing = false; - const fnTest = /xyz/.test(function () { + const fnTest = (/xyz/).test(function () { xyz; }) ? /\b_super\b/ @@ -36,31 +36,31 @@ // Copy the properties over onto the new prototype for (const name in prop) { // Check if we're overwriting an existing function - prototype[name] = - typeof prop[name] === "function" && typeof _super[name] === "function" && fnTest.test(prop[name]) + prototype[name] + = typeof prop[name] === "function" && typeof _super[name] === "function" && fnTest.test(prop[name]) ? (function (name, fn) { - return function () { - const tmp = this._super; + return function () { + const tmp = this._super; - // Add a new ._super() method that is the same method - // but on the super-class - this._super = _super[name]; + // Add a new ._super() method that is the same method + // but on the super-class + this._super = _super[name]; - // The method only need to be bound temporarily, so we - // remove it when we're done executing - const ret = fn.apply(this, arguments); - this._super = tmp; + // The method only need to be bound temporarily, so we + // remove it when we're done executing + const ret = fn.apply(this, arguments); + this._super = tmp; - return ret; - }; - })(name, prop[name]) + return ret; + }; + }(name, prop[name])) : prop[name]; } /** * The dummy class constructor */ - function Class() { + function Class () { // All construction is actually done in the init method if (!initializing && this.init) { this.init.apply(this, arguments); @@ -78,19 +78,22 @@ return Class; }; -})(); +}()); /** * Define the clone method for later use. Helper Method. - * * @param {object} obj Object to be cloned * @returns {object} the cloned object */ -function cloneObject(obj) { +function cloneObject (obj) { if (obj === null || typeof obj !== "object") { return obj; } + if (obj.constructor.name === "RegExp") { + return new RegExp(obj); + } + const temp = obj.constructor(); // give temp the original obj's constructor for (const key in obj) { temp[key] = cloneObject(obj[key]); diff --git a/js/defaults.js b/js/defaults.js index b2edb8e4ff..c4efa77e95 100644 --- a/js/defaults.js +++ b/js/defaults.js @@ -1,11 +1,5 @@ /* global mmPort */ -/* MagicMirror² - * Config Defaults - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. - */ const address = "localhost"; let port = 8080; if (typeof mmPort !== "undefined") { @@ -26,9 +20,14 @@ const defaults = { zoom: 1, customCss: "css/custom.css", // httpHeaders used by helmet, see https://helmetjs.github.io/. You can add other/more object values by overriding this in config.js, - // e.g. you need to add `frameguard: false` for embedding MagicMirror in another website, see https://github.com/MichMich/MagicMirror/issues/2847 + // e.g. you need to add `frameguard: false` for embedding MagicMirror in another website, see https://github.com/MagicMirrorOrg/MagicMirror/issues/2847 httpHeaders: { contentSecurityPolicy: false, crossOriginOpenerPolicy: false, crossOriginEmbedderPolicy: false, crossOriginResourcePolicy: false, originAgentCluster: false }, + // properties for checking if server is alive and has same startup-timestamp, the check is per default enabled + // (interval 30 seconds). If startup-timestamp has changed the client reloads the magicmirror webpage. + checkServerInterval: 30 * 1000, + reloadAfterServerRestart: false, + modules: [ { module: "updatenotification", diff --git a/js/deprecated.js b/js/deprecated.js index e2c70322ac..b0aca56ca0 100644 --- a/js/deprecated.js +++ b/js/deprecated.js @@ -1,11 +1,3 @@ -/* MagicMirror² Deprecated Config Options List - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. - * - * Olex S. original idea this deprecated option - */ - module.exports = { configs: ["kioskmode"] }; diff --git a/js/electron.js b/js/electron.js index ac58657c30..2dfde6728a 100644 --- a/js/electron.js +++ b/js/electron.js @@ -1,16 +1,17 @@ "use strict"; const electron = require("electron"); -const core = require("./app.js"); -const Log = require("logger"); +const core = require("./app"); +const Log = require("./logger"); // Config let config = process.env.config ? JSON.parse(process.env.config) : {}; // Module to control application life. const app = electron.app; -// If ELECTRON_DISABLE_GPU is set electron is started with --disable-gpu flag. +// Per default electron is started with --disable-gpu flag, if you want the gpu enabled, +// you must set the env var ELECTRON_ENABLE_GPU=1 on startup. // See https://www.electronjs.org/docs/latest/tutorial/offscreen-rendering for more info. -if (process.env.ELECTRON_DISABLE_GPU !== undefined) { +if (process.env.ELECTRON_ENABLE_GPU !== "1") { app.disableHardwareAcceleration(); } @@ -24,12 +25,22 @@ let mainWindow; /** * */ -function createWindow() { +function createWindow () { + // see https://www.electronjs.org/docs/latest/api/screen + // Create a window that fills the screen's available work area. + let electronSize = (800, 600); + try { + electronSize = electron.screen.getPrimaryDisplay().workAreaSize; + } catch { + Log.warn("Could not get display size, using defaults ..."); + } + let electronSwitchesDefaults = ["autoplay-policy", "no-user-gesture-required"]; app.commandLine.appendSwitch(...new Set(electronSwitchesDefaults, config.electronSwitches)); let electronOptionsDefaults = { - width: 800, - height: 600, + width: electronSize.width, + height: electronSize.height, + icon: "mm2.png", x: 0, y: 0, darkTheme: true, @@ -46,8 +57,11 @@ function createWindow() { if (config.kioskmode) { electronOptionsDefaults.kiosk = true; } else { + electronOptionsDefaults.show = false; + electronOptionsDefaults.frame = false; + electronOptionsDefaults.transparent = true; + electronOptionsDefaults.hasShadow = false; electronOptionsDefaults.fullscreen = true; - electronOptionsDefaults.autoHideMenuBar = true; } const electronOptions = Object.assign({}, electronOptionsDefaults, config.electronOptions); @@ -65,8 +79,9 @@ function createWindow() { prefix = "http://"; } - let address = (config.address === void 0) | (config.address === "") ? (config.address = "localhost") : config.address; - mainWindow.loadURL(`${prefix}${address}:${config.port}`); + let address = (config.address === void 0) | (config.address === "") | (config.address === "0.0.0.0") ? (config.address = "localhost") : config.address; + const port = process.env.MM_PORT || config.port; + mainWindow.loadURL(`${prefix}${address}:${port}`); // Open the DevTools if run with "npm start dev" if (process.argv.includes("dev")) { @@ -108,23 +123,20 @@ function createWindow() { 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]))); + 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]))); + 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 -// initialization and is ready to create browser windows. -app.on("ready", function () { - Log.log("Launching application."); - createWindow(); -}); + mainWindow.once("ready-to-show", () => { + mainWindow.show(); + }); +} // Quit when all windows are closed. app.on("window-all-closed", function () { @@ -150,27 +162,39 @@ app.on("activate", function () { * Note: this is only used if running Electron. Otherwise * core.stop() is called by process.on("SIGINT"... in `app.js` */ -app.on("before-quit", (event) => { +app.on("before-quit", async (event) => { Log.log("Shutting down server..."); event.preventDefault(); setTimeout(() => { process.exit(0); }, 3000); // Force-quit after 3 seconds. - core.stop(); + await core.stop(); process.exit(0); }); -/* handle errors from self signed certificates */ - +/** + * Handle errors from self-signed certificates + */ app.on("certificate-error", (event, webContents, url, error, certificate, callback) => { event.preventDefault(); callback(true); }); +if (process.env.clientonly) { + app.whenReady().then(() => { + Log.log("Launching client viewer application."); + createWindow(); + }); +} + // Start the core application if server is run on localhost // This starts all node helpers and starts the webserver. if (["localhost", "127.0.0.1", "::1", "::ffff:127.0.0.1", undefined].includes(config.address)) { - core.start(function (c) { + core.start().then((c) => { config = c; + app.whenReady().then(() => { + Log.log("Launching application."); + createWindow(); + }); }); } diff --git a/js/fetch.js b/js/fetch.js deleted file mode 100644 index 3ae874c813..0000000000 --- a/js/fetch.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * 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); - // } - const nodefetch = require("node-fetch"); - return nodefetch(url, options); -} - -module.exports = fetch; diff --git a/js/loader.js b/js/loader.js index 70ed32c5fe..0d59858c77 100644 --- a/js/loader.js +++ b/js/loader.js @@ -1,12 +1,7 @@ /* global defaultModules, vendor */ -/* MagicMirror² - * Module and File loaders. - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. - */ const Loader = (function () { + /* Create helper variables */ const loadedModuleFiles = []; @@ -16,40 +11,27 @@ const Loader = (function () { /* Private Methods */ /** - * Loops thru all modules and requests load for every module. + * Loops through all modules and requests start for every module. */ - const loadModules = function () { - let moduleData = getModuleData(); - - const loadNextModule = function () { - if (moduleData.length > 0) { - const nextModule = moduleData[0]; - loadModule(nextModule, function () { - moduleData = moduleData.slice(1); - loadNextModule(); - }); - } else { - // All modules loaded. Load custom.css - // This is done after all the modules so we can - // overwrite all the defined styles. - - loadFile(config.customCss, function () { - // custom.css loaded. Start all modules. - startModules(); - }); + const startModules = async function () { + const modulePromises = []; + for (const module of moduleObjects) { + try { + modulePromises.push(module.start()); + } catch (error) { + Log.error(`Error when starting node_helper for module ${module.name}:`); + Log.error(error); } - }; + } - loadNextModule(); - }; + const results = await Promise.allSettled(modulePromises); - /** - * Loops thru all modules and requests start for every module. - */ - const startModules = function () { - for (const module of moduleObjects) { - module.start(); - } + // Log errors that happened during async node_helper startup + results.forEach((result) => { + if (result.status === "rejected") { + Log.error(result.reason); + } + }); // Notify core of loaded modules. MM.modulesStarted(moduleObjects); @@ -57,7 +39,7 @@ const Loader = (function () { // Starting modules also hides any modules that have requested to be initially hidden for (const thisModule of moduleObjects) { if (thisModule.data.hiddenOnStartup) { - Log.info("Initially hiding " + thisModule.name); + Log.info(`Initially hiding ${thisModule.name}`); thisModule.hide(); } } @@ -65,7 +47,6 @@ const Loader = (function () { /** * Retrieve list of all modules. - * * @returns {object[]} module data as configured in config */ const getAllModules = function () { @@ -74,7 +55,6 @@ const Loader = (function () { /** * Generate array with module information including module paths. - * * @returns {object[]} Module information. */ const getModuleData = function () { @@ -86,10 +66,10 @@ const Loader = (function () { const elements = module.split("/"); const moduleName = elements[elements.length - 1]; - let moduleFolder = config.paths.modules + "/" + module; + let moduleFolder = `${config.paths.modules}/${module}`; if (defaultModules.indexOf(moduleName) !== -1) { - moduleFolder = config.paths.modules + "/default/" + module; + moduleFolder = `${config.paths.modules}/default/${module}`; } if (moduleData.disabled === true) { @@ -98,16 +78,18 @@ const Loader = (function () { moduleFiles.push({ index: index, - identifier: "module_" + index + "_" + module, + identifier: `module_${index}_${module}`, name: moduleName, - path: moduleFolder + "/", - file: moduleName + ".js", + path: `${moduleFolder}/`, + file: `${moduleName}.js`, position: moduleData.position, + animateIn: moduleData.animateIn, + animateOut: moduleData.animateOut, hiddenOnStartup: moduleData.hiddenOnStartup, header: moduleData.header, configDeepMerge: typeof moduleData.configDeepMerge === "boolean" ? moduleData.configDeepMerge : false, config: moduleData.config, - classes: typeof moduleData.classes !== "undefined" ? moduleData.classes + " " + module : module + classes: typeof moduleData.classes !== "undefined" ? `${moduleData.classes} ${module}` : module }); }); @@ -115,134 +97,138 @@ const Loader = (function () { }; /** - * Load modules via ajax request and create module objects.s - * + * Load modules via ajax request and create module objects. * @param {object} module Information about the module we want to load. - * @param {Function} callback Function called when done. + * @returns {Promise} resolved when module is loaded */ - const loadModule = function (module, callback) { + const loadModule = async function (module) { const url = module.path + module.file; - const afterLoad = function () { + /** + * @returns {Promise} + */ + const afterLoad = async function () { const moduleObject = Module.create(module.name); if (moduleObject) { - bootstrapModule(module, moduleObject, function () { - callback(); - }); - } else { - callback(); + await bootstrapModule(module, moduleObject); } }; if (loadedModuleFiles.indexOf(url) !== -1) { - afterLoad(); + await afterLoad(); } else { - loadFile(url, function () { - loadedModuleFiles.push(url); - afterLoad(); - }); + await loadFile(url); + loadedModuleFiles.push(url); + await afterLoad(); } }; /** * Bootstrap modules by setting the module data and loading the scripts & styles. - * * @param {object} module Information about the module we want to load. * @param {Module} mObj Modules instance. - * @param {Function} callback Function called when done. */ - const bootstrapModule = function (module, mObj, callback) { - Log.info("Bootstrapping module: " + module.name); - + const bootstrapModule = async function (module, mObj) { + Log.info(`Bootstrapping module: ${module.name}`); mObj.setData(module); - mObj.loadScripts(function () { - Log.log("Scripts loaded for: " + module.name); - mObj.loadStyles(function () { - Log.log("Styles loaded for: " + module.name); - mObj.loadTranslations(function () { - Log.log("Translations loaded for: " + module.name); - moduleObjects.push(mObj); - callback(); - }); - }); - }); + await mObj.loadScripts(); + Log.log(`Scripts loaded for: ${module.name}`); + + await mObj.loadStyles(); + Log.log(`Styles loaded for: ${module.name}`); + + await mObj.loadTranslations(); + Log.log(`Translations loaded for: ${module.name}`); + + moduleObjects.push(mObj); }; /** * Load a script or stylesheet by adding it to the dom. - * * @param {string} fileName Path of the file we want to load. - * @param {Function} callback Function called when done. + * @returns {Promise} resolved when the file is loaded */ - const loadFile = function (fileName, callback) { + const loadFile = async function (fileName) { const extension = fileName.slice((Math.max(0, fileName.lastIndexOf(".")) || Infinity) + 1); let script, stylesheet; switch (extension.toLowerCase()) { case "js": - Log.log("Load script: " + fileName); - script = document.createElement("script"); - script.type = "text/javascript"; - script.src = fileName; - script.onload = function () { - if (typeof callback === "function") { - callback(); - } - }; - script.onerror = function () { - Log.error("Error on loading script:", fileName); - if (typeof callback === "function") { - callback(); - } - }; - - document.getElementsByTagName("body")[0].appendChild(script); - break; + return new Promise((resolve) => { + Log.log(`Load script: ${fileName}`); + script = document.createElement("script"); + script.type = "text/javascript"; + script.src = fileName; + script.onload = function () { + resolve(); + }; + script.onerror = function () { + Log.error("Error on loading script:", fileName); + resolve(); + }; + document.getElementsByTagName("body")[0].appendChild(script); + }); case "css": - Log.log("Load stylesheet: " + fileName); - stylesheet = document.createElement("link"); - stylesheet.rel = "stylesheet"; - stylesheet.type = "text/css"; - stylesheet.href = fileName; - stylesheet.onload = function () { - if (typeof callback === "function") { - callback(); - } - }; - stylesheet.onerror = function () { - Log.error("Error on loading stylesheet:", fileName); - if (typeof callback === "function") { - callback(); - } - }; - - document.getElementsByTagName("head")[0].appendChild(stylesheet); - break; + return new Promise((resolve) => { + Log.log(`Load stylesheet: ${fileName}`); + + stylesheet = document.createElement("link"); + stylesheet.rel = "stylesheet"; + stylesheet.type = "text/css"; + stylesheet.href = fileName; + stylesheet.onload = function () { + resolve(); + }; + stylesheet.onerror = function () { + Log.error("Error on loading stylesheet:", fileName); + resolve(); + }; + document.getElementsByTagName("head")[0].appendChild(stylesheet); + }); } }; /* Public Methods */ return { + /** * Load all modules as defined in the config. */ - loadModules: function () { - loadModules(); + async loadModules () { + let moduleData = getModuleData(); + + /** + * @returns {Promise} when all modules are loaded + */ + const loadNextModule = async function () { + if (moduleData.length > 0) { + const nextModule = moduleData[0]; + await loadModule(nextModule); + moduleData = moduleData.slice(1); + await loadNextModule(); + } else { + // All modules loaded. Load custom.css + // This is done after all the modules so we can + // overwrite all the defined styles. + await loadFile(config.customCss); + // custom.css loaded. Start all modules. + await startModules(); + } + }; + await loadNextModule(); }, /** * Load a file (script or stylesheet). * Prevent double loading and search for files in the vendor folder. - * * @param {string} fileName Path of the file we want to load. * @param {Module} module The module that calls the loadFile function. - * @param {Function} callback Function called when done. + * @returns {Promise} resolved when the file is loaded */ - loadFile: function (fileName, module, callback) { + async loadFileForModule (fileName, module) { if (loadedFiles.indexOf(fileName.toLowerCase()) !== -1) { - Log.log("File already loaded: " + fileName); - callback(); + Log.log(`File already loaded: ${fileName}`); return; } @@ -250,22 +236,20 @@ const Loader = (function () { // This is an absolute or relative path. // Load it and then return. loadedFiles.push(fileName.toLowerCase()); - loadFile(fileName, callback); - return; + return loadFile(fileName); } if (vendor[fileName] !== undefined) { // This file is available in the vendor folder. // Load it from this vendor folder. loadedFiles.push(fileName.toLowerCase()); - loadFile(config.paths.vendor + "/" + vendor[fileName], callback); - return; + return loadFile(`${config.paths.vendor}/${vendor[fileName]}`); } // File not loaded yet. // Load it based on the module path. loadedFiles.push(fileName.toLowerCase()); - loadFile(module.file(fileName), callback); + return loadFile(module.file(fileName)); } }; -})(); +}()); diff --git a/js/logger.js b/js/logger.js index e6a244cb73..0c254082c4 100644 --- a/js/logger.js +++ b/js/logger.js @@ -1,19 +1,40 @@ -/* MagicMirror² - * Log - * - * This logger is very simple, but needs to be extended. - * This system can eventually be used to push the log messages to an external target. - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. - */ +// This logger is very simple, but needs to be extended. (function (root, factory) { if (typeof exports === "object") { if (process.env.JEST_WORKER_ID === undefined) { + const colors = require("ansis"); + // add timestamps in front of log messages require("console-stamp")(console, { - pattern: "yyyy-mm-dd HH:MM:ss.l", - include: ["debug", "log", "info", "warn", "error"] + format: ":date(yyyy-mm-dd HH:MM:ss.l) :label(7) :msg", + tokens: { + label: (arg) => { + const { method, defaultTokens } = arg; + let label = defaultTokens.label(arg); + if (method === "error") { + label = colors.red(label); + } else if (method === "warn") { + label = colors.yellow(label); + } else if (method === "debug") { + label = colors.bgBlue(label); + } else if (method === "info") { + label = colors.blue(label); + } + return label; + }, + msg: (arg) => { + const { method, defaultTokens } = arg; + let msg = defaultTokens.msg(arg); + if (method === "error") { + msg = colors.red(msg); + } else if (method === "warn") { + msg = colors.yellow(msg); + } else if (method === "info") { + msg = colors.blue(msg); + } + return msg; + } + } }); } // Node, CommonJS-like @@ -22,7 +43,7 @@ // Browser globals (root is window) root.Log = factory(root.config); } -})(this, function (config) { +}(this, function (config) { let logLevel; let enableLog; if (typeof exports === "object") { @@ -50,7 +71,7 @@ logLevel.setLogLevel = function (newLevel) { if (newLevel) { - Object.keys(logLevel).forEach(function (key, index) { + Object.keys(logLevel).forEach(function (key) { if (!newLevel.includes(key.toLocaleUpperCase())) { logLevel[key] = function () {}; } @@ -59,21 +80,21 @@ }; } else { logLevel = { - debug: function () {}, - log: function () {}, - info: function () {}, - warn: function () {}, - error: function () {}, - group: function () {}, - groupCollapsed: function () {}, - groupEnd: function () {}, - time: function () {}, - timeEnd: function () {}, - timeStamp: function () {} + debug () {}, + log () {}, + info () {}, + warn () {}, + error () {}, + group () {}, + groupCollapsed () {}, + groupEnd () {}, + time () {}, + timeEnd () {}, + timeStamp () {} }; logLevel.setLogLevel = function () {}; } return logLevel; -}); +})); diff --git a/js/main.js b/js/main.js index 3eed494bff..43ec02ad87 100644 --- a/js/main.js +++ b/js/main.js @@ -1,11 +1,5 @@ -/* global Loader, defaults, Translator */ - -/* MagicMirror² - * Main System - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. - */ +/* global Loader, defaults, Translator, addAnimateCSS, removeAnimateCSS, AnimateCSSIn, AnimateCSSOut */ + const MM = (function () { let modules = []; @@ -22,6 +16,10 @@ const MM = (function () { return; } + let haveAnimateIn = null; + // check if have valid animateIn in module definition (module.data.animateIn) + if (module.data.animateIn && AnimateCSSIn.indexOf(module.data.animateIn) !== -1) haveAnimateIn = module.data.animateIn; + const wrapper = selectWrapper(module.data.position); const dom = document.createElement("div"); @@ -29,7 +27,7 @@ const MM = (function () { dom.className = module.name; if (typeof module.data.classes === "string") { - dom.className = "module " + dom.className + " " + module.data.classes; + dom.className = `module ${dom.className} ${module.data.classes}`; } dom.opacity = 0; @@ -50,7 +48,12 @@ const MM = (function () { moduleContent.className = "module-content"; dom.appendChild(moduleContent); - const domCreationPromise = updateDom(module, 0); + // create the domCreationPromise with AnimateCSS (with animateIn of module definition) + // or just display it + var domCreationPromise; + if (haveAnimateIn) domCreationPromise = updateDom(module, { options: { speed: 1000, animate: { in: haveAnimateIn } } }, true); + else domCreationPromise = updateDom(module, 0); + domCreationPromises.push(domCreationPromise); domCreationPromise .then(function () { @@ -68,7 +71,6 @@ const MM = (function () { /** * Select the wrapper dom object for a specific position. - * * @param {string} position The name of the position. * @returns {HTMLElement | void} the wrapper element */ @@ -85,7 +87,6 @@ const MM = (function () { /** * Send a notification to all modules. - * * @param {string} notification The identifier of the notification. * @param {*} payload The payload of the notification. * @param {Module} sender The module that sent the notification. @@ -102,13 +103,31 @@ const MM = (function () { /** * Update the dom for a specific module. - * * @param {Module} module The module that needs an update. - * @param {number} [speed] The (optional) number of microseconds for the animation. + * @param {object|number} [updateOptions] The (optional) number of microseconds for the animation or object with updateOptions (speed/animates) + * @param {boolean} [createAnimatedDom] for displaying only animateIn (used on first start of MagicMirror) * @returns {Promise} Resolved when the dom is fully updated. */ - const updateDom = function (module, speed) { + const updateDom = function (module, updateOptions, createAnimatedDom = false) { return new Promise(function (resolve) { + let speed = updateOptions; + let animateOut = null; + let animateIn = null; + if (typeof updateOptions === "object") { + if (typeof updateOptions.options === "object" && updateOptions.options.speed !== undefined) { + speed = updateOptions.options.speed; + Log.debug(`updateDom: ${module.identifier} Has speed in object: ${speed}`); + if (typeof updateOptions.options.animate === "object") { + animateOut = updateOptions.options.animate.out; + animateIn = updateOptions.options.animate.in; + Log.debug(`updateDom: ${module.identifier} Has animate in object: out->${animateOut}, in->${animateIn}`); + } + } else { + Log.debug(`updateDom: ${module.identifier} Has no speed in object`); + speed = 0; + } + } + const newHeader = module.getHeader(); let newContentPromise = module.getDom(); @@ -119,7 +138,7 @@ const MM = (function () { newContentPromise .then(function (newContent) { - const updatePromise = updateDomWithContent(module, speed, newHeader, newContent); + const updatePromise = updateDomWithContent(module, speed, newHeader, newContent, animateOut, animateIn, createAnimatedDom); updatePromise.then(resolve).catch(Log.error); }) @@ -129,14 +148,16 @@ const MM = (function () { /** * Update the dom with the specified content - * * @param {Module} module The module that needs an update. * @param {number} [speed] The (optional) number of microseconds for the animation. * @param {string} newHeader The new header that is generated. * @param {HTMLElement} newContent The new content that is generated. + * @param {string} [animateOut] AnimateCss animation name before hidden + * @param {string} [animateIn] AnimateCss animation name on show + * @param {boolean} [createAnimatedDom] for displaying only animateIn (used on first start) * @returns {Promise} Resolved when the module dom has been updated. */ - const updateDomWithContent = function (module, speed, newHeader, newContent) { + const updateDomWithContent = function (module, speed, newHeader, newContent, animateOut, animateIn, createAnimatedDom = false) { return new Promise(function (resolve) { if (module.hidden || !speed) { updateModuleContent(module, newHeader, newContent); @@ -155,19 +176,33 @@ const MM = (function () { return; } - hideModule(module, speed / 2, function () { + if (createAnimatedDom && animateIn !== null) { + Log.debug(`${module.identifier} createAnimatedDom (${animateIn})`); updateModuleContent(module, newHeader, newContent); if (!module.hidden) { - showModule(module, speed / 2); + showModule(module, speed, null, { animate: animateIn }); } resolve(); - }); + return; + } + + hideModule( + module, + speed / 2, + function () { + updateModuleContent(module, newHeader, newContent); + if (!module.hidden) { + showModule(module, speed / 2, null, { animate: animateIn }); + } + resolve(); + }, + { animate: animateOut } + ); }); }; /** * Check if the content has changed. - * * @param {Module} module The module to check. * @param {string} newHeader The new header that is generated. * @param {HTMLElement} newContent The new content that is generated. @@ -198,7 +233,6 @@ const MM = (function () { /** * Update the content of a module on screen. - * * @param {Module} module The module to check. * @param {string} newHeader The new header that is generated. * @param {HTMLElement} newContent The new content that is generated. @@ -224,15 +258,12 @@ const MM = (function () { /** * Hide the module. - * * @param {Module} module The module to hide. * @param {number} speed The speed of the hide animation. * @param {Function} callback Called when the animation is done. * @param {object} [options] Optional settings for the hide method. */ - const hideModule = function (module, speed, callback, options) { - options = options || {}; - + const hideModule = function (module, speed, callback, options = {}) { // set lockString if set in options. if (options.lockString) { // Log.log("Has lockstring: " + options.lockString); @@ -243,24 +274,65 @@ const MM = (function () { const moduleWrapper = document.getElementById(module.identifier); if (moduleWrapper !== null) { - moduleWrapper.style.transition = "opacity " + speed / 1000 + "s"; - moduleWrapper.style.opacity = 0; - moduleWrapper.classList.add("hidden"); - clearTimeout(module.showHideTimer); - module.showHideTimer = setTimeout(function () { - // To not take up any space, we just make the position absolute. - // since it's fade out anyway, we can see it lay above or - // below other modules. This works way better than adjusting - // the .display property. - moduleWrapper.style.position = "fixed"; - - updateWrapperStates(); - - if (typeof callback === "function") { - callback(); - } - }, speed); + // reset all animations if needed + if (module.hasAnimateOut) { + removeAnimateCSS(module.identifier, module.hasAnimateOut); + Log.debug(`${module.identifier} Force remove animateOut (in hide): ${module.hasAnimateOut}`); + module.hasAnimateOut = false; + } + if (module.hasAnimateIn) { + removeAnimateCSS(module.identifier, module.hasAnimateIn); + Log.debug(`${module.identifier} Force remove animateIn (in hide): ${module.hasAnimateIn}`); + module.hasAnimateIn = false; + } + // haveAnimateName for verify if we are using AninateCSS library + // we check AnimateCSSOut Array for validate it + // and finaly return the animate name or `null` (for default MM² animation) + let haveAnimateName = null; + // check if have valid animateOut in module definition (module.data.animateOut) + if (module.data.animateOut && AnimateCSSOut.indexOf(module.data.animateOut) !== -1) haveAnimateName = module.data.animateOut; + // can't be override with options.animate + else if (options.animate && AnimateCSSOut.indexOf(options.animate) !== -1) haveAnimateName = options.animate; + + if (haveAnimateName) { + // with AnimateCSS + Log.debug(`${module.identifier} Has animateOut: ${haveAnimateName}`); + module.hasAnimateOut = haveAnimateName; + addAnimateCSS(module.identifier, haveAnimateName, speed / 1000); + module.showHideTimer = setTimeout(function () { + removeAnimateCSS(module.identifier, haveAnimateName); + Log.debug(`${module.identifier} Remove animateOut: ${module.hasAnimateOut}`); + // AnimateCSS is now done + moduleWrapper.style.opacity = 0; + moduleWrapper.classList.add("hidden"); + moduleWrapper.style.position = "fixed"; + module.hasAnimateOut = false; + + updateWrapperStates(); + if (typeof callback === "function") { + callback(); + } + }, speed); + } else { + // default MM² Animate + moduleWrapper.style.transition = `opacity ${speed / 1000}s`; + moduleWrapper.style.opacity = 0; + moduleWrapper.classList.add("hidden"); + module.showHideTimer = setTimeout(function () { + // To not take up any space, we just make the position absolute. + // since it's fade out anyway, we can see it lay above or + // below other modules. This works way better than adjusting + // the .display property. + moduleWrapper.style.position = "fixed"; + + updateWrapperStates(); + + if (typeof callback === "function") { + callback(); + } + }, speed); + } } else { // invoke callback even if no content, issue 1308 if (typeof callback === "function") { @@ -271,15 +343,12 @@ const MM = (function () { /** * Show the module. - * * @param {Module} module The module to show. * @param {number} speed The speed of the show animation. * @param {Function} callback Called when the animation is done. * @param {object} [options] Optional settings for the show method. */ - const showModule = function (module, speed, callback, options) { - options = options || {}; - + const showModule = function (module, speed, callback, options = {}) { // remove lockString if set in options. if (options.lockString) { const index = module.lockStrings.indexOf(options.lockString); @@ -291,24 +360,46 @@ const MM = (function () { // Check if there are no more lockstrings set, or the force option is set. // Otherwise cancel show action. if (module.lockStrings.length !== 0 && options.force !== true) { - Log.log("Will not show " + module.name + ". LockStrings active: " + module.lockStrings.join(",")); + Log.log(`Will not show ${module.name}. LockStrings active: ${module.lockStrings.join(",")}`); if (typeof options.onError === "function") { options.onError(new Error("LOCK_STRING_ACTIVE")); } return; } + // reset all animations if needed + if (module.hasAnimateOut) { + removeAnimateCSS(module.identifier, module.hasAnimateOut); + Log.debug(`${module.identifier} Force remove animateOut (in show): ${module.hasAnimateOut}`); + module.hasAnimateOut = false; + } + if (module.hasAnimateIn) { + removeAnimateCSS(module.identifier, module.hasAnimateIn); + Log.debug(`${module.identifier} Force remove animateIn (in show): ${module.hasAnimateIn}`); + module.hasAnimateIn = false; + } module.hidden = false; // If forced show, clean current lockstrings. if (module.lockStrings.length !== 0 && options.force === true) { - Log.log("Force show of module: " + module.name); + Log.log(`Force show of module: ${module.name}`); module.lockStrings = []; } const moduleWrapper = document.getElementById(module.identifier); if (moduleWrapper !== null) { - moduleWrapper.style.transition = "opacity " + speed / 1000 + "s"; + clearTimeout(module.showHideTimer); + + // haveAnimateName for verify if we are using AninateCSS library + // we check AnimateCSSIn Array for validate it + // and finaly return the animate name or `null` (for default MM² animation) + let haveAnimateName = null; + // check if have valid animateOut in module definition (module.data.animateIn) + if (module.data.animateIn && AnimateCSSIn.indexOf(module.data.animateIn) !== -1) haveAnimateName = module.data.animateIn; + // can't be override with options.animate + else if (options.animate && AnimateCSSIn.indexOf(options.animate) !== -1) haveAnimateName = options.animate; + + if (!haveAnimateName) moduleWrapper.style.transition = `opacity ${speed / 1000}s`; // Restore the position. See hideModule() for more info. moduleWrapper.style.position = "static"; moduleWrapper.classList.remove("hidden"); @@ -319,12 +410,27 @@ const MM = (function () { const dummy = moduleWrapper.parentElement.parentElement.offsetHeight; moduleWrapper.style.opacity = 1; - clearTimeout(module.showHideTimer); - module.showHideTimer = setTimeout(function () { - if (typeof callback === "function") { - callback(); - } - }, speed); + if (haveAnimateName) { + // with AnimateCSS + Log.debug(`${module.identifier} Has animateIn: ${haveAnimateName}`); + module.hasAnimateIn = haveAnimateName; + addAnimateCSS(module.identifier, haveAnimateName, speed / 1000); + module.showHideTimer = setTimeout(function () { + removeAnimateCSS(module.identifier, haveAnimateName); + Log.debug(`${module.identifier} Remove animateIn: ${haveAnimateName}`); + module.hasAnimateIn = false; + if (typeof callback === "function") { + callback(); + } + }, speed); + } else { + // default MM² Animate + module.showHideTimer = setTimeout(function () { + if (typeof callback === "function") { + callback(); + } + }, speed); + } } else { // invoke callback if (typeof callback === "function") { @@ -367,7 +473,6 @@ const MM = (function () { */ const loadConfig = function () { // FIXME: Think about how to pass config around without breaking tests - /* eslint-disable */ if (typeof config === "undefined") { config = defaults; Log.error("Config file is missing! Please create a config file."); @@ -375,18 +480,16 @@ const MM = (function () { } config = Object.assign({}, defaults, config); - /* eslint-enable */ }; /** * Adds special selectors on a collection of modules. - * * @param {Module[]} modules Array of modules. */ const setSelectionMethodsForModules = function (modules) { + /** * Filter modules with the specified classes. - * * @param {string|string[]} className one or multiple classnames (array or space divided). * @returns {Module[]} Filtered collection of modules. */ @@ -396,7 +499,6 @@ const MM = (function () { /** * Filter modules without the specified classes. - * * @param {string|string[]} className one or multiple classnames (array or space divided). * @returns {Module[]} Filtered collection of modules. */ @@ -406,7 +508,6 @@ const MM = (function () { /** * Filters a collection of modules based on classname(s). - * * @param {string|string[]} className one or multiple classnames (array or space divided). * @param {boolean} include if the filter should include or exclude the modules with the specific classes. * @returns {Module[]} Filtered collection of modules. @@ -435,7 +536,6 @@ const MM = (function () { /** * Removes a module instance from the collection. - * * @param {object} module The module instance to remove from the collection. * @returns {Module[]} Filtered collection of modules. */ @@ -450,7 +550,6 @@ const MM = (function () { /** * Walks thru a collection of modules and executes the callback with the module as an argument. - * * @param {Function} callback The function to execute with the module as an argument. */ const enumerate = function (callback) { @@ -474,44 +573,64 @@ const MM = (function () { }; return { + /* Public Methods */ /** * Main init method. */ - init: function () { + async init () { Log.info("Initializing MagicMirror²."); loadConfig(); Log.setLogLevel(config.logLevel); - Translator.loadCoreTranslations(config.language); - Loader.loadModules(); + await Translator.loadCoreTranslations(config.language); + await Loader.loadModules(); }, /** * Gets called when all modules are started. - * * @param {Module[]} moduleObjects All module instances. */ - modulesStarted: function (moduleObjects) { + modulesStarted (moduleObjects) { modules = []; + let startUp = ""; + moduleObjects.forEach((module) => modules.push(module)); Log.info("All modules started!"); sendNotification("ALL_MODULES_STARTED"); createDomObjects(); + + if (config.reloadAfterServerRestart) { + setInterval(async () => { + // if server startup time has changed (which means server was restarted) + // the client reloads the mm page + try { + const res = await fetch(`${location.protocol}//${location.host}/startup`); + const curr = await res.text(); + if (startUp === "") startUp = curr; + if (startUp !== curr) { + startUp = ""; + window.location.reload(true); + console.warn("Refreshing Website because server was restarted"); + } + } catch (err) { + Log.error(`MagicMirror not reachable: ${err}`); + } + }, config.checkServerInterval); + } }, /** * Send a notification to all modules. - * * @param {string} notification The identifier of the notification. * @param {*} payload The payload of the notification. * @param {Module} sender The module that sent the notification. */ - sendNotification: function (notification, payload, sender) { + sendNotification (notification, payload, sender) { if (arguments.length < 3) { Log.error("sendNotification: Missing arguments."); return; @@ -533,11 +652,10 @@ const MM = (function () { /** * Update the dom for a specific module. - * * @param {Module} module The module that needs an update. - * @param {number} [speed] The number of microseconds for the animation. + * @param {object|number} [updateOptions] The (optional) number of microseconds for the animation or object with updateOptions (speed/animates) */ - updateDom: function (module, speed) { + updateDom (module, updateOptions) { if (!(module instanceof Module)) { Log.error("updateDom: Sender should be a module."); return; @@ -549,46 +667,43 @@ const MM = (function () { } // Further implementation is done in the private method. - updateDom(module, speed); + updateDom(module, updateOptions); }, /** * Returns a collection of all modules currently active. - * * @returns {Module[]} A collection of all modules currently active. */ - getModules: function () { + getModules () { setSelectionMethodsForModules(modules); return modules; }, /** * Hide the module. - * * @param {Module} module The module to hide. * @param {number} speed The speed of the hide animation. * @param {Function} callback Called when the animation is done. * @param {object} [options] Optional settings for the hide method. */ - hideModule: function (module, speed, callback, options) { + hideModule (module, speed, callback, options) { module.hidden = true; hideModule(module, speed, callback, options); }, /** * Show the module. - * * @param {Module} module The module to show. * @param {number} speed The speed of the show animation. * @param {Function} callback Called when the animation is done. * @param {object} [options] Optional settings for the show method. */ - showModule: function (module, speed, callback, options) { + showModule (module, speed, callback, options) { // do not change module.hidden yet, only if we really show it later showModule(module, speed, callback, options); } }; -})(); +}()); // Add polyfill for Object.assign. if (typeof Object.assign !== "function") { @@ -611,7 +726,7 @@ if (typeof Object.assign !== "function") { } return output; }; - })(); + }()); } MM.init(); diff --git a/js/module.js b/js/module.js index 6d15452994..71451763d0 100644 --- a/js/module.js +++ b/js/module.js @@ -1,13 +1,10 @@ /* global Class, cloneObject, Loader, MMSocket, nunjucks, Translator */ -/* MagicMirror² - * Module Blueprint. +/* Module Blueprint. * @typedef {Object} Module - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. */ const Module = Class.extend({ + /********************************************************* * All methods (and properties) below can be subclassed. * *********************************************************/ @@ -25,7 +22,7 @@ const Module = Class.extend({ // visibility when hiding and showing module. lockStrings: [], - // Storage of the nunjuck Environment, + // Storage of the nunjucks Environment, // This should not be referenced directly. // Use the nunjucksEnvironment() to get it. _nunjucksEnvironment: null, @@ -33,32 +30,30 @@ const Module = Class.extend({ /** * Called when the module is instantiated. */ - init: function () { + init () { //Log.log(this.defaults); }, /** * Called when the module is started. */ - start: function () { - Log.info("Starting module: " + this.name); + async start () { + Log.info(`Starting module: ${this.name}`); }, /** * Returns a list of scripts the module requires to be loaded. - * * @returns {string[]} An array with filenames. */ - getScripts: function () { + getScripts () { return []; }, /** * Returns a list of stylesheets the module requires to be loaded. - * * @returns {string[]} An array with filenames. */ - getStyles: function () { + getStyles () { return []; }, @@ -66,10 +61,9 @@ const Module = Class.extend({ * Returns a map of translation files the module requires to be loaded. * * return Map - - * * @returns {*} A map with langKeys and filenames. */ - getTranslations: function () { + getTranslations () { return false; }, @@ -77,17 +71,16 @@ const Module = Class.extend({ * Generates the dom which needs to be displayed. This method is called by the MagicMirror² core. * This method can to be subclassed if the module wants to display info on the mirror. * Alternatively, the getTemplate method could be subclassed. - * * @returns {HTMLElement|Promise} The dom or a promise with the dom to display. */ - getDom: function () { + getDom () { return new Promise((resolve) => { const div = document.createElement("div"); const template = this.getTemplate(); const templateData = this.getTemplateData(); // Check to see if we need to render a template string or a file. - if (/^.*((\.html)|(\.njk))$/.test(template)) { + if ((/^.*((\.html)|(\.njk))$/).test(template)) { // the template is a filename this.nunjucksEnvironment().render(template, templateData, function (err, res) { if (err) { @@ -111,10 +104,9 @@ const Module = Class.extend({ * Generates the header string which needs to be displayed if a user has a header configured for this module. * This method is called by the MagicMirror² core, but only if the user has configured a default header for the module. * This method needs to be subclassed if the module wants to display modified headers on the mirror. - * * @returns {string} The header to display above the header. */ - getHeader: function () { + getHeader () { return this.data.header; }, @@ -123,31 +115,28 @@ const Module = Class.extend({ * This method needs to be subclassed if the module wants to use a template. * It can either return a template sting, or a template filename. * If the string ends with '.html' it's considered a file from within the module's folder. - * * @returns {string} The template string of filename. */ - getTemplate: function () { - return '
' + this.name + '
' + this.identifier + "
"; + getTemplate () { + return `
${this.name}
${this.identifier}
`; }, /** * Returns the data to be used in the template. * This method needs to be subclassed if the module wants to use a custom data. - * * @returns {object} The data for the template */ - getTemplateData: function () { + getTemplateData () { return {}; }, /** * Called by the MagicMirror² core when a notification arrives. - * * @param {string} notification The identifier of the notification. * @param {*} payload The payload of the notification. * @param {Module} sender The module that sent the notification. */ - notificationReceived: function (notification, payload, sender) { + notificationReceived (notification, payload, sender) { if (sender) { // Log.log(this.name + " received a module notification: " + notification + " from sender: " + sender.name); } else { @@ -158,10 +147,9 @@ const Module = Class.extend({ /** * Returns the nunjucks environment for the current module. * The environment is checked in the _nunjucksEnvironment instance variable. - * * @returns {object} The Nunjucks Environment */ - nunjucksEnvironment: function () { + nunjucksEnvironment () { if (this._nunjucksEnvironment !== null) { return this._nunjucksEnvironment; } @@ -180,63 +168,61 @@ const Module = Class.extend({ /** * Called when a socket notification arrives. - * * @param {string} notification The identifier of the notification. * @param {*} payload The payload of the notification. */ - socketNotificationReceived: function (notification, payload) { - Log.log(this.name + " received a socket notification: " + notification + " - Payload: " + payload); + socketNotificationReceived (notification, payload) { + Log.log(`${this.name} received a socket notification: ${notification} - Payload: ${payload}`); }, /** * Called when the module is hidden. */ - suspend: function () { - Log.log(this.name + " is suspended."); + suspend () { + Log.log(`${this.name} is suspended.`); }, /** * Called when the module is shown. */ - resume: function () { - Log.log(this.name + " is resumed."); + resume () { + Log.log(`${this.name} is resumed.`); }, /********************************************* - * The methods below don"t need subclassing. * + * The methods below don't need subclassing. * *********************************************/ /** * Set the module data. - * * @param {object} data The module data */ - setData: function (data) { + setData (data) { this.data = data; this.name = data.name; this.identifier = data.identifier; this.hidden = false; + this.hasAnimateIn = false; + this.hasAnimateOut = false; this.setConfig(data.config, data.configDeepMerge); }, /** * Set the module config and combine it with the module defaults. - * * @param {object} config The combined module config. * @param {boolean} deep Merge module config in deep. */ - setConfig: function (config, deep) { + setConfig (config, deep) { this.config = deep ? configMerge({}, this.defaults, config) : Object.assign({}, this.defaults, config); }, /** * Returns a socket object. If it doesn't exist, it's created. * It also registers the notification callback. - * * @returns {MMSocket} a socket object */ - socket: function () { + socket () { if (typeof this._socket === "undefined") { this._socket = new MMSocket(this.name); } @@ -250,62 +236,56 @@ const Module = Class.extend({ /** * Retrieve the path to a module file. - * * @param {string} file Filename * @returns {string} the file path */ - file: function (file) { - return (this.data.path + "/" + file).replace("//", "/"); + file (file) { + return `${this.data.path}/${file}`.replace("//", "/"); }, /** * Load all required stylesheets by requesting the MM object to load the files. - * - * @param {Function} callback Function called when done. + * @returns {Promise} */ - loadStyles: function (callback) { - this.loadDependencies("getStyles", callback); + loadStyles () { + return this.loadDependencies("getStyles"); }, /** * Load all required scripts by requesting the MM object to load the files. - * - * @param {Function} callback Function called when done. + * @returns {Promise} */ - loadScripts: function (callback) { - this.loadDependencies("getScripts", callback); + loadScripts () { + return this.loadDependencies("getScripts"); }, /** * Helper method to load all dependencies. - * * @param {string} funcName Function name to call to get scripts or styles. - * @param {Function} callback Function called when done. + * @returns {Promise} */ - loadDependencies: function (funcName, callback) { + async loadDependencies (funcName) { let dependencies = this[funcName](); - const loadNextDependency = () => { + const loadNextDependency = async () => { if (dependencies.length > 0) { const nextDependency = dependencies[0]; - Loader.loadFile(nextDependency, this, () => { - dependencies = dependencies.slice(1); - loadNextDependency(); - }); + await Loader.loadFileForModule(nextDependency, this); + dependencies = dependencies.slice(1); + await loadNextDependency(); } else { - callback(); + return Promise.resolve(); } }; - loadNextDependency(); + await loadNextDependency(); }, /** * Load all translations. - * - * @param {Function} callback Function called when done. + * @returns {Promise} */ - loadTranslations(callback) { + async loadTranslations () { const translations = this.getTranslations() || {}; const language = config.language.toLowerCase(); @@ -313,7 +293,6 @@ const Module = Class.extend({ const fallbackLanguage = languages[0]; if (languages.length === 0) { - callback(); return; } @@ -321,28 +300,24 @@ const Module = Class.extend({ const translationsFallbackFile = translations[fallbackLanguage]; if (!translationFile) { - Translator.load(this, translationsFallbackFile, true, callback); - return; + return Translator.load(this, translationsFallbackFile, true); } - Translator.load(this, translationFile, false, () => { - if (translationFile !== translationsFallbackFile) { - Translator.load(this, translationsFallbackFile, true, callback); - } else { - callback(); - } - }); + await Translator.load(this, translationFile, false); + + if (translationFile !== translationsFallbackFile) { + return Translator.load(this, translationsFallbackFile, true); + } }, /** * Request the translation for a given key with optional variables and default value. - * * @param {string} key The key of the string to translate * @param {string|object} [defaultValueOrVariables] The default value or variables for translating. * @param {string} [defaultValue] The default value with variables. * @returns {string} the translated key */ - translate: function (key, defaultValueOrVariables, defaultValue) { + translate (key, defaultValueOrVariables, defaultValue) { if (typeof defaultValueOrVariables === "object") { return Translator.translate(this, key, defaultValueOrVariables) || defaultValue || ""; } @@ -351,84 +326,81 @@ const Module = Class.extend({ /** * Request an (animated) update of the module. - * - * @param {number} [speed] The speed of the animation. + * @param {number|object} [updateOptions] The speed of the animation or object with for updateOptions (speed/animates) */ - updateDom: function (speed) { - MM.updateDom(this, speed); + updateDom (updateOptions) { + MM.updateDom(this, updateOptions); }, /** * Send a notification to all modules. - * * @param {string} notification The identifier of the notification. * @param {*} payload The payload of the notification. */ - sendNotification: function (notification, payload) { + sendNotification (notification, payload) { MM.sendNotification(notification, payload, this); }, /** * Send a socket notification to the node helper. - * * @param {string} notification The identifier of the notification. * @param {*} payload The payload of the notification. */ - sendSocketNotification: function (notification, payload) { + sendSocketNotification (notification, payload) { this.socket().sendNotification(notification, payload); }, /** * Hide this module. - * * @param {number} speed The speed of the hide animation. * @param {Function} callback Called when the animation is done. * @param {object} [options] Optional settings for the hide method. */ - hide: function (speed, callback, options) { + hide (speed, callback, options = {}) { + let usedCallback = callback || function () {}; + let usedOptions = options; + if (typeof callback === "object") { - options = callback; - callback = function () {}; + Log.error("Parameter mismatch in module.hide: callback is not an optional parameter!"); + usedOptions = callback; + usedCallback = function () {}; } - callback = callback || function () {}; - options = options || {}; - MM.hideModule( this, speed, () => { this.suspend(); - callback(); + usedCallback(); }, - options + usedOptions ); }, /** * Show this module. - * * @param {number} speed The speed of the show animation. * @param {Function} callback Called when the animation is done. * @param {object} [options] Optional settings for the show method. */ - show: function (speed, callback, options) { + show (speed, callback, options) { + let usedCallback = callback || function () {}; + let usedOptions = options; + if (typeof callback === "object") { - options = callback; - callback = function () {}; + Log.error("Parameter mismatch in module.show: callback is not an optional parameter!"); + usedOptions = callback; + usedCallback = function () {}; } - callback = callback || function () {}; - options = options || {}; - MM.showModule( this, speed, () => { this.resume(); - callback(); + usedCallback(); }, - options + usedOptions ); } }); @@ -452,11 +424,10 @@ const Module = Class.extend({ * ------- * * Todo: idea of Mich determinate what do you want to merge or not - * * @param {object} result the initial object * @returns {object} the merged config */ -function configMerge(result) { +function configMerge (result) { const stack = Array.prototype.slice.call(arguments, 1); let item, key; @@ -498,15 +469,15 @@ Module.create = function (name) { Module.register = function (name, moduleDefinition) { if (moduleDefinition.requiresVersion) { - Log.log("Check MagicMirror² version for module '" + name + "' - Minimum version: " + moduleDefinition.requiresVersion + " - Current version: " + window.mmVersion); + Log.log(`Check MagicMirror² version for module '${name}' - Minimum version: ${moduleDefinition.requiresVersion} - Current version: ${window.mmVersion}`); if (cmpVersions(window.mmVersion, moduleDefinition.requiresVersion) >= 0) { Log.log("Version is ok!"); } else { - Log.warn("Version is incorrect. Skip module: '" + name + "'"); + Log.warn(`Version is incorrect. Skip module: '${name}'`); return; } } - Log.log("Module registered: " + name); + Log.log(`Module registered: ${name}`); Module.definitions[name] = moduleDefinition; }; @@ -514,13 +485,12 @@ window.Module = Module; /** * Compare two semantic version numbers and return the difference. - * * @param {string} a Version number a. * @param {string} b Version number b. * @returns {number} A positive number if a is larger than b, a negative * number if a is smaller and 0 if they are the same */ -function cmpVersions(a, b) { +function cmpVersions (a, b) { const regExStrip0 = /(\.0+)+$/; const segmentsA = a.replace(regExStrip0, "").split("."); const segmentsB = b.replace(regExStrip0, "").split("."); diff --git a/js/node_helper.js b/js/node_helper.js index fa8c568873..42da0efcff 100644 --- a/js/node_helper.js +++ b/js/node_helper.js @@ -1,24 +1,17 @@ -/* MagicMirror² - * Node Helper Superclass - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. - */ -const Class = require("./class.js"); -const Log = require("logger"); const express = require("express"); +const Log = require("logger"); +const Class = require("./class"); const NodeHelper = Class.extend({ - init() { + init () { Log.log("Initializing new module helper ..."); }, - loaded(callback) { + loaded () { Log.log(`Module helper loaded: ${this.name}`); - callback(); }, - start() { + start () { Log.log(`Starting module helper: ${this.name}`); }, @@ -27,35 +20,32 @@ const NodeHelper = Class.extend({ * Close any open connections, stop any sub-processes and * gracefully exit the module. */ - stop() { + stop () { Log.log(`Stopping module helper: ${this.name}`); }, /** * This method is called when a socket notification arrives. - * * @param {string} notification The identifier of the notification. * @param {*} payload The payload of the notification. */ - socketNotificationReceived(notification, payload) { + socketNotificationReceived (notification, payload) { Log.log(`${this.name} received a socket notification: ${notification} - Payload: ${payload}`); }, /** * Set the module name. - * * @param {string} name Module name. */ - setName(name) { + setName (name) { this.name = name; }, /** * Set the module path. - * * @param {string} path Module path. */ - setPath(path) { + setPath (path) { this.path = path; }, @@ -65,7 +55,7 @@ const NodeHelper = Class.extend({ * argument notification string - The identifier of the notification. * argument payload mixed - The payload of the notification. */ - sendSocketNotification(notification, payload) { + sendSocketNotification (notification, payload) { this.io.of(this.name).emit(notification, payload); }, @@ -75,7 +65,7 @@ const NodeHelper = Class.extend({ * * argument app Express app - The Express app object. */ - setExpressApp(app) { + setExpressApp (app) { this.expressApp = app; app.use(`/${this.name}`, express.static(`${this.path}/public`)); @@ -87,7 +77,7 @@ const NodeHelper = Class.extend({ * * argument io Socket.io - The Socket io object. */ - setSocketIO(io) { + setSocketIO (io) { this.io = io; Log.log(`Connecting socket for: ${this.name}`); @@ -124,7 +114,6 @@ NodeHelper.checkFetchStatus = function (response) { /** * Look at the specified error and return an appropriate error type, that * can be translated to a detailed error message - * * @param {Error} error the error from fetching something * @returns {string} the string of the detailed error message in the translations */ diff --git a/js/server.js b/js/server.js index 3aa246b5c1..bfa0f911d7 100644 --- a/js/server.js +++ b/js/server.js @@ -1,26 +1,22 @@ -/* MagicMirror² - * Server - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. - */ +const fs = require("node:fs"); +const http = require("node:http"); +const https = require("node:https"); +const path = require("node:path"); const express = require("express"); -const path = require("path"); const ipfilter = require("express-ipfilter").IpFilter; -const fs = require("fs"); const helmet = require("helmet"); +const socketio = require("socket.io"); const Log = require("logger"); -const Utils = require("./utils.js"); -const { cors, getConfig, getHtml, getVersion } = require("./server_functions.js"); +const Utils = require("./utils"); +const { cors, getConfig, getHtml, getVersion, getStartup } = require("./server_functions"); /** * Server - * * @param {object} config The MM config * @class */ -function Server(config) { +function Server (config) { const app = express(); const port = process.env.MM_PORT || config.port; const serverSockets = new Set(); @@ -28,7 +24,6 @@ function Server(config) { /** * Opens the server for incoming connections - * * @returns {Promise} A promise that is resolved when the server listens to connections */ this.open = function () { @@ -38,11 +33,11 @@ function Server(config) { key: fs.readFileSync(config.httpsPrivateKey), cert: fs.readFileSync(config.httpsCertificate) }; - server = require("https").Server(options, app); + server = https.Server(options, app); } else { - server = require("http").Server(app); + server = http.Server(app); } - const io = require("socket.io")(server, { + const io = socketio(server, { cors: { origin: /.*$/, credentials: true @@ -61,7 +56,7 @@ function Server(config) { 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")); + Log.warn("You're using a full whitelist configuration to allow for all IPs"); } app.use(function (req, res, next) { @@ -90,6 +85,8 @@ function Server(config) { app.get("/config", (req, res) => getConfig(req, res)); + app.get("/startup", (req, res) => getStartup(req, res)); + app.get("/", (req, res) => getHtml(req, res)); server.on("listening", () => { @@ -103,7 +100,6 @@ function Server(config) { /** * 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 () { diff --git a/js/server_functions.js b/js/server_functions.js index f210a8b848..7d4358b2e5 100644 --- a/js/server_functions.js +++ b/js/server_functions.js @@ -1,36 +1,44 @@ -const fetch = require("./fetch"); -const fs = require("fs"); -const path = require("path"); +const fs = require("node:fs"); +const path = require("node:path"); const Log = require("logger"); +const startUp = new Date(); + /** * Gets the config. - * * @param {Request} req - the request * @param {Response} res - the result */ -function getConfig(req, res) { +function getConfig (req, res) { res.send(config); } /** - * A method that forewards HTTP Get-methods to the internet to avoid CORS-errors. + * Gets the startup time. + * @param {Request} req - the request + * @param {Response} res - the result + */ +function getStartup (req, res) { + res.send(startUp); +} + +/** + * A method that forwards HTTP Get-methods to the internet to avoid CORS-errors. * * Example input request url: /cors?sendheaders=header1:value1,header2:value2&expectedheaders=header1,header2&url=http://www.test.com/path?param1=value1 * * 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) { +async function cors (req, res) { try { const urlRegEx = "url=(.+?)$"; - let url = ""; + let url; const match = new RegExp(urlRegEx, "g").exec(req.url); if (!match) { - url = "invalid url: " + req.url; + url = `invalid url: ${req.url}`; Log.error(url); res.send(url); } else { @@ -39,7 +47,7 @@ async function cors(req, res) { const headersToSend = getHeadersToSend(req.url); const expectedRecievedHeaders = geExpectedRecievedHeaders(req.url); - Log.log("cors url: " + url); + Log.log(`cors url: ${url}`); const response = await fetch(url, { headers: headersToSend }); for (const header of expectedRecievedHeaders) { @@ -56,13 +64,12 @@ async function cors(req, res) { } /** - * Gets headers and values to attatch to the web request. - * + * Gets headers and values to attach to the web request. * @param {string} url - The url containing the headers and values to send. * @returns {object} An object specifying name and value of the headers. */ -function getHeadersToSend(url) { - const headersToSend = { "User-Agent": "Mozilla/5.0 MagicMirror/" + global.version }; +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(","); @@ -79,11 +86,10 @@ function getHeadersToSend(url) { /** * 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) { +function geExpectedRecievedHeaders (url) { const expectedRecievedHeaders = ["Content-Type"]; const expectedRecievedHeadersMatch = new RegExp("expectedheaders=(.+?)(&|$)", "g").exec(url); if (expectedRecievedHeadersMatch) { @@ -97,11 +103,10 @@ function geExpectedRecievedHeaders(url) { /** * Gets the HTML to display the magic mirror. - * * @param {Request} req - the request * @param {Response} res - the result */ -function getHtml(req, res) { +function getHtml (req, res) { let html = fs.readFileSync(path.resolve(`${global.root_path}/index.html`), { encoding: "utf8" }); html = html.replace("#VERSION#", global.version); @@ -116,12 +121,11 @@ function getHtml(req, res) { /** * Gets the MagicMirror version. - * * @param {Request} req - the request * @param {Response} res - the result */ -function getVersion(req, res) { +function getVersion (req, res) { res.send(global.version); } -module.exports = { cors, getConfig, getHtml, getVersion }; +module.exports = { cors, getConfig, getHtml, getVersion, getStartup }; diff --git a/js/socketclient.js b/js/socketclient.js index 8b3aec827a..d8408e9e93 100644 --- a/js/socketclient.js +++ b/js/socketclient.js @@ -1,11 +1,5 @@ /* global io */ -/* MagicMirror² - * TODO add description - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. - */ const MMSocket = function (moduleName) { if (typeof moduleName !== "string") { throw new Error("Please set the module name for the MMSocket."); @@ -18,8 +12,8 @@ const MMSocket = function (moduleName) { if (typeof config !== "undefined" && typeof config.basePath !== "undefined") { base = config.basePath; } - this.socket = io("/" + this.moduleName, { - path: base + "socket.io" + this.socket = io(`/${this.moduleName}`, { + path: `${base}socket.io` }); let notificationCallback = function () {}; @@ -44,10 +38,7 @@ const MMSocket = function (moduleName) { notificationCallback = callback; }; - this.sendNotification = (notification, payload) => { - if (typeof payload === "undefined") { - payload = {}; - } + this.sendNotification = (notification, payload = {}) => { this.socket.emit(notification, payload); }; }; diff --git a/js/translator.js b/js/translator.js index 77d4b8f0da..e742eb9c3b 100644 --- a/js/translator.js +++ b/js/translator.js @@ -1,36 +1,32 @@ /* global translations */ -/* MagicMirror² - * Translator (l10n) - * - * By Christopher Fenner https://github.com/CFenner - * MIT Licensed. - */ const Translator = (function () { + /** * Load a JSON file via XHR. - * * @param {string} file Path of the file we want to load. - * @param {Function} callback Function called when done. + * @returns {Promise} the translations in the specified file */ - function loadJSON(file, callback) { + async function loadJSON (file) { const xhr = new XMLHttpRequest(); - xhr.overrideMimeType("application/json"); - xhr.open("GET", file, true); - xhr.onreadystatechange = function () { - if (xhr.readyState === 4 && xhr.status === 200) { - // needs error handler try/catch at least - let fileinfo = null; - try { - fileinfo = JSON.parse(xhr.responseText); - } catch (exception) { - // nothing here, but don't die - Log.error(" loading json file =" + file + " failed"); + return new Promise(function (resolve) { + xhr.overrideMimeType("application/json"); + xhr.open("GET", file, true); + xhr.onreadystatechange = function () { + if (xhr.readyState === 4 && xhr.status === 200) { + // needs error handler try/catch at least + let fileinfo = null; + try { + fileinfo = JSON.parse(xhr.responseText); + } catch (exception) { + // nothing here, but don't die + Log.error(` loading json file =${file} failed`); + } + resolve(fileinfo); } - callback(fileinfo); - } - }; - xhr.send(null); + }; + xhr.send(null); + }); } return { @@ -41,34 +37,32 @@ const Translator = (function () { /** * Load a translation for a given key for a given module. - * * @param {Module} module The module to load the translation for. * @param {string} key The key of the text to translate. * @param {object} variables The variables to use within the translation template (optional) * @returns {string} the translated key */ - translate: function (module, key, variables) { - variables = variables || {}; //Empty object by default + translate (module, key, variables = {}) { /** * Combines template and variables like: * template: "Please wait for {timeToWait} before continuing with {work}." * variables: {timeToWait: "2 hours", work: "painting"} * to: "Please wait for 2 hours before continuing with painting." - * * @param {string} template Text with placeholder * @param {object} variables Variables for the placeholder * @returns {string} the template filled with the variables */ - function createStringFromTemplate(template, variables) { + function createStringFromTemplate (template, variables) { if (Object.prototype.toString.call(template) !== "[object String]") { return template; } + let templateToUse = template; if (variables.fallback && !template.match(new RegExp("{.+}"))) { - template = variables.fallback; + templateToUse = variables.fallback; } - return template.replace(new RegExp("{([^}]+)}", "g"), function (_unused, varName) { - return varName in variables ? variables[varName] : "{" + varName + "}"; + return templateToUse.replace(new RegExp("{([^}]+)}", "g"), function (_unused, varName) { + return varName in variables ? variables[varName] : `{${varName}}`; }); } @@ -97,59 +91,49 @@ const Translator = (function () { /** * Load a translation file (json) and remember the data. - * * @param {Module} module The module to load the translation file for. * @param {string} file Path of the file we want to load. * @param {boolean} isFallback Flag to indicate fallback translations. - * @param {Function} callback Function called when done. */ - load(module, file, isFallback, callback) { + async load (module, file, isFallback) { Log.log(`${module.name} - Load translation${isFallback ? " fallback" : ""}: ${file}`); if (this.translationsFallback[module.name]) { - callback(); return; } - loadJSON(module.file(file), (json) => { - const property = isFallback ? "translationsFallback" : "translations"; - this[property][module.name] = json; - callback(); - }); + const json = await loadJSON(module.file(file)); + const property = isFallback ? "translationsFallback" : "translations"; + this[property][module.name] = json; }, /** * Load the core translations. - * * @param {string} lang The language identifier of the core language. */ - loadCoreTranslations: function (lang) { + async loadCoreTranslations (lang) { if (lang in translations) { - Log.log("Loading core translation file: " + translations[lang]); - loadJSON(translations[lang], (translations) => { - this.coreTranslations = translations; - }); + Log.log(`Loading core translation file: ${translations[lang]}`); + this.coreTranslations = await loadJSON(translations[lang]); } else { Log.log("Configured language not found in core translations."); } - this.loadCoreTranslationsFallback(); + await this.loadCoreTranslationsFallback(); }, /** - * Load the core translations fallback. + * Load the core translations' fallback. * The first language defined in translations.js will be used. */ - loadCoreTranslationsFallback: function () { + async loadCoreTranslationsFallback () { let first = Object.keys(translations)[0]; if (first) { - Log.log("Loading core translation fallback file: " + translations[first]); - loadJSON(translations[first], (translations) => { - this.coreTranslationsFallback = translations; - }); + Log.log(`Loading core translation fallback file: ${translations[first]}`); + this.coreTranslationsFallback = await loadJSON(translations[first]); } } }; -})(); +}()); window.Translator = Translator; diff --git a/js/utils.js b/js/utils.js index d111afca23..ba80004bb3 100644 --- a/js/utils.js +++ b/js/utils.js @@ -1,16 +1,29 @@ -/* MagicMirror² - * Utils - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ -const colors = require("colors/safe"); +const execSync = require("node:child_process").execSync; +const Log = require("logger"); +const si = require("systeminformation"); module.exports = { - colors: { - warn: colors.yellow, - error: colors.red, - info: colors.blue, - pass: colors.green + + async logSystemInformation () { + try { + let installedNodeVersion = execSync("node -v", { encoding: "utf-8" }).replace("v", "").replace(/(?:\r\n|\r|\n)/g, ""); + + const staticData = await si.get({ + system: "manufacturer, model, raspberry, virtual", + osInfo: "platform, distro, release, arch", + versions: "kernel, node, npm, pm2" + }); + let systemDataString = "System information:"; + systemDataString += `\n### SYSTEM: manufacturer: ${staticData["system"]["manufacturer"]}; model: ${staticData["system"]["model"]}; raspberry: ${staticData["system"]["raspberry"]}; virtual: ${staticData["system"]["virtual"]}`; + systemDataString += `\n### OS: platform: ${staticData["osInfo"]["platform"]}; distro: ${staticData["osInfo"]["distro"]}; release: ${staticData["osInfo"]["release"]}; arch: ${staticData["osInfo"]["arch"]}; kernel: ${staticData["versions"]["kernel"]}`; + systemDataString += `\n### VERSIONS: electron: ${process.versions.electron}; used node: ${staticData["versions"]["node"]}; installed node: ${installedNodeVersion}; npm: ${staticData["versions"]["npm"]}; pm2: ${staticData["versions"]["pm2"]}`; + systemDataString += `\n### OTHER: timeZone: ${Intl.DateTimeFormat().resolvedOptions().timeZone}; ELECTRON_ENABLE_GPU: ${process.env.ELECTRON_ENABLE_GPU}`; + Log.info(systemDataString); + + // Return is currently only for jest + return systemDataString; + } catch (e) { + Log.error(e); + } } }; diff --git a/mm2.png b/mm2.png new file mode 100644 index 0000000000..5be0b24be2 Binary files /dev/null and b/mm2.png differ diff --git a/module-types.ts b/module-types.ts index be1a2061dd..440b2c4959 100644 --- a/module-types.ts +++ b/module-types.ts @@ -1,16 +1,19 @@ type ModuleProperties = { defaults?: object; + [key: string]: any; start?(): void; + getScripts?(): string[]; + getStyles?(): string[]; + getTranslations?(): object; + getDom?(): HTMLElement; getHeader?(): string; getTemplate?(): string; getTemplateData?(): object; notificationReceived?(notification: string, payload: any, sender: object): void; + nunjucksEnvironment?(): void; socketNotificationReceived?(notification: string, payload: any): void; suspend?(): void; resume?(): void; - getDom?(): HTMLElement; - getStyles?(): string[]; - [key: string]: any; }; export declare const Module: { diff --git a/modules/default/alert/alert.js b/modules/default/alert/alert.js index 76bacc0248..a436a74c7b 100644 --- a/modules/default/alert/alert.js +++ b/modules/default/alert/alert.js @@ -1,11 +1,5 @@ /* global NotificationFx */ -/* MagicMirror² - * Module: alert - * - * By Paul-Vincent Roll https://paulvincentroll.com/ - * MIT Licensed. - */ Module.register("alert", { alerts: {}, @@ -17,15 +11,15 @@ Module.register("alert", { welcome_message: false // shown at startup }, - getScripts() { + getScripts () { return ["notificationFx.js"]; }, - getStyles() { - return ["font-awesome.css", this.file(`./styles/notificationFx.css`), this.file(`./styles/${this.config.position}.css`)]; + getStyles () { + return ["font-awesome.css", this.file("./styles/notificationFx.css"), this.file(`./styles/${this.config.position}.css`)]; }, - getTranslations() { + getTranslations () { return { bg: "translations/bg.json", da: "translations/da.json", @@ -35,15 +29,16 @@ Module.register("alert", { fr: "translations/fr.json", hu: "translations/hu.json", nl: "translations/nl.json", - ru: "translations/ru.json" + ru: "translations/ru.json", + th: "translations/th.json" }; }, - getTemplate(type) { + getTemplate (type) { return `templates/${type}.njk`; }, - start() { + async start () { Log.info(`Starting module: ${this.name}`); if (this.config.effect === "slide") { @@ -52,11 +47,11 @@ Module.register("alert", { if (this.config.welcome_message) { const message = this.config.welcome_message === true ? this.translate("welcome") : this.config.welcome_message; - this.showNotification({ title: this.translate("sysTitle"), message }); + await this.showNotification({ title: this.translate("sysTitle"), message }); } }, - notificationReceived(notification, payload, sender) { + notificationReceived (notification, payload, sender) { if (notification === "SHOW_ALERT") { if (payload.type === "notification") { this.showNotification(payload); @@ -68,8 +63,8 @@ Module.register("alert", { } }, - async showNotification(notification) { - const message = await this.renderMessage("notification", notification); + async showNotification (notification) { + const message = await this.renderMessage(notification.templateName || "notification", notification); new NotificationFx({ message, @@ -79,7 +74,7 @@ Module.register("alert", { }).show(); }, - async showAlert(alert, sender) { + async showAlert (alert, sender) { // If module already has an open alert close it if (this.alerts[sender.name]) { this.hideAlert(sender, false); @@ -90,7 +85,7 @@ Module.register("alert", { this.toggleBlur(true); } - const message = await this.renderMessage("alert", alert); + const message = await this.renderMessage(alert.templateName || "alert", alert); // Store alert in this.alerts this.alerts[sender.name] = new NotificationFx({ @@ -112,7 +107,7 @@ Module.register("alert", { } }, - hideAlert(sender, close = true) { + hideAlert (sender, close = true) { // Dismiss alert and remove from this.alerts if (this.alerts[sender.name]) { this.alerts[sender.name].dismiss(close); @@ -124,7 +119,7 @@ Module.register("alert", { } }, - renderMessage(type, data) { + renderMessage (type, data) { return new Promise((resolve) => { this.nunjucksEnvironment().render(this.getTemplate(type), data, function (err, res) { if (err) { @@ -136,7 +131,7 @@ Module.register("alert", { }); }, - toggleBlur(add = false) { + toggleBlur (add = false) { const method = add ? "add" : "remove"; const modules = document.querySelectorAll(".module"); for (const module of modules) { diff --git a/modules/default/alert/notificationFx.js b/modules/default/alert/notificationFx.js index 3957abe814..fcf7f3456b 100644 --- a/modules/default/alert/notificationFx.js +++ b/modules/default/alert/notificationFx.js @@ -9,18 +9,17 @@ * * Copyright 2014, Codrops * https://tympanus.net/codrops/ - * * @param {object} window The window object */ (function (window) { + /** * Extend one object with another one - * * @param {object} a The object to extend * @param {object} b The object which extends the other, overwrites existing keys * @returns {object} The merged object */ - function extend(a, b) { + function extend (a, b) { for (let key in b) { if (b.hasOwnProperty(key)) { a[key] = b[key]; @@ -31,11 +30,10 @@ /** * NotificationFx constructor - * * @param {object} options The configuration options * @class */ - function NotificationFx(options) { + function NotificationFx (options) { this.options = extend({}, this.options); extend(this.options, options); this._init(); @@ -66,10 +64,10 @@ ttl: 6000, al_no: "ns-box", // callbacks - onClose: function () { + onClose () { return false; }, - onOpen: function () { + onOpen () { return false; } }; @@ -80,8 +78,8 @@ NotificationFx.prototype._init = function () { // create HTML structure this.ntf = document.createElement("div"); - this.ntf.className = this.options.al_no + " ns-" + this.options.layout + " ns-effect-" + this.options.effect + " ns-type-" + this.options.type; - let strinner = '
'; + this.ntf.className = `${this.options.al_no} ns-${this.options.layout} ns-effect-${this.options.effect} ns-type-${this.options.type}`; + let strinner = "
"; strinner += this.options.message; strinner += "
"; this.ntf.innerHTML = strinner; @@ -124,7 +122,6 @@ /** * Dismiss the notification - * * @param {boolean} [close] call the onClose callback at the end */ NotificationFx.prototype.dismiss = function (close = true) { @@ -157,4 +154,4 @@ * Add to global namespace */ window.NotificationFx = NotificationFx; -})(window); +}(window)); diff --git a/modules/default/alert/styles/notificationFx.css b/modules/default/alert/styles/notificationFx.css index 8e033e0d61..df3407514c 100644 --- a/modules/default/alert/styles/notificationFx.css +++ b/modules/default/alert/styles/notificationFx.css @@ -1,7 +1,7 @@ /* Based on work by https://tympanus.net/codrops/licensing/ */ .ns-box { - background-color: rgba(0, 0, 0, 0.93); + background-color: rgb(0 0 0 / 93%); padding: 17px; line-height: 1.4; margin-bottom: 10px; @@ -55,15 +55,15 @@ .ns-effect-flip.ns-show, .ns-effect-flip.ns-hide { - animation-name: animFlipFront; + animation-name: anim-flip-front; animation-duration: 0.3s; } .ns-effect-flip.ns-hide { - animation-name: animFlipBack; + animation-name: anim-flip-back; } -@keyframes animFlipFront { +@keyframes anim-flip-front { 0% { transform: perspective(1000px) rotate3d(1, 0, 0, -90deg); } @@ -73,7 +73,7 @@ } } -@keyframes animFlipBack { +@keyframes anim-flip-back { 0% { transform: perspective(1000px) rotate3d(1, 0, 0, 90deg); } @@ -85,11 +85,11 @@ .ns-effect-bouncyflip.ns-show, .ns-effect-bouncyflip.ns-hide { - animation-name: flipInX; + animation-name: flip-in-x; animation-duration: 0.8s; } -@keyframes flipInX { +@keyframes flip-in-x { 0% { transform: perspective(400px) rotate3d(1, 0, 0, -90deg); transition-timing-function: ease-in; @@ -117,11 +117,11 @@ } .ns-effect-bouncyflip.ns-hide { - animation-name: flipInXSimple; + animation-name: flip-in-x-simple; animation-duration: 0.3s; } -@keyframes flipInXSimple { +@keyframes flip-in-x-simple { 0% { transform: perspective(400px) rotate3d(1, 0, 0, -90deg); transition-timing-function: ease-in; @@ -141,11 +141,11 @@ } .ns-effect-exploader.ns-show { - animation-name: animLoad; + animation-name: anim-load; animation-duration: 1s; } -@keyframes animLoad { +@keyframes anim-load { 0% { opacity: 1; transform: scale3d(0, 0.3, 1); @@ -158,7 +158,7 @@ } .ns-effect-exploader.ns-hide { - animation-name: animFade; + animation-name: anim-fade; animation-duration: 0.3s; } @@ -170,15 +170,15 @@ } .ns-effect-exploader.ns-show .ns-close { - animation-name: animFade; + animation-name: anim-fade; } .ns-effect-exploader.ns-show .ns-box-inner { - animation-name: animFadeMove; + animation-name: anim-fade-move; animation-timing-function: ease-out; } -@keyframes animFadeMove { +@keyframes anim-fade-move { 0% { opacity: 0; transform: translate3d(0, 10px, 0); @@ -190,7 +190,7 @@ } } -@keyframes animFade { +@keyframes anim-fade { 0% { opacity: 0; } @@ -202,11 +202,11 @@ .ns-effect-scale.ns-show, .ns-effect-scale.ns-hide { - animation-name: animScale; + animation-name: anim-scale; animation-duration: 0.25s; } -@keyframes animScale { +@keyframes anim-scale { 0% { opacity: 0; transform: translate3d(0, 40px, 0) scale3d(0.1, 0.6, 1); @@ -219,168 +219,169 @@ } .ns-effect-jelly.ns-show { - animation-name: animJelly; + animation-name: anim-jelly; animation-duration: 1s; animation-timing-function: linear; } .ns-effect-jelly.ns-hide { - animation-name: animFade; + animation-name: anim-fade; animation-duration: 0.3s; } -@keyframes animFade { +@keyframes anim-fade { 0% { opacity: 0; } + 100% { opacity: 1; } } -@keyframes animJelly { +@keyframes anim-jelly { 0% { transform: matrix3d(0.7, 0, 0, 0, 0, 0.7, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 2.083333% { - transform: matrix3d(0.75266, 0, 0, 0, 0, 0.76342, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.7527, 0, 0, 0, 0, 0.7634, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 4.166667% { - transform: matrix3d(0.81071, 0, 0, 0, 0, 0.84545, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.8107, 0, 0, 0, 0, 0.8454, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 6.25% { - transform: matrix3d(0.86808, 0, 0, 0, 0, 0.9286, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.8681, 0, 0, 0, 0, 0.929, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 8.333333% { - transform: matrix3d(0.92038, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9204, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 10.416667% { - transform: matrix3d(0.96482, 0, 0, 0, 0, 1.05202, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9648, 0, 0, 0, 0, 1.052, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 12.5% { - transform: matrix3d(1, 0, 0, 0, 0, 1.08204, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1.082, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 14.583333% { - transform: matrix3d(1.02563, 0, 0, 0, 0, 1.09149, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0256, 0, 0, 0, 0, 1.0915, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 16.666667% { - transform: matrix3d(1.04227, 0, 0, 0, 0, 1.08453, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0423, 0, 0, 0, 0, 1.0845, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 18.75% { - transform: matrix3d(1.05102, 0, 0, 0, 0, 1.06666, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.051, 0, 0, 0, 0, 1.0667, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 20.833333% { - transform: matrix3d(1.05334, 0, 0, 0, 0, 1.04355, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0533, 0, 0, 0, 0, 1.0436, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 22.916667% { - transform: matrix3d(1.05078, 0, 0, 0, 0, 1.02012, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0508, 0, 0, 0, 0, 1.0201, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 25% { - transform: matrix3d(1.04487, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0449, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 27.083333% { - transform: matrix3d(1.03699, 0, 0, 0, 0, 0.98534, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.037, 0, 0, 0, 0, 0.9853, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 29.166667% { - transform: matrix3d(1.02831, 0, 0, 0, 0, 0.97688, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0283, 0, 0, 0, 0, 0.9769, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 31.25% { - transform: matrix3d(1.01973, 0, 0, 0, 0, 0.97422, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0197, 0, 0, 0, 0, 0.9742, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 33.333333% { - transform: matrix3d(1.01191, 0, 0, 0, 0, 0.97618, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0119, 0, 0, 0, 0, 0.9762, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 35.416667% { - transform: matrix3d(1.00526, 0, 0, 0, 0, 0.98122, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0053, 0, 0, 0, 0, 0.9812, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 37.5% { - transform: matrix3d(1, 0, 0, 0, 0, 0.98773, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 0.9877, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 39.583333% { - transform: matrix3d(0.99617, 0, 0, 0, 0, 0.99433, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9962, 0, 0, 0, 0, 0.9943, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 41.666667% { - transform: matrix3d(0.99368, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9937, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 43.75% { - transform: matrix3d(0.99237, 0, 0, 0, 0, 1.00413, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9924, 0, 0, 0, 0, 1.0041, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 45.833333% { - transform: matrix3d(0.99202, 0, 0, 0, 0, 1.00651, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.992, 0, 0, 0, 0, 1.0065, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 47.916667% { - transform: matrix3d(0.99241, 0, 0, 0, 0, 1.00726, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9924, 0, 0, 0, 0, 1.0073, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 50% { - transform: matrix3d(0.99329, 0, 0, 0, 0, 1.00671, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9933, 0, 0, 0, 0, 1.0067, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 52.083333% { - transform: matrix3d(0.99447, 0, 0, 0, 0, 1.00529, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9945, 0, 0, 0, 0, 1.0053, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 54.166667% { - transform: matrix3d(0.99577, 0, 0, 0, 0, 1.00346, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9958, 0, 0, 0, 0, 1.0035, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 56.25% { - transform: matrix3d(0.99705, 0, 0, 0, 0, 1.0016, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.997, 0, 0, 0, 0, 1.002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 58.333333% { - transform: matrix3d(0.99822, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9982, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 60.416667% { - transform: matrix3d(0.99921, 0, 0, 0, 0, 0.99884, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9992, 0, 0, 0, 0, 0.9989, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 62.5% { - transform: matrix3d(1, 0, 0, 0, 0, 0.99816, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 0.9982, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 64.583333% { - transform: matrix3d(1.00057, 0, 0, 0, 0, 0.99795, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0006, 0, 0, 0, 0, 0.998, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 66.666667% { - transform: matrix3d(1.00095, 0, 0, 0, 0, 0.99811, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.001, 0, 0, 0, 0, 0.9981, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 68.75% { - transform: matrix3d(1.00114, 0, 0, 0, 0, 0.99851, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0011, 0, 0, 0, 0, 0.9985, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 70.833333% { - transform: matrix3d(1.00119, 0, 0, 0, 0, 0.99903, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0012, 0, 0, 0, 0, 0.999, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 72.916667% { - transform: matrix3d(1.00114, 0, 0, 0, 0, 0.99955, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0011, 0, 0, 0, 0, 0.9996, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 75% { @@ -388,47 +389,47 @@ } 77.083333% { - transform: matrix3d(1.00083, 0, 0, 0, 0, 1.00033, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0008, 0, 0, 0, 0, 1.0003, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 79.166667% { - transform: matrix3d(1.00063, 0, 0, 0, 0, 1.00052, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0006, 0, 0, 0, 0, 1.0005, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 81.25% { - transform: matrix3d(1.00044, 0, 0, 0, 0, 1.00058, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0004, 0, 0, 0, 0, 1.0006, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 83.333333% { - transform: matrix3d(1.00027, 0, 0, 0, 0, 1.00053, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0003, 0, 0, 0, 0, 1.0005, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 85.416667% { - transform: matrix3d(1.00012, 0, 0, 0, 0, 1.00042, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1.0001, 0, 0, 0, 0, 1.0004, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 87.5% { - transform: matrix3d(1, 0, 0, 0, 0, 1.00027, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1.0003, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 89.583333% { - transform: matrix3d(0.99991, 0, 0, 0, 0, 1.00013, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9999, 0, 0, 0, 0, 1.0001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 91.666667% { - transform: matrix3d(0.99986, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9999, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 93.75% { - transform: matrix3d(0.99983, 0, 0, 0, 0, 0.99991, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9998, 0, 0, 0, 0, 0.9999, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 95.833333% { - transform: matrix3d(0.99982, 0, 0, 0, 0, 0.99985, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9998, 0, 0, 0, 0, 0.9999, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 97.916667% { - transform: matrix3d(0.99983, 0, 0, 0, 0, 0.99984, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); + transform: matrix3d(0.9998, 0, 0, 0, 0, 0.9998, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1); } 100% { @@ -437,162 +438,162 @@ } .ns-effect-slide-left.ns-show { - animation-name: animSlideElasticLeft; + animation-name: anim-slide-elastic-left; animation-duration: 1s; animation-timing-function: linear; } -@keyframes animSlideElasticLeft { +@keyframes anim-slide-elastic-left { 0% { transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1000, 0, 0, 1); } 1.666667% { - transform: matrix3d(1.92933, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -739.26805, 0, 0, 1); + transform: matrix3d(1.9293, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -739.2681, 0, 0, 1); } 3.333333% { - transform: matrix3d(1.96989, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -521.82545, 0, 0, 1); + transform: matrix3d(1.9699, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -521.8255, 0, 0, 1); } 5% { - transform: matrix3d(1.70901, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -349.26115, 0, 0, 1); + transform: matrix3d(1.709, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -349.2612, 0, 0, 1); } 6.666667% { - transform: matrix3d(1.4235, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -218.3238, 0, 0, 1); + transform: matrix3d(1.424, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -218.324, 0, 0, 1); } 8.333333% { - transform: matrix3d(1.21065, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -123.29848, 0, 0, 1); + transform: matrix3d(1.2107, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -123.2985, 0, 0, 1); } 10% { - transform: matrix3d(1.08167, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -57.59273, 0, 0, 1); + transform: matrix3d(1.0817, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -57.5927, 0, 0, 1); } 11.666667% { - transform: matrix3d(1.0165, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -14.72371, 0, 0, 1); + transform: matrix3d(1.017, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -14.7237, 0, 0, 1); } 13.333333% { - transform: matrix3d(0.99057, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.12794, 0, 0, 1); + transform: matrix3d(0.9906, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.1279, 0, 0, 1); } 15% { - transform: matrix3d(0.98478, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 24.86339, 0, 0, 1); + transform: matrix3d(0.9848, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 24.8634, 0, 0, 1); } 16.666667% { - transform: matrix3d(0.98719, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.40503, 0, 0, 1); + transform: matrix3d(0.9872, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.405, 0, 0, 1); } 18.333333% { - transform: matrix3d(0.9916, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.75275, 0, 0, 1); + transform: matrix3d(0.992, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 30.7528, 0, 0, 1); } 20% { - transform: matrix3d(0.99541, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 28.10141, 0, 0, 1); + transform: matrix3d(0.9954, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 28.1014, 0, 0, 1); } 21.666667% { - transform: matrix3d(0.99795, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 23.98271, 0, 0, 1); + transform: matrix3d(0.998, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 23.9827, 0, 0, 1); } 23.333333% { - transform: matrix3d(0.99936, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 19.40752, 0, 0, 1); + transform: matrix3d(0.9994, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 19.4075, 0, 0, 1); } 25% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 14.99558, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 14.9956, 0, 0, 1); } 26.666667% { - transform: matrix3d(1.00021, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.08575, 0, 0, 1); + transform: matrix3d(1.0002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 11.0858, 0, 0, 1); } 28.333333% { - transform: matrix3d(1.00022, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7.82507, 0, 0, 1); + transform: matrix3d(1.0002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 7.8251, 0, 0, 1); } 30% { - transform: matrix3d(1.00016, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5.23737, 0, 0, 1); + transform: matrix3d(1.0002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 5.2374, 0, 0, 1); } 31.666667% { - transform: matrix3d(1.0001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3.27389, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 3.2739, 0, 0, 1); } 33.333333% { - transform: matrix3d(1.00005, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1.84893, 0, 0, 1); + transform: matrix3d(1.0001, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1.8489, 0, 0, 1); } 35% { - transform: matrix3d(1.00002, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.86364, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.8636, 0, 0, 1); } 36.666667% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.22079, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.2208, 0, 0, 1); } 38.333333% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16687, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.1669, 0, 0, 1); } 40% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.37284, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.3728, 0, 0, 1); } 41.666667% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.45594, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.4559, 0, 0, 1); } 43.333333% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.46116, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.4612, 0, 0, 1); } 45% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.4214, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.421, 0, 0, 1); } 46.666667% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.35963, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.3596, 0, 0, 1); } 48.333333% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.29103, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.291, 0, 0, 1); } 50% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.22487, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.2249, 0, 0, 1); } 51.666667% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.16624, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.1662, 0, 0, 1); } 53.333333% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.11734, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.1173, 0, 0, 1); } 55% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.07854, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0785, 0, 0, 1); } 56.666667% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.04909, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0491, 0, 0, 1); } 58.333333% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.02773, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0277, 0, 0, 1); } 60% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.01295, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.013, 0, 0, 1); } 61.666667% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00331, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0033, 0, 0, 1); } 63.333333% { @@ -600,67 +601,67 @@ } 65% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00559, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0056, 0, 0, 1); } 66.666667% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00684, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0068, 0, 0, 1); } 68.333333% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00692, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0069, 0, 0, 1); } 70% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00632, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0063, 0, 0, 1); } 71.666667% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00539, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0054, 0, 0, 1); } 73.333333% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00436, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0044, 0, 0, 1); } 75% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00337, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0034, 0, 0, 1); } 76.666667% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00249, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0025, 0, 0, 1); } 78.333333% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00176, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0018, 0, 0, 1); } 80% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00118, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0012, 0, 0, 1); } 81.666667% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00074, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0007, 0, 0, 1); } 83.333333% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00042, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0004, 0, 0, 1); } 85% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00019, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0002, 0, 0, 1); } 86.666667% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.00005, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0.0001, 0, 0, 1); } 88.333333% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00004, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); } 90% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); } 91.666667% { @@ -672,15 +673,15 @@ } 95% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00009, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); } 96.666667% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00008, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); } 98.333333% { - transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.00007, 0, 0, 1); + transform: matrix3d(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -0.0001, 0, 0, 1); } 100% { @@ -689,11 +690,11 @@ } .ns-effect-slide-left.ns-hide { - animation-name: animSlideLeft; + animation-name: anim-slide-left; animation-duration: 0.25s; } -@keyframes animSlideLeft { +@keyframes anim-slide-left { 0% { transform: translate3d(-30px, 0, 0) translate3d(-100%, 0, 0); } @@ -704,10 +705,10 @@ } .ns-effect-slide-right.ns-show { - animation: animSlideElasticRight 2000ms linear both; + animation: anim-slide-elastic-right 2000ms linear both; } -@keyframes animSlideElasticRight { +@keyframes anim-slide-elastic-right { 0% { transform: matrix3d(2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1000, 0, 0, 1); } @@ -786,11 +787,11 @@ } .ns-effect-slide-right.ns-hide { - animation-name: animSlideRight; + animation-name: anim-slide-right; animation-duration: 0.25s; } -@keyframes animSlideRight { +@keyframes anim-slide-right { 0% { transform: translate3d(30px, 0, 0) translate3d(100%, 0, 0); } @@ -801,10 +802,10 @@ } .ns-effect-slide-center.ns-show { - animation: animSlideElasticCenter 2000ms linear both; + animation: anim-slide-elastic-center 2000ms linear both; } -@keyframes animSlideElasticCenter { +@keyframes anim-slide-elastic-center { 0% { transform: matrix3d(1, 0, 0, 0, 0, 3, 0, 0, 0, 0, 1, 0, 0, -300, 0, 1); } @@ -883,11 +884,11 @@ } .ns-effect-slide-center.ns-hide { - animation-name: animSlideCenter; + animation-name: anim-slide-center; animation-duration: 0.25s; } -@keyframes animSlideCenter { +@keyframes anim-slide-center { 0% { transform: translate3d(0, -30px, 0) translate3d(0, -100%, 0); } @@ -899,11 +900,11 @@ .ns-effect-genie.ns-show, .ns-effect-genie.ns-hide { - animation-name: animGenie; + animation-name: anim-genie; animation-duration: 0.4s; } -@keyframes animGenie { +@keyframes anim-genie { 0% { opacity: 0; transform: translate3d(0, calc(200% + 30px), 0) scale3d(0, 1, 1); diff --git a/modules/default/alert/templates/alert.njk b/modules/default/alert/templates/alert.njk index a748d2684e..b7db3a4de4 100644 --- a/modules/default/alert/templates/alert.njk +++ b/modules/default/alert/templates/alert.njk @@ -1,18 +1,20 @@ {% if imageUrl or imageFA %} - {% set imageHeight = imageHeight if imageHeight else "80px" %} - {% if imageUrl %} - - {% else %} - - {% endif %} -
+ {% set imageHeight = imageHeight if imageHeight else "80px" %} + {% if imageUrl %} + + {% else %} + + {% endif %} +
{% endif %} {% if title %} - {{ title }} + {{ title if titleType == 'text' else title | safe }} {% endif %} {% if message %} - {% if title %} -
- {% endif %} - {{ message }} + {% if title %}
{% endif %} + {{ message if messageType == 'text' else message | safe }} {% endif %} diff --git a/modules/default/alert/templates/notification.njk b/modules/default/alert/templates/notification.njk index 1d67bcda7d..0de6908b26 100644 --- a/modules/default/alert/templates/notification.njk +++ b/modules/default/alert/templates/notification.njk @@ -1,9 +1,7 @@ {% if title %} - {{ title }} + {{ title if titleType == 'text' else title | safe }} {% endif %} {% if message %} - {% if title %} -
- {% endif %} - {{ message }} + {% if title %}
{% endif %} + {{ message if messageType == 'text' else message | safe }} {% endif %} diff --git a/modules/default/alert/translations/th.json b/modules/default/alert/translations/th.json new file mode 100644 index 0000000000..a1894bf3f1 --- /dev/null +++ b/modules/default/alert/translations/th.json @@ -0,0 +1,4 @@ +{ + "sysTitle": "การแจ้งเตือน MagicMirror²", + "welcome": "ยินดีต้อนรับ การเริ่มต้นสำเร็จแล้ว!" +} diff --git a/modules/default/calendar/calendar.css b/modules/default/calendar/calendar.css index f04d683872..f8e3bd7929 100644 --- a/modules/default/calendar/calendar.css +++ b/modules/default/calendar/calendar.css @@ -14,6 +14,7 @@ .calendar .title { padding-left: 0; padding-right: 0; + vertical-align: top; } .calendar .time { diff --git a/modules/default/calendar/calendar.js b/modules/default/calendar/calendar.js index 3694a21603..4b0409c01c 100644 --- a/modules/default/calendar/calendar.js +++ b/modules/default/calendar/calendar.js @@ -1,17 +1,12 @@ -/* global cloneObject */ - -/* MagicMirror² - * Module: Calendar - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. - */ +/* global CalendarUtils */ + Module.register("calendar", { // Define module defaults defaults: { maximumEntries: 10, // Total Maximum Entries maximumNumberOfDays: 365, limitDays: 0, // Limit the number of days shown, 0 = no limit + pastDaysCount: 0, displaySymbol: true, defaultSymbol: "calendar-alt", // Fontawesome Symbol see https://fontawesome.com/cheatsheet?from=io defaultSymbolClassName: "fas fa-fw fa-", @@ -20,28 +15,29 @@ Module.register("calendar", { defaultRepeatingCountTitle: "", maxTitleLength: 25, maxLocationTitleLength: 25, - wrapEvents: false, // wrap events to multiple lines breaking at maxTitleLength + wrapEvents: false, // Wrap events to multiple lines breaking at maxTitleLength wrapLocationEvents: false, maxTitleLines: 3, maxEventTitleLines: 3, - fetchInterval: 5 * 60 * 1000, // Update every 5 minutes. + fetchInterval: 60 * 60 * 1000, // Update every hour animationSpeed: 2000, fade: true, + fadePoint: 0.25, // Start on 1/4th of the list. urgency: 7, timeFormat: "relative", dateFormat: "MMM Do", dateEndFormat: "LT", fullDayEventDateFormat: "MMM Do", showEnd: false, + showEndsOnlyWithDuration: false, getRelative: 6, - fadePoint: 0.25, // Start on 1/4th of the list. hidePrivate: false, hideOngoing: false, hideTime: false, + hideDuplicates: true, showTimeToday: false, colored: false, - coloredSymbolOnly: false, - customEvents: [], // Array of {keyword: "", symbol: "", color: ""} where Keyword is a regexp and symbol/color are to be applied for matched + forceUseCurrentTime: false, tableClass: "small", calendars: [ { @@ -49,10 +45,11 @@ Module.register("calendar", { url: "https://www.calendarlabs.com/templates/ical/US-Holidays.ics" } ], - titleReplace: { - "De verjaardag van ": "", - "'s birthday": "" - }, + customEvents: [ + // Array of {keyword: "", symbol: "", color: "", eventClass: ""} where Keyword is a regexp and symbol/color/eventClass are to be applied for matched + { keyword: ".*", transform: { search: "De verjaardag van ", replace: "" } }, + { keyword: ".*", transform: { search: "'s birthday", replace: "" } } + ], locationTitleReplace: { "street ": "" }, @@ -61,23 +58,30 @@ Module.register("calendar", { sliceMultiDayEvents: false, broadcastPastEvents: false, nextDaysRelative: false, - selfSignedCert: false + selfSignedCert: false, + coloredText: false, + coloredBorder: false, + coloredSymbol: false, + coloredBackground: false, + limitDaysNeverSkip: false, + flipDateHeaderTitle: false, + updateOnFetch: true }, requiresVersion: "2.1.0", // Define required scripts. - getStyles: function () { + getStyles () { return ["calendar.css", "font-awesome.css"]; }, // Define required scripts. - getScripts: function () { - return ["moment.js"]; + getScripts () { + return ["calendarutils.js", "moment.js"]; }, // Define required translations. - getTranslations: function () { + getTranslations () { // The translations for the default modules are defined in the core translation files. // Therefore we can just return false. Otherwise we should have returned a dictionary. // If you're trying to build your own module including translations, check out the documentation. @@ -85,11 +89,22 @@ Module.register("calendar", { }, // Override start method. - start: function () { - Log.info("Starting module: " + this.name); + start () { + Log.info(`Starting module: ${this.name}`); + + if (this.config.colored) { + Log.warn("Your are using the deprecated config values 'colored'. Please switch to 'coloredSymbol' & 'coloredText'!"); + this.config.coloredText = true; + this.config.coloredSymbol = true; + } + if (this.config.coloredSymbolOnly) { + Log.warn("Your are using the deprecated config values 'coloredSymbolOnly'. Please switch to 'coloredSymbol' & 'coloredText'!"); + this.config.coloredText = false; + this.config.coloredSymbol = true; + } // Set locale. - moment.updateLocale(config.language, this.getLocaleSpecification(config.timeFormat)); + moment.updateLocale(config.language, CalendarUtils.getLocaleSpecification(config.timeFormat)); // clear data holder before start this.calendarData = {}; @@ -97,30 +112,36 @@ Module.register("calendar", { // indicate no data available yet this.loaded = false; + // data holder of calendar url. Avoid fade out/in on updateDom (one for each calendar update) + this.calendarDisplayer = {}; + this.config.calendars.forEach((calendar) => { calendar.url = calendar.url.replace("webcal://", "http://"); const calendarConfig = { maximumEntries: calendar.maximumEntries, maximumNumberOfDays: calendar.maximumNumberOfDays, + pastDaysCount: calendar.pastDaysCount, broadcastPastEvents: calendar.broadcastPastEvents, - selfSignedCert: calendar.selfSignedCert + selfSignedCert: calendar.selfSignedCert, + excludedEvents: calendar.excludedEvents, + fetchInterval: calendar.fetchInterval }; - if (calendar.symbolClass === "undefined" || calendar.symbolClass === null) { + if (typeof calendar.symbolClass === "undefined" || calendar.symbolClass === null) { calendarConfig.symbolClass = ""; } - if (calendar.titleClass === "undefined" || calendar.titleClass === null) { + if (typeof calendar.titleClass === "undefined" || calendar.titleClass === null) { calendarConfig.titleClass = ""; } - if (calendar.timeClass === "undefined" || calendar.timeClass === null) { + if (typeof calendar.timeClass === "undefined" || calendar.timeClass === null) { calendarConfig.timeClass = ""; } // we check user and password here for backwards compatibility with old configs if (calendar.user && calendar.pass) { Log.warn("Deprecation warning: Please update your calendar authentication configuration."); - Log.warn("https://github.com/MichMich/MagicMirror/tree/v2.1.2/modules/default/calendar#calendar-authentication-options"); + Log.warn("https://docs.magicmirror.builders/modules/calendar.html#configuration-options"); calendar.auth = { user: calendar.user, pass: calendar.pass @@ -131,10 +152,20 @@ Module.register("calendar", { // fetcher till cycle this.addCalendar(calendar.url, calendar.auth, calendarConfig); }); + + // for backward compatibility titleReplace + if (typeof this.config.titleReplace !== "undefined") { + Log.warn("Deprecation warning: Please consider upgrading your calendar titleReplace configuration to customEvents."); + for (const [titlesearchstr, titlereplacestr] of Object.entries(this.config.titleReplace)) { + this.config.customEvents.push({ keyword: ".*", transform: { search: titlesearchstr, replace: titlereplacestr } }); + } + } + + this.selfUpdate(); }, // Override socket notification handler. - socketNotificationReceived: function (notification, payload) { + socketNotificationReceived (notification, payload) { if (notification === "FETCH_CALENDAR") { this.sendSocketNotification(notification, { url: payload.url, id: this.identifier }); } @@ -152,6 +183,18 @@ Module.register("calendar", { if (this.config.broadcastEvents) { this.broadcastEvents(); } + + if (!this.config.updateOnFetch) { + if (this.calendarDisplayer[payload.url] === undefined) { + // calendar will never displayed, so display it + this.updateDom(this.config.animationSpeed); + // set this calendar as displayed + this.calendarDisplayer[payload.url] = true; + } else { + Log.debug("[Calendar] DOM not updated waiting self update()"); + } + return; + } } } else if (notification === "CALENDAR_ERROR") { let error_message = this.translate(payload.error_type); @@ -162,8 +205,13 @@ Module.register("calendar", { this.updateDom(this.config.animationSpeed); }, + eventEndingWithinNextFullTimeUnit (event, ONE_DAY) { + const now = new Date(); + return event.endDate - now <= ONE_DAY; + }, + // Override dom generator. - getDom: function () { + getDom () { const ONE_SECOND = 1000; // 1,000 milliseconds const ONE_MINUTE = ONE_SECOND * 60; const ONE_HOUR = ONE_MINUTE * 60; @@ -175,13 +223,13 @@ Module.register("calendar", { if (this.error) { wrapper.innerHTML = this.error; - wrapper.className = this.config.tableClass + " dimmed"; + wrapper.className = `${this.config.tableClass} dimmed`; return wrapper; } if (events.length === 0) { wrapper.innerHTML = this.loaded ? this.translate("EMPTY") : this.translate("LOADING"); - wrapper.className = this.config.tableClass + " dimmed"; + wrapper.className = `${this.config.tableClass} dimmed`; return wrapper; } @@ -204,9 +252,12 @@ Module.register("calendar", { if (this.config.timeFormat === "dateheaders") { if (lastSeenDate !== dateAsString) { const dateRow = document.createElement("tr"); - dateRow.className = "normal"; + dateRow.className = "dateheader normal"; if (event.today) dateRow.className += " today"; + else if (event.dayBeforeYesterday) dateRow.className += " dayBeforeYesterday"; + else if (event.yesterday) dateRow.className += " yesterday"; else if (event.tomorrow) dateRow.className += " tomorrow"; + else if (event.dayAfterTomorrow) dateRow.className += " dayAfterTomorrow"; const dateCell = document.createElement("td"); dateCell.colSpan = "3"; @@ -227,23 +278,34 @@ Module.register("calendar", { const eventWrapper = document.createElement("tr"); - if (this.config.colored && !this.config.coloredSymbolOnly) { - eventWrapper.style.cssText = "color:" + this.colorForUrl(event.url); + if (this.config.coloredText) { + eventWrapper.style.cssText = `color:${this.colorForUrl(event.url, false)}`; } - eventWrapper.className = "normal event"; + if (this.config.coloredBackground) { + eventWrapper.style.backgroundColor = this.colorForUrl(event.url, true); + } + + if (this.config.coloredBorder) { + eventWrapper.style.borderColor = this.colorForUrl(event.url, false); + } + + eventWrapper.className = "event-wrapper normal event"; if (event.today) eventWrapper.className += " today"; + else if (event.dayBeforeYesterday) eventWrapper.className += " dayBeforeYesterday"; + else if (event.yesterday) eventWrapper.className += " yesterday"; else if (event.tomorrow) eventWrapper.className += " tomorrow"; + else if (event.dayAfterTomorrow) eventWrapper.className += " dayAfterTomorrow"; const symbolWrapper = document.createElement("td"); if (this.config.displaySymbol) { - if (this.config.colored && this.config.coloredSymbolOnly) { - symbolWrapper.style.cssText = "color:" + this.colorForUrl(event.url); + if (this.config.coloredSymbol) { + symbolWrapper.style.cssText = `color:${this.colorForUrl(event.url, false)}`; } const symbolClass = this.symbolClassForUrl(event.url); - symbolWrapper.className = "symbol align-right " + symbolClass; + symbolWrapper.className = `symbol align-right ${symbolClass}`; const symbols = this.symbolsForEvent(event); symbols.forEach((s, index) => { @@ -271,60 +333,74 @@ Module.register("calendar", { const thisYear = new Date(parseInt(event.startDate)).getFullYear(), yearDiff = thisYear - event.firstYear; - repeatingCountTitle = ", " + yearDiff + ". " + repeatingCountTitle; + repeatingCountTitle = `, ${yearDiff} ${repeatingCountTitle}`; } } - // Color events if custom color is specified + var transformedTitle = event.title; + + // Color events if custom color or eventClass are specified, transform title if required if (this.config.customEvents.length > 0) { for (let ev in this.config.customEvents) { - if (typeof this.config.customEvents[ev].color !== "undefined" && this.config.customEvents[ev].color !== "") { - let needle = new RegExp(this.config.customEvents[ev].keyword, "gi"); - if (needle.test(event.title)) { + let needle = new RegExp(this.config.customEvents[ev].keyword, "gi"); + if (needle.test(event.title)) { + if (typeof this.config.customEvents[ev].transform === "object") { + transformedTitle = CalendarUtils.titleTransform(transformedTitle, [this.config.customEvents[ev].transform]); + } + if (typeof this.config.customEvents[ev].color !== "undefined" && this.config.customEvents[ev].color !== "") { // Respect parameter ColoredSymbolOnly also for custom events - if (!this.config.coloredSymbolOnly) { - eventWrapper.style.cssText = "color:" + this.config.customEvents[ev].color; - titleWrapper.style.cssText = "color:" + this.config.customEvents[ev].color; + if (this.config.coloredText) { + eventWrapper.style.cssText = `color:${this.config.customEvents[ev].color}`; + titleWrapper.style.cssText = `color:${this.config.customEvents[ev].color}`; } - if (this.config.displaySymbol) { - symbolWrapper.style.cssText = "color:" + this.config.customEvents[ev].color; + if (this.config.displaySymbol && this.config.coloredSymbol) { + symbolWrapper.style.cssText = `color:${this.config.customEvents[ev].color}`; } - break; + } + if (typeof this.config.customEvents[ev].eventClass !== "undefined" && this.config.customEvents[ev].eventClass !== "") { + eventWrapper.className += ` ${this.config.customEvents[ev].eventClass}`; } } } } - titleWrapper.innerHTML = this.titleTransform(event.title, this.config.titleReplace, this.config.wrapEvents, this.config.maxTitleLength, this.config.maxTitleLines) + repeatingCountTitle; + titleWrapper.innerHTML = CalendarUtils.shorten(transformedTitle, this.config.maxTitleLength, this.config.wrapEvents, this.config.maxTitleLines) + repeatingCountTitle; const titleClass = this.titleClassForUrl(event.url); - if (!this.config.colored) { - titleWrapper.className = "title bright " + titleClass; + if (!this.config.coloredText) { + titleWrapper.className = `title bright ${titleClass}`; } else { - titleWrapper.className = "title " + titleClass; + titleWrapper.className = `title ${titleClass}`; } if (this.config.timeFormat === "dateheaders") { + if (this.config.flipDateHeaderTitle) eventWrapper.appendChild(titleWrapper); + if (event.fullDayEvent) { titleWrapper.colSpan = "2"; titleWrapper.classList.add("align-left"); } else { const timeWrapper = document.createElement("td"); - timeWrapper.className = "time light align-left " + this.timeClassForUrl(event.url); + timeWrapper.className = `time light ${this.config.flipDateHeaderTitle ? "align-right " : "align-left "}${this.timeClassForUrl(event.url)}`; timeWrapper.style.paddingLeft = "2px"; + timeWrapper.style.textAlign = this.config.flipDateHeaderTitle ? "right" : "left"; timeWrapper.innerHTML = moment(event.startDate, "x").format("LT"); // Add endDate to dataheaders if showEnd is enabled if (this.config.showEnd) { - timeWrapper.innerHTML += " - " + moment(event.endDate, "x").format("LT"); + if (this.config.showEndsOnlyWithDuration && event.startDate === event.endDate) { + // no duration here, don't display end + } else { + timeWrapper.innerHTML += ` - ${CalendarUtils.capFirst(moment(event.endDate, "x").format("LT"))}`; + } } eventWrapper.appendChild(timeWrapper); - titleWrapper.classList.add("align-right"); - } - eventWrapper.appendChild(titleWrapper); + if (!this.config.flipDateHeaderTitle) titleWrapper.classList.add("align-right"); + } + if (!this.config.flipDateHeaderTitle) eventWrapper.appendChild(titleWrapper); } else { const timeWrapper = document.createElement("td"); @@ -333,52 +409,58 @@ Module.register("calendar", { if (this.config.timeFormat === "absolute") { // Use dateFormat - timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").format(this.config.dateFormat)); + timeWrapper.innerHTML = CalendarUtils.capFirst(moment(event.startDate, "x").format(this.config.dateFormat)); // Add end time if showEnd if (this.config.showEnd) { - timeWrapper.innerHTML += "-"; - timeWrapper.innerHTML += this.capFirst(moment(event.endDate, "x").format(this.config.dateEndFormat)); + if (this.config.showEndsOnlyWithDuration && event.startDate === event.endDate) { + // no duration here, don't display end + } else { + timeWrapper.innerHTML += "-"; + timeWrapper.innerHTML += CalendarUtils.capFirst(moment(event.endDate, "x").format(this.config.dateEndFormat)); + } } // 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 -= ONE_SECOND; - timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").format(this.config.fullDayEventDateFormat)); + timeWrapper.innerHTML = CalendarUtils.capFirst(moment(event.startDate, "x").format(this.config.fullDayEventDateFormat)); } else if (this.config.getRelative > 0 && event.startDate < now) { // Ongoing and getRelative is set - timeWrapper.innerHTML = this.capFirst( + timeWrapper.innerHTML = CalendarUtils.capFirst( this.translate("RUNNING", { - fallback: this.translate("RUNNING") + " {timeUntilEnd}", + fallback: `${this.translate("RUNNING")} {timeUntilEnd}`, timeUntilEnd: moment(event.endDate, "x").fromNow(true) }) ); } 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()); + timeWrapper.innerHTML = CalendarUtils.capFirst(moment(event.startDate, "x").fromNow()); } if (event.fullDayEvent && this.config.nextDaysRelative) { // Full days events within the next two days if (event.today) { - timeWrapper.innerHTML = this.capFirst(this.translate("TODAY")); + timeWrapper.innerHTML = CalendarUtils.capFirst(this.translate("TODAY")); + } else if (event.yesterday) { + timeWrapper.innerHTML = CalendarUtils.capFirst(this.translate("YESTERDAY")); } else if (event.startDate - now < ONE_DAY && event.startDate - now > 0) { - timeWrapper.innerHTML = this.capFirst(this.translate("TOMORROW")); + timeWrapper.innerHTML = CalendarUtils.capFirst(this.translate("TOMORROW")); } else if (event.startDate - now < 2 * ONE_DAY && event.startDate - now > 0) { if (this.translate("DAYAFTERTOMORROW") !== "DAYAFTERTOMORROW") { - timeWrapper.innerHTML = this.capFirst(this.translate("DAYAFTERTOMORROW")); + timeWrapper.innerHTML = CalendarUtils.capFirst(this.translate("DAYAFTERTOMORROW")); } } } } else { // Show relative times - if (event.startDate >= now || (event.fullDayEvent && event.today)) { + if (event.startDate >= now || (event.fullDayEvent && this.eventEndingWithinNextFullTimeUnit(event, ONE_DAY))) { // Use relative time if (!this.config.hideTime && !event.fullDayEvent) { - timeWrapper.innerHTML = this.capFirst(moment(event.startDate, "x").calendar(null, { sameElse: this.config.dateFormat })); + timeWrapper.innerHTML = CalendarUtils.capFirst(moment(event.startDate, "x").calendar(null, { sameElse: this.config.dateFormat })); } else { - timeWrapper.innerHTML = this.capFirst( + timeWrapper.innerHTML = CalendarUtils.capFirst( moment(event.startDate, "x").calendar(null, { - sameDay: this.config.showTimeToday ? "LT" : "[" + this.translate("TODAY") + "]", - nextDay: "[" + this.translate("TOMORROW") + "]", + sameDay: this.config.showTimeToday ? "LT" : `[${this.translate("TODAY")}]`, + nextDay: `[${this.translate("TOMORROW")}]`, nextWeek: "dddd", sameElse: event.fullDayEvent ? this.config.fullDayEventDateFormat : this.config.dateFormat }) @@ -386,57 +468,79 @@ Module.register("calendar", { } if (event.fullDayEvent) { // Full days events within the next two days - if (event.today) { - timeWrapper.innerHTML = this.capFirst(this.translate("TODAY")); + if (event.today || (event.fullDayEvent && this.eventEndingWithinNextFullTimeUnit(event, ONE_DAY))) { + timeWrapper.innerHTML = CalendarUtils.capFirst(this.translate("TODAY")); + } else if (event.dayBeforeYesterday) { + if (this.translate("DAYBEFOREYESTERDAY") !== "DAYBEFOREYESTERDAY") { + timeWrapper.innerHTML = CalendarUtils.capFirst(this.translate("DAYBEFOREYESTERDAY")); + } + } else if (event.yesterday) { + timeWrapper.innerHTML = CalendarUtils.capFirst(this.translate("YESTERDAY")); } else if (event.startDate - now < ONE_DAY && event.startDate - now > 0) { - timeWrapper.innerHTML = this.capFirst(this.translate("TOMORROW")); + timeWrapper.innerHTML = CalendarUtils.capFirst(this.translate("TOMORROW")); } else if (event.startDate - now < 2 * ONE_DAY && event.startDate - now > 0) { if (this.translate("DAYAFTERTOMORROW") !== "DAYAFTERTOMORROW") { - timeWrapper.innerHTML = this.capFirst(this.translate("DAYAFTERTOMORROW")); + timeWrapper.innerHTML = CalendarUtils.capFirst(this.translate("DAYAFTERTOMORROW")); } } } 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()); + timeWrapper.innerHTML = CalendarUtils.capFirst(moment(event.startDate, "x").fromNow()); } } else { // Ongoing event - timeWrapper.innerHTML = this.capFirst( + timeWrapper.innerHTML = CalendarUtils.capFirst( this.translate("RUNNING", { - fallback: this.translate("RUNNING") + " {timeUntilEnd}", + fallback: `${this.translate("RUNNING")} {timeUntilEnd}`, timeUntilEnd: moment(event.endDate, "x").fromNow(true) }) ); } } - timeWrapper.className = "time light " + this.timeClassForUrl(event.url); + timeWrapper.className = `time light ${this.timeClassForUrl(event.url)}`; eventWrapper.appendChild(timeWrapper); } - wrapper.appendChild(eventWrapper); - // Create fade effect. if (index >= startFade) { currentFadeStep = index - startFade; eventWrapper.style.opacity = 1 - (1 / fadeSteps) * currentFadeStep; } + wrapper.appendChild(eventWrapper); if (this.config.showLocation) { if (event.location !== false) { const locationRow = document.createElement("tr"); - locationRow.className = "normal xsmall light"; + locationRow.className = "event-wrapper-location normal xsmall light"; if (event.today) locationRow.className += " today"; + else if (event.dayBeforeYesterday) locationRow.className += " dayBeforeYesterday"; + else if (event.yesterday) locationRow.className += " yesterday"; else if (event.tomorrow) locationRow.className += " tomorrow"; + else if (event.dayAfterTomorrow) locationRow.className += " dayAfterTomorrow"; if (this.config.displaySymbol) { const symbolCell = document.createElement("td"); locationRow.appendChild(symbolCell); } + if (this.config.coloredText) { + locationRow.style.cssText = `color:${this.colorForUrl(event.url, false)}`; + } + + if (this.config.coloredBackground) { + locationRow.style.backgroundColor = this.colorForUrl(event.url, true); + } + + if (this.config.coloredBorder) { + locationRow.style.borderColor = this.colorForUrl(event.url, false); + } + const descCell = document.createElement("td"); descCell.className = "location"; descCell.colSpan = "2"; - descCell.innerHTML = this.titleTransform(event.location, this.config.locationTitleReplace, this.config.wrapLocationEvents, this.config.maxLocationTitleLength, this.config.maxEventTitleLines); + + const transformedTitle = CalendarUtils.titleTransform(event.location, this.config.locationTitleReplace); + descCell.innerHTML = CalendarUtils.shorten(transformedTitle, this.config.maxLocationTitleLength, this.config.wrapLocationEvents, this.config.maxEventTitleLines); locationRow.appendChild(descCell); wrapper.appendChild(locationRow); @@ -452,35 +556,12 @@ Module.register("calendar", { return wrapper; }, - /** - * This function accepts a number (either 12 or 24) and returns a moment.js LocaleSpecification with the - * corresponding timeformat to be used in the calendar display. If no number is given (or otherwise invalid input) - * it will a localeSpecification object with the system locale time format. - * - * @param {number} timeFormat Specifies either 12 or 24 hour time format - * @returns {moment.LocaleSpecification} formatted time - */ - getLocaleSpecification: function (timeFormat) { - switch (timeFormat) { - case 12: { - return { longDateFormat: { LT: "h:mm A" } }; - } - case 24: { - return { longDateFormat: { LT: "HH:mm" } }; - } - default: { - return { longDateFormat: { LT: moment.localeData().longDateFormat("LT") } }; - } - } - }, - /** * Checks if this config contains the calendar url. - * * @param {string} url The calendar url * @returns {boolean} True if the calendar config contains the url, False otherwise */ - hasCalendarURL: function (url) { + hasCalendarURL (url) { for (const calendar of this.config.calendars) { if (calendar.url === url) { return true; @@ -492,24 +573,31 @@ Module.register("calendar", { /** * Creates the sorted list of all events. - * * @param {boolean} limitNumberOfEntries Whether to filter returned events for display. * @returns {object[]} Array with events. */ - createEventList: function (limitNumberOfEntries) { + createEventList (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(); + let now, today, future; + if (this.config.forceUseCurrentTime || this.defaults.forceUseCurrentTime) { + now = new Date(); + today = moment().startOf("day"); + future = moment().startOf("day").add(this.config.maximumNumberOfDays, "days").toDate(); + } else { + now = new Date(Date.now()); // Can use overridden time + today = moment(now).startOf("day"); + future = moment(now).startOf("day").add(this.config.maximumNumberOfDays, "days").toDate(); + } let events = []; for (const calendarUrl in this.calendarData) { const calendar = this.calendarData[calendarUrl]; let remainingEntries = this.maximumEntriesForUrl(calendarUrl); + let maxPastDaysCompare = now - this.maximumPastDaysForUrl(calendarUrl) * ONE_DAY; for (const e in calendar) { const event = JSON.parse(JSON.stringify(calendar[e])); // clone object @@ -518,22 +606,26 @@ Module.register("calendar", { continue; } if (limitNumberOfEntries) { - if (event.endDate < now) { + if (event.endDate < maxPastDaysCompare) { continue; } if (this.config.hideOngoing && event.startDate < now) { continue; } - if (this.listContainsEvent(events, event)) { + if (this.config.hideDuplicates && this.listContainsEvent(events, event)) { continue; } if (--remainingEntries < 0) { break; } } + event.url = calendarUrl; event.today = event.startDate >= today && event.startDate < today + ONE_DAY; + event.dayBeforeYesterday = event.startDate >= today - ONE_DAY * 2 && event.startDate < today - ONE_DAY; + event.yesterday = event.startDate >= today - ONE_DAY && event.startDate < today; event.tomorrow = !event.today && event.startDate >= today + ONE_DAY && event.startDate < today + 2 * ONE_DAY; + event.dayAfterTomorrow = !event.tomorrow && event.startDate >= today + ONE_DAY * 2 && event.startDate < today + 3 * ONE_DAY; /* if sliceMultiDayEvents is set to true, multiday events (events exceeding at least one midnight) are sliced into days, * otherwise, esp. in dateheaders mode it is not clear how long these events are. @@ -541,14 +633,19 @@ Module.register("calendar", { 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 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 + ONE_DAY; thisEvent.tomorrow = !thisEvent.today && thisEvent.startDate >= today + ONE_DAY && thisEvent.startDate < today + 2 * ONE_DAY; thisEvent.endDate = midnight; - thisEvent.title += " (" + count + "/" + maxCount + ")"; + thisEvent.title += ` (${count}/${maxCount})`; splitEvents.push(thisEvent); event.startDate = midnight; @@ -556,7 +653,7 @@ Module.register("calendar", { midnight = moment(midnight, "x").add(1, "day").format("x"); // next day } // Last day - event.title += " (" + count + "/" + maxCount + ")"; + event.title += ` (${count}/${maxCount})`; event.today += event.startDate >= today && event.startDate < today + ONE_DAY; event.tomorrow = !event.today && event.startDate >= today + ONE_DAY && event.startDate < today + 2 * ONE_DAY; splitEvents.push(event); @@ -592,7 +689,7 @@ Module.register("calendar", { // check if we already are showing max unique days if (eventDate > lastDate) { // if the only entry in the first day is a full day event that day is not counted as unique - if (newEvents.length === 1 && days === 1 && newEvents[0].fullDayEvent) { + if (!this.config.limitDaysNeverSkip && newEvents.length === 1 && days === 1 && newEvents[0].fullDayEvent) { days--; } days++; @@ -610,9 +707,9 @@ Module.register("calendar", { return events.slice(0, this.config.maximumEntries); }, - listContainsEvent: function (eventList, event) { + listContainsEvent (eventList, event) { for (const evt of eventList) { - if (evt.title === event.title && parseInt(evt.startDate) === parseInt(event.startDate)) { + if (evt.title === event.title && parseInt(evt.startDate) === parseInt(event.startDate) && parseInt(evt.endDate) === parseInt(event.endDate)) { return true; } } @@ -621,19 +718,19 @@ Module.register("calendar", { /** * Requests node helper to add calendar url. - * * @param {string} url The calendar url to add * @param {object} auth The authentication method and credentials * @param {object} calendarConfig The config of the specific calendar */ - addCalendar: function (url, auth, calendarConfig) { + addCalendar (url, auth, calendarConfig) { this.sendSocketNotification("ADD_CALENDAR", { id: this.identifier, url: url, excludedEvents: calendarConfig.excludedEvents || this.config.excludedEvents, maximumEntries: calendarConfig.maximumEntries || this.config.maximumEntries, maximumNumberOfDays: calendarConfig.maximumNumberOfDays || this.config.maximumNumberOfDays, - fetchInterval: this.config.fetchInterval, + pastDaysCount: calendarConfig.pastDaysCount || this.config.pastDaysCount, + fetchInterval: calendarConfig.fetchInterval || this.config.fetchInterval, symbolClass: calendarConfig.symbolClass, titleClass: calendarConfig.titleClass, timeClass: calendarConfig.timeClass, @@ -645,11 +742,10 @@ Module.register("calendar", { /** * Retrieves the symbols for a specific event. - * * @param {object} event Event to look for. * @returns {string[]} The symbols */ - symbolsForEvent: function (event) { + symbolsForEvent (event) { let symbols = this.getCalendarPropertyAsArray(event.url, "symbol", this.config.defaultSymbol); if (event.recurringEvent === true && this.hasCalendarProperty(event.url, "recurringSymbol")) { @@ -665,7 +761,9 @@ Module.register("calendar", { if (typeof ev.symbol !== "undefined" && ev.symbol !== "") { let needle = new RegExp(ev.keyword, "gi"); if (needle.test(event.title)) { - symbols[0] = ev.symbol; + // Get the default prefix for this class name and add to the custom symbol provided + const className = this.getCalendarProperty(event.url, "symbolClassName", this.config.defaultSymbolClassName); + symbols[0] = className + ev.symbol; break; } } @@ -674,7 +772,7 @@ Module.register("calendar", { return symbols; }, - mergeUnique: function (arr1, arr2) { + mergeUnique (arr1, arr2) { return arr1.concat( arr2.filter(function (item) { return arr1.indexOf(item) === -1; @@ -684,83 +782,85 @@ Module.register("calendar", { /** * Retrieves the symbolClass for a specific calendar url. - * * @param {string} url The calendar url * @returns {string} The class to be used for the symbols of the calendar */ - symbolClassForUrl: function (url) { + symbolClassForUrl (url) { return this.getCalendarProperty(url, "symbolClass", ""); }, /** * Retrieves the titleClass for a specific calendar url. - * * @param {string} url The calendar url * @returns {string} The class to be used for the title of the calendar */ - titleClassForUrl: function (url) { + titleClassForUrl (url) { return this.getCalendarProperty(url, "titleClass", ""); }, /** * Retrieves the timeClass for a specific calendar url. - * * @param {string} url The calendar url * @returns {string} The class to be used for the time of the calendar */ - timeClassForUrl: function (url) { + timeClassForUrl (url) { return this.getCalendarProperty(url, "timeClass", ""); }, /** * Retrieves the calendar name for a specific calendar url. - * * @param {string} url The calendar url * @returns {string} The name of the calendar */ - calendarNameForUrl: function (url) { + calendarNameForUrl (url) { return this.getCalendarProperty(url, "name", ""); }, /** * Retrieves the color for a specific calendar url. - * * @param {string} url The calendar url + * @param {boolean} isBg Determines if we fetch the bgColor or not * @returns {string} The color */ - colorForUrl: function (url) { - return this.getCalendarProperty(url, "color", "#fff"); + colorForUrl (url, isBg) { + return this.getCalendarProperty(url, isBg ? "bgColor" : "color", "#fff"); }, /** * Retrieves the count title for a specific calendar url. - * * @param {string} url The calendar url * @returns {string} The title */ - countTitleForUrl: function (url) { + countTitleForUrl (url) { return this.getCalendarProperty(url, "repeatingCountTitle", this.config.defaultRepeatingCountTitle); }, /** * Retrieves the maximum entry count for a specific calendar url. - * * @param {string} url The calendar url * @returns {number} The maximum entry count */ - maximumEntriesForUrl: function (url) { + maximumEntriesForUrl (url) { return this.getCalendarProperty(url, "maximumEntries", this.config.maximumEntries); }, + /** + * Retrieves the maximum count of past days which events of should be displayed for a specific calendar url. + * @param {string} url The calendar url + * @returns {number} The maximum past days count + */ + maximumPastDaysForUrl (url) { + return this.getCalendarProperty(url, "pastDaysCount", this.config.pastDaysCount); + }, + /** * Helper method to retrieve the property for a specific calendar url. - * * @param {string} url The calendar url * @param {string} property The property to look for * @param {string} defaultValue The value if the property is not found * @returns {*} The property */ - getCalendarProperty: function (url, property, defaultValue) { + getCalendarProperty (url, property, defaultValue) { for (const calendar of this.config.calendars) { if (calendar.url === url && calendar.hasOwnProperty(property)) { return calendar[property]; @@ -770,7 +870,7 @@ Module.register("calendar", { return defaultValue; }, - getCalendarPropertyAsArray: function (url, property, defaultValue) { + getCalendarPropertyAsArray (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); @@ -781,115 +881,48 @@ Module.register("calendar", { return p; }, - hasCalendarProperty: function (url, property) { + hasCalendarProperty (url, property) { return !!this.getCalendarProperty(url, property, undefined); }, - /** - * Shortens a string if it's longer than maxLength and add a ellipsis to the end - * - * @param {string} string Text string to shorten - * @param {number} maxLength The max length of the string - * @param {boolean} wrapEvents Wrap the text after the line has reached maxLength - * @param {number} maxTitleLines The max number of vertical lines before cutting event title - * @returns {string} The shortened string - */ - shorten: function (string, maxLength, wrapEvents, maxTitleLines) { - if (typeof string !== "string") { - return ""; - } - - if (wrapEvents === true) { - const words = string.split(" "); - let temp = ""; - let currentLine = ""; - let line = 0; - - for (let i = 0; i < words.length; i++) { - const word = words[i]; - if (currentLine.length + word.length < (typeof maxLength === "number" ? maxLength : 25) - 1) { - // max - 1 to account for a space - currentLine += word + " "; - } else { - line++; - if (line > maxTitleLines - 1) { - if (i < words.length) { - currentLine += "…"; - } - break; - } - - if (currentLine.length > 0) { - temp += currentLine + "
" + word + " "; - } else { - temp += word + "
"; - } - currentLine = ""; - } - } - - return (temp + currentLine).trim(); - } else { - if (maxLength && typeof maxLength === "number" && string.length > maxLength) { - return string.trim().slice(0, maxLength) + "…"; - } else { - return string.trim(); - } - } - }, - - /** - * Capitalize the first letter of a string - * - * @param {string} string The string to capitalize - * @returns {string} The capitalized string - */ - capFirst: function (string) { - return string.charAt(0).toUpperCase() + string.slice(1); - }, - - /** - * Transforms the title of an event for usage. - * Replaces parts of the text as defined in config.titleReplace. - * Shortens title based on config.maxTitleLength and config.wrapEvents - * - * @param {string} title The title to transform. - * @param {object} titleReplace Pairs of strings to be replaced in the title - * @param {boolean} wrapEvents Wrap the text after the line has reached maxLength - * @param {number} maxTitleLength The max length of the string - * @param {number} maxTitleLines The max number of vertical lines before cutting event title - * @returns {string} The transformed title. - */ - titleTransform: function (title, titleReplace, wrapEvents, maxTitleLength, maxTitleLines) { - for (let needle in titleReplace) { - const replacement = titleReplace[needle]; - - const regParts = needle.match(/^\/(.+)\/([gim]*)$/); - if (regParts) { - // the parsed pattern is a regexp. - needle = new RegExp(regParts[1], regParts[2]); - } - - title = title.replace(needle, replacement); - } - - title = this.shorten(title, maxTitleLength, wrapEvents, maxTitleLines); - return title; - }, - /** * Broadcasts the events to all other modules for reuse. * The all events available in one array, sorted on startdate. */ - broadcastEvents: function () { + broadcastEvents () { const eventList = this.createEventList(false); for (const event of eventList) { event.symbol = this.symbolsForEvent(event); event.calendarName = this.calendarNameForUrl(event.url); - event.color = this.colorForUrl(event.url); + event.color = this.colorForUrl(event.url, false); delete event.url; } this.sendNotification("CALENDAR_EVENTS", eventList); + }, + + /** + * Refresh the DOM every minute if needed: When using relative date format for events that start + * or end in less than an hour, the date shows minute granularity and we want to keep that accurate. + * -- + * When updateOnFetch is not set, it will Avoid fade out/in on updateDom when many calendars are used + * and it's allow to refresh The DOM every minute with animation speed too + * (because updateDom is not set in CALENDAR_EVENTS for this case) + */ + selfUpdate () { + const ONE_MINUTE = 60 * 1000; + setTimeout( + () => { + setInterval(() => { + Log.debug("[Calendar] self update"); + if (this.config.updateOnFetch) { + this.updateDom(1); + } else { + this.updateDom(this.config.animationSpeed); + } + }, ONE_MINUTE); + }, + ONE_MINUTE - (new Date() % ONE_MINUTE) + ); } }); diff --git a/modules/default/calendar/calendarfetcher.js b/modules/default/calendar/calendarfetcher.js index 0798d1785c..824c7c5b4f 100644 --- a/modules/default/calendar/calendarfetcher.js +++ b/modules/default/calendar/calendarfetcher.js @@ -1,16 +1,8 @@ -/* MagicMirror² - * Node Helper: Calendar - CalendarFetcher - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. - */ -const CalendarUtils = require("./calendarutils"); +const https = require("node:https"); +const ical = require("node-ical"); const Log = require("logger"); const NodeHelper = require("node_helper"); -const ical = require("node-ical"); -const fetch = require("fetch"); -const digest = require("digest-fetch"); -const https = require("https"); +const CalendarFetcherUtils = require("./calendarfetcherutils"); /** * @@ -38,10 +30,9 @@ const CalendarFetcher = function (url, reloadInterval, excludedEvents, maximumEn clearTimeout(reloadTimer); reloadTimer = null; const nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]); - let fetcher = null; let httpsAgent = null; let headers = { - "User-Agent": "Mozilla/5.0 (Node.js " + nodeVersion + ") MagicMirror/" + global.version + "User-Agent": `Mozilla/5.0 (Node.js ${nodeVersion}) MagicMirror/${global.version}` }; if (selfSignedCert) { @@ -51,18 +42,13 @@ const CalendarFetcher = function (url, reloadInterval, excludedEvents, maximumEn } if (auth) { if (auth.method === "bearer") { - headers.Authorization = "Bearer " + auth.pass; - } else if (auth.method === "digest") { - fetcher = new digest(auth.user, auth.pass).fetch(url, { headers: headers, agent: httpsAgent }); + headers.Authorization = `Bearer ${auth.pass}`; } else { - headers.Authorization = "Basic " + Buffer.from(auth.user + ":" + auth.pass).toString("base64"); + headers.Authorization = `Basic ${Buffer.from(`${auth.user}:${auth.pass}`).toString("base64")}`; } } - if (fetcher === null) { - fetcher = fetch(url, { headers: headers, agent: httpsAgent }); - } - fetcher + fetch(url, { headers: headers, agent: httpsAgent }) .then(NodeHelper.checkFetchStatus) .then((response) => response.text()) .then((responseData) => { @@ -70,8 +56,8 @@ const CalendarFetcher = function (url, reloadInterval, excludedEvents, maximumEn try { data = ical.parseICS(responseData); - Log.debug("parsed data=" + JSON.stringify(data)); - events = CalendarUtils.filterEvents(data, { + Log.debug(`parsed data=${JSON.stringify(data)}`); + events = CalendarFetcherUtils.filterEvents(data, { excludedEvents, includePastEvents, maximumEntries, @@ -114,13 +100,12 @@ const CalendarFetcher = function (url, reloadInterval, excludedEvents, maximumEn * Broadcast the existing events. */ this.broadcastEvents = function () { - Log.info("Calendar-Fetcher: Broadcasting " + events.length + " events."); + Log.info(`Calendar-Fetcher: Broadcasting ${events.length} events from ${url}.`); eventsReceivedCallback(this); }; /** * Sets the on success callback - * * @param {Function} callback The on success callback. */ this.onReceive = function (callback) { @@ -129,7 +114,6 @@ const CalendarFetcher = function (url, reloadInterval, excludedEvents, maximumEn /** * Sets the on error callback - * * @param {Function} callback The on error callback. */ this.onError = function (callback) { @@ -138,7 +122,6 @@ const CalendarFetcher = function (url, reloadInterval, excludedEvents, maximumEn /** * Returns the url of this fetcher. - * * @returns {string} The url of this fetcher. */ this.url = function () { @@ -147,7 +130,6 @@ const CalendarFetcher = function (url, reloadInterval, excludedEvents, maximumEn /** * Returns current available events for this fetcher. - * * @returns {object[]} The current available events for this fetcher. */ this.events = function () { diff --git a/modules/default/calendar/calendarfetcherutils.js b/modules/default/calendar/calendarfetcherutils.js new file mode 100644 index 0000000000..eec3540f29 --- /dev/null +++ b/modules/default/calendar/calendarfetcherutils.js @@ -0,0 +1,585 @@ +/** + * @external Moment + */ +const path = require("node:path"); +const moment = require("moment"); + +const zoneTable = require(path.join(__dirname, "windowsZones.json")); +const Log = require("../../../js/logger"); + +const CalendarFetcherUtils = { + + /** + * Calculate the time correction, either dst/std or full day in cases where + * utc time is day before plus offset + * @param {object} event the event which needs adjustment + * @param {Date} date the date on which this event happens + * @returns {number} the necessary adjustment in hours + */ + calculateTimezoneAdjustment (event, date) { + let adjustHours = 0; + // if a timezone was specified + if (!event.start.tz) { + Log.debug(" if no tz, guess based on now"); + event.start.tz = moment.tz.guess(); + } + Log.debug(`initial tz=${event.start.tz}`); + + // if there is a start date specified + if (event.start.tz) { + // if this is a windows timezone + if (event.start.tz.includes(" ")) { + // use the lookup table to get theIANA name as moment and date don't know MS timezones + let tz = CalendarFetcherUtils.getIanaTZFromMS(event.start.tz); + Log.debug(`corrected TZ=${tz}`); + // watch out for unregistered windows timezone names + // if we had a successful lookup + if (tz) { + // change the timezone to the IANA name + event.start.tz = tz; + // Log.debug("corrected timezone="+event.start.tz) + } + } + Log.debug(`corrected tz=${event.start.tz}`); + let current_offset = 0; // offset from TZ string or calculated + let mm = 0; // date with tz or offset + let start_offset = 0; // utc offset of created with tz + // if there is still an offset, lookup failed, use it + if (event.start.tz.startsWith("(")) { + const regex = /[+|-]\d*:\d*/; + const start_offsetString = event.start.tz.match(regex).toString().split(":"); + let start_offset = parseInt(start_offsetString[0]); + start_offset *= event.start.tz[1] === "-" ? -1 : 1; + adjustHours = start_offset; + Log.debug(`defined offset=${start_offset} hours`); + current_offset = start_offset; + event.start.tz = ""; + Log.debug(`ical offset=${current_offset} date=${date}`); + mm = moment(date); + let x = moment(new Date()).utcOffset(); + Log.debug(`net mins=${current_offset * 60 - x}`); + + mm = mm.add(x - current_offset * 60, "minutes"); + adjustHours = (current_offset * 60 - x) / 60; + event.start = mm.toDate(); + Log.debug(`adjusted date=${event.start}`); + } else { + // get the start time in that timezone + let es = moment(event.start); + // check for start date prior to start of daylight changing date + if (es.format("YYYY") < 2007) { + es.set("year", 2013); // if so, use a closer date + } + Log.debug(`start date/time=${es.toDate()}`); + start_offset = moment.tz(es, event.start.tz).utcOffset(); + Log.debug(`start offset=${start_offset}`); + + Log.debug(`start date/time w tz =${moment.tz(moment(event.start), event.start.tz).toDate()}`); + + // get the specified date in that timezone + mm = moment.tz(moment(date), event.start.tz); + Log.debug(`event date=${mm.toDate()}`); + current_offset = mm.utcOffset(); + } + Log.debug(`event offset=${current_offset} hour=${mm.format("H")} event date=${mm.toDate()}`); + + // if the offset is greater than 0, east of london + if (current_offset !== start_offset) { + // big offset + Log.debug("offset"); + let h = parseInt(mm.format("H")); + // check if the event time is less than the offset + if (h > 0 && h < Math.abs(current_offset) / 60) { + // if so, rrule created a wrong date (utc day, oops, with utc yesterday adjusted time) + // we need to fix that + //adjustHours = 24; + // Log.debug("adjusting date") + } + //-300 > -240 + //if (Math.abs(current_offset) > Math.abs(start_offset)){ + if (current_offset > start_offset) { + adjustHours -= 1; + Log.debug("adjust down 1 hour dst change"); + //} else if (Math.abs(current_offset) < Math.abs(start_offset)) { + } else if (current_offset < start_offset) { + adjustHours += 1; + Log.debug("adjust up 1 hour dst change"); + } + } + } + Log.debug(`adjustHours=${adjustHours}`); + return adjustHours; + }, + + /** + * Filter the events from ical according to the given config + * @param {object} data the calendar data from ical + * @param {object} config The configuration object + * @returns {string[]} the filtered events + */ + filterEvents (data, config) { + const newEvents = []; + + // limitFunction doesn't do much limiting, see comment re: the dates + // array in rrule section below as to why we need to do the filtering + // ourselves + const limitFunction = function (date, i) { + return true; + }; + + const eventDate = function (event, time) { + return CalendarFetcherUtils.isFullDayEvent(event) ? moment(event[time]).startOf("day") : moment(event[time]); + }; + + Log.debug(`There are ${Object.entries(data).length} calendar entries.`); + + const now = new Date(Date.now()); + const todayLocal = moment(now).startOf("day").toDate(); + const futureLocalDate + = moment(now) + .startOf("day") + .add(config.maximumNumberOfDays, "days") + .subtract(1, "seconds") // Subtract 1 second so that events that start on the middle of the night will not repeat. + .toDate(); + + Object.entries(data).forEach(([key, event]) => { + Log.debug("Processing entry..."); + let pastLocalDate = todayLocal; + + if (config.includePastEvents) { + pastLocalDate = moment(now).startOf("day").subtract(config.maximumNumberOfDays, "days").toDate(); + } + + // FIXME: Ugly fix to solve the facebook birthday issue. + // Otherwise, the recurring events only show the birthday for next year. + let isFacebookBirthday = false; + if (typeof event.uid !== "undefined") { + if (event.uid.indexOf("@facebook.com") !== -1) { + isFacebookBirthday = true; + } + } + + if (event.type === "VEVENT") { + Log.debug(`Event:\n${JSON.stringify(event)}`); + let startMoment = eventDate(event, "start"); + let endMoment; + + if (typeof event.end !== "undefined") { + endMoment = eventDate(event, "end"); + } else if (typeof event.duration !== "undefined") { + endMoment = startMoment.clone().add(moment.duration(event.duration)); + } else { + if (!isFacebookBirthday) { + // make copy of start date, separate storage area + endMoment = moment(startMoment.valueOf()); + } else { + endMoment = moment(startMoment).add(1, "days"); + } + } + + Log.debug(`start: ${startMoment.toDate()}`); + Log.debug(`end:: ${endMoment.toDate()}`); + + // Calculate the duration of the event for use with recurring events. + const durationMs = endMoment.valueOf() - startMoment.valueOf(); + Log.debug(`duration: ${durationMs}`); + + // FIXME: Since the parsed json object from node-ical comes with time information + // this check could be removed (?) + if (event.start.length === 8) { + startMoment = startMoment.startOf("day"); + } + + const title = CalendarFetcherUtils.getTitleFromEvent(event); + Log.debug(`title: ${title}`); + + let excluded = false, + dateFilter = null; + + for (let f in config.excludedEvents) { + let filter = config.excludedEvents[f], + testTitle = title.toLowerCase(), + until = null, + useRegex = false, + regexFlags = "g"; + + if (filter instanceof Object) { + if (typeof filter.until !== "undefined") { + until = filter.until; + } + + if (typeof filter.regex !== "undefined") { + useRegex = filter.regex; + } + + // If additional advanced filtering is added in, this section + // must remain last as we overwrite the filter object with the + // filterBy string + if (filter.caseSensitive) { + filter = filter.filterBy; + testTitle = title; + } else if (useRegex) { + filter = filter.filterBy; + testTitle = title; + regexFlags += "i"; + } else { + filter = filter.filterBy.toLowerCase(); + } + } else { + filter = filter.toLowerCase(); + } + + if (CalendarFetcherUtils.titleFilterApplies(testTitle, filter, useRegex, regexFlags)) { + if (until) { + dateFilter = until; + } else { + excluded = true; + } + break; + } + } + + if (excluded) { + return; + } + + const location = event.location || false; + const geo = event.geo || false; + const description = event.description || false; + + if (event.rrule && typeof event.rrule !== "undefined" && !isFacebookBirthday) { + const rule = event.rrule; + + const pastMoment = moment(pastLocalDate); + const futureMoment = moment(futureLocalDate); + + // can cause problems with e.g. birthdays before 1900 + if ((rule.options && rule.origOptions && rule.origOptions.dtstart && rule.origOptions.dtstart.getFullYear() < 1900) || (rule.options && rule.options.dtstart && rule.options.dtstart.getFullYear() < 1900)) { + rule.origOptions.dtstart.setYear(1900); + rule.options.dtstart.setYear(1900); + } + + // For recurring events, get the set of start dates that fall within the range + // of dates we're looking for. + // kblankenship1989 - to fix issue #1798, converting all dates to locale time first, then converting back to UTC time + let pastLocal; + let futureLocal; + if (CalendarFetcherUtils.isFullDayEvent(event)) { + Log.debug("fullday"); + // if full day event, only use the date part of the ranges + pastLocal = pastMoment.toDate(); + futureLocal = futureMoment.toDate(); + + Log.debug(`pastLocal: ${pastLocal}`); + Log.debug(`futureLocal: ${futureLocal}`); + } else { + // if we want past events + if (config.includePastEvents) { + // use the calculated past time for the between from + pastLocal = pastMoment.toDate(); + } else { + // otherwise use NOW.. cause we shouldn't use any before now + pastLocal = moment(now).toDate(); //now + } + futureLocal = futureMoment.toDate(); // future + } + Log.debug(`Search for recurring events between: ${pastLocal} and ${futureLocal}`); + const hasByWeekdayRule = rule.options.byweekday !== undefined && rule.options.byweekday !== null; + const oneDayInMs = 24 * 60 * 60 * 1000; + Log.debug(`RRule: ${rule.toString()}`); + rule.options.tzid = null; // RRule gets *very* confused with timezones + let dates = rule.between(new Date(pastLocal.valueOf() - oneDayInMs), new Date(futureLocal.valueOf() + oneDayInMs), true, () => { return true; }); + Log.debug(`Title: ${event.summary}, with dates: ${JSON.stringify(dates)}`); + dates = dates.filter((d) => { + if (JSON.stringify(d) === "null") return false; + else return true; + }); + + // RRule can generate dates with an incorrect recurrence date. Process the array here and apply date correction. + if (hasByWeekdayRule) { + Log.debug("Rule has byweekday, checking for correction"); + dates.forEach((date, index, arr) => { + // NOTE: getTimezoneOffset() is negative of the expected value. For America/Los_Angeles under DST (GMT-7), + // this value is +420. For Australia/Sydney under DST (GMT+11), this value is -660. + const tzOffset = date.getTimezoneOffset() / 60; + const hour = date.getHours(); + if ((tzOffset < 0) && (hour < -tzOffset)) { // east of GMT + Log.debug(`East of GMT (tzOffset: ${tzOffset}) and hour=${hour} < ${-tzOffset}, Subtracting 1 day from ${date}`); + arr[index] = new Date(date.valueOf() - oneDayInMs); + } else if ((tzOffset > 0) && (hour >= (24 - tzOffset))) { // west of GMT + Log.debug(`West of GMT (tzOffset: ${tzOffset}) and hour=${hour} >= 24-${tzOffset}, Adding 1 day to ${date}`); + arr[index] = new Date(date.valueOf() + oneDayInMs); + } + }); + // Adjusting the dates could push it beyond the 'until' date, so filter those out here. + if (rule.options.until !== null) { + dates = dates.filter((date) => { + return date.valueOf() <= rule.options.until.valueOf(); + }); + } + } + + // The dates array from rrule can be confused by DST. If the event was created during DST and we + // are querying a date range during non-DST, rrule can have the incorrect time for the date range. + // Reprocess the array here computing and applying the time offset. + dates.forEach((date, index, arr) => { + let adjustHours = CalendarFetcherUtils.calculateTimezoneAdjustment(event, date); + if (adjustHours !== 0) { + Log.debug(`Applying timezone adjustment hours=${adjustHours} to ${date}`); + arr[index] = new Date(date.valueOf() + (adjustHours * 60 * 60 * 1000)); + } + }); + + // The "dates" array contains the set of dates within our desired date range range that are valid + // for the recurrence rule. *However*, it's possible for us to have a specific recurrence that + // had its date changed from outside the range to inside the range. For the time being, + // we'll handle this by adding *all* recurrence entries into the set of dates that we check, + // because the logic below will filter out any recurrences that don't actually belong within + // our display range. + // Would be great if there was a better way to handle this. + Log.debug(`event.recurrences: ${event.recurrences}`); + if (event.recurrences !== undefined) { + for (let dateKey in event.recurrences) { + // Only add dates that weren't already in the range we added from the rrule so that + // we don't double-add those events. + let d = new Date(dateKey); + if (!moment(d).isBetween(pastMoment, futureMoment)) { + dates.push(d); + } + } + } + + // Lastly, sometimes rrule doesn't include the event.start even if it is in the requested range. Ensure + // inclusion here. Unfortunately dates.includes() doesn't find it so we have to do forEach(). + { + let found = false; + dates.forEach((d) => { if (d.valueOf() === event.start.valueOf()) found = true; }); + if (!found) { + Log.debug(`event.start=${event.start} was not included in results from rrule; adding`); + dates.splice(0, 0, event.start); + } + } + + // Loop through the set of date entries to see which recurrences should be added to our event list. + for (let d in dates) { + let date = dates[d]; + let curEvent = event; + let curDurationMs = durationMs; + let showRecurrence = true; + + startMoment = moment(date); + + // Remove the time information of each date by using its substring, using the following method: + // .toISOString().substring(0,10). + // since the date is given as ISOString with YYYY-MM-DDTHH:MM:SS.SSSZ + // (see https://momentjs.com/docs/#/displaying/as-iso-string/). + // This must be done after `date` is adjusted + const dateKey = date.toISOString().substring(0, 10); + + // For each date that we're checking, it's possible that there is a recurrence override for that one day. + if (curEvent.recurrences !== undefined && curEvent.recurrences[dateKey] !== undefined) { + // We found an override, so for this recurrence, use a potentially different title, start date, and duration. + curEvent = curEvent.recurrences[dateKey]; + startMoment = moment(curEvent.start); + curDurationMs = curEvent.end.valueOf() - startMoment.valueOf(); + } + // If there's no recurrence override, check for an exception date. Exception dates represent exceptions to the rule. + else if (curEvent.exdate !== undefined && curEvent.exdate[dateKey] !== undefined) { + // This date is an exception date, which means we should skip it in the recurrence pattern. + showRecurrence = false; + } + Log.debug(`duration: ${curDurationMs}`); + + endMoment = moment(startMoment.valueOf() + curDurationMs); + if (startMoment.valueOf() === endMoment.valueOf()) { + endMoment = endMoment.endOf("day"); + } + + const recurrenceTitle = CalendarFetcherUtils.getTitleFromEvent(curEvent); + + // If this recurrence ends before the start of the date range, or starts after the end of the date range, don"t add + // it to the event list. + if (endMoment.isBefore(pastLocal) || startMoment.isAfter(futureLocal)) { + showRecurrence = false; + } + + if (CalendarFetcherUtils.timeFilterApplies(now, endMoment, dateFilter)) { + showRecurrence = false; + } + + if (showRecurrence === true) { + Log.debug(`saving event: ${description}`); + newEvents.push({ + title: recurrenceTitle, + startDate: startMoment.format("x"), + endDate: endMoment.format("x"), + fullDayEvent: CalendarFetcherUtils.isFullDayEvent(event), + recurringEvent: true, + class: event.class, + firstYear: event.start.getFullYear(), + location: location, + geo: geo, + description: description + }); + } + } + // End recurring event parsing. + } else { + // Single event. + const fullDayEvent = isFacebookBirthday ? true : CalendarFetcherUtils.isFullDayEvent(event); + // Log.debug("full day event") + + // if the start and end are the same, then make end the 'end of day' value (start is at 00:00:00) + if (fullDayEvent && startMoment.valueOf() === endMoment.valueOf()) { + endMoment = endMoment.endOf("day"); + } + + if (config.includePastEvents) { + // Past event is too far in the past, so skip. + if (endMoment < pastLocalDate) { + return; + } + } else { + // It's not a fullday event, and it is in the past, so skip. + if (!fullDayEvent && endMoment < now) { + return; + } + + // It's a fullday event, and it is before today, So skip. + if (fullDayEvent && endMoment <= todayLocal) { + return; + } + } + + // It exceeds the maximumNumberOfDays limit, so skip. + if (startMoment > futureLocalDate) { + return; + } + + if (CalendarFetcherUtils.timeFilterApplies(now, endMoment, dateFilter)) { + return; + } + + // get correction for date saving and dst change between now and then + let adjustHours = CalendarFetcherUtils.calculateTimezoneAdjustment(event, startMoment.toDate()); + // This shouldn't happen + if (adjustHours) { + Log.warn(`Unexpected timezone adjustment of ${adjustHours} hours on non-recurring event`); + } + // Every thing is good. Add it to the list. + newEvents.push({ + title: title, + startDate: startMoment.add(adjustHours, "hours").format("x"), + endDate: endMoment.add(adjustHours, "hours").format("x"), + fullDayEvent: fullDayEvent, + class: event.class, + location: location, + geo: geo, + description: description + }); + } + } + }); + + newEvents.sort(function (a, b) { + return a.startDate - b.startDate; + }); + + return newEvents; + }, + + /** + * Lookup iana tz from windows + * @param {string} msTZName the timezone name to lookup + * @returns {string|null} the iana name or null of none is found + */ + getIanaTZFromMS (msTZName) { + // Get hash entry + const he = zoneTable[msTZName]; + // If found return iana name, else null + return he ? he.iana[0] : null; + }, + + /** + * Gets the title from the event. + * @param {object} event The event object to check. + * @returns {string} The title of the event, or "Event" if no title is found. + */ + getTitleFromEvent (event) { + let title = "Event"; + if (event.summary) { + title = typeof event.summary.val !== "undefined" ? event.summary.val : event.summary; + } else if (event.description) { + title = event.description; + } + + return title; + }, + + /** + * Checks if an event is a fullday event. + * @param {object} event The event object to check. + * @returns {boolean} True if the event is a fullday event, false otherwise + */ + isFullDayEvent (event) { + if (event.start.length === 8 || event.start.dateOnly || event.datetype === "date") { + return true; + } + + const start = event.start || 0; + const startDate = new Date(start); + const end = event.end || 0; + if ((end - start) % (24 * 60 * 60 * 1000) === 0 && startDate.getHours() === 0 && startDate.getMinutes() === 0) { + // Is 24 hours, and starts on the middle of the night. + return true; + } + + return false; + }, + + /** + * Determines if the user defined time filter should apply + * @param {Date} now Date object using previously created object for consistency + * @param {Moment} endDate Moment object representing the event end date + * @param {string} filter The time to subtract from the end date to determine if an event should be shown + * @returns {boolean} True if the event should be filtered out, false otherwise + */ + timeFilterApplies (now, endDate, filter) { + if (filter) { + const until = filter.split(" "), + value = parseInt(until[0]), + increment = until[1].slice(-1) === "s" ? until[1] : `${until[1]}s`, // Massage the data for moment js + filterUntil = moment(endDate.format()).subtract(value, increment); + + return now < filterUntil.toDate(); + } + + return false; + }, + + /** + * Determines if the user defined title filter should apply + * @param {string} title the title of the event + * @param {string} filter the string to look for, can be a regex also + * @param {boolean} useRegex true if a regex should be used, otherwise it just looks for the filter as a string + * @param {string} regexFlags flags that should be applied to the regex + * @returns {boolean} True if the title should be filtered out, false otherwise + */ + titleFilterApplies (title, filter, useRegex, regexFlags) { + if (useRegex) { + let regexFilter = filter; + // Assume if leading slash, there is also trailing slash + if (filter[0] === "/") { + // Strip leading and trailing slashes + regexFilter = filter.substr(1).slice(0, -1); + } + return new RegExp(regexFilter, regexFlags).test(title); + } else { + return title.includes(filter); + } + } +}; + +if (typeof module !== "undefined") { + module.exports = CalendarFetcherUtils; +} diff --git a/modules/default/calendar/calendarutils.js b/modules/default/calendar/calendarutils.js index 20c8ff0a25..5cbc8d6824 100644 --- a/modules/default/calendar/calendarutils.js +++ b/modules/default/calendar/calendarutils.js @@ -1,610 +1,125 @@ -/* MagicMirror² - * Calendar Util Methods - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. - */ - -/** - * @external Moment - */ -const moment = require("moment"); -const path = require("path"); -const zoneTable = require(path.join(__dirname, "windowsZones.json")); -const Log = require("../../../js/logger.js"); - const CalendarUtils = { + /** - * Calculate the time correction, either dst/std or full day in cases where - * utc time is day before plus offset - * - * @param {object} event the event which needs adjustement - * @param {Date} date the date on which this event happens - * @returns {number} the necessary adjustment in hours + * Capitalize the first letter of a string + * @param {string} string The string to capitalize + * @returns {string} The capitalized string */ - calculateTimezoneAdjustment: function (event, date) { - let adjustHours = 0; - // if a timezone was specified - if (!event.start.tz) { - Log.debug(" if no tz, guess based on now"); - event.start.tz = moment.tz.guess(); - } - Log.debug("initial tz=" + event.start.tz); + capFirst (string) { + return string.charAt(0).toUpperCase() + string.slice(1); + }, - // if there is a start date specified - if (event.start.tz) { - // if this is a windows timezone - if (event.start.tz.includes(" ")) { - // use the lookup table to get theIANA name as moment and date don't know MS timezones - let tz = CalendarUtils.getIanaTZFromMS(event.start.tz); - Log.debug("corrected TZ=" + tz); - // watch out for unregistered windows timezone names - // if we had a successful lookup - if (tz) { - // change the timezone to the IANA name - event.start.tz = tz; - // Log.debug("corrected timezone="+event.start.tz) - } + /** + * This function accepts a number (either 12 or 24) and returns a moment.js LocaleSpecification with the + * corresponding time-format to be used in the calendar display. If no number is given (or otherwise invalid input) + * it will a localeSpecification object with the system locale time format. + * @param {number} timeFormat Specifies either 12 or 24-hour time format + * @returns {moment.LocaleSpecification} formatted time + */ + getLocaleSpecification (timeFormat) { + switch (timeFormat) { + case 12: { + return { longDateFormat: { LT: "h:mm A" } }; } - Log.debug("corrected tz=" + event.start.tz); - let current_offset = 0; // offset from TZ string or calculated - let mm = 0; // date with tz or offset - let start_offset = 0; // utc offset of created with tz - // if there is still an offset, lookup failed, use it - if (event.start.tz.startsWith("(")) { - const regex = /[+|-]\d*:\d*/; - const start_offsetString = event.start.tz.match(regex).toString().split(":"); - let start_offset = parseInt(start_offsetString[0]); - start_offset *= event.start.tz[1] === "-" ? -1 : 1; - adjustHours = start_offset; - Log.debug("defined offset=" + start_offset + " hours"); - current_offset = start_offset; - event.start.tz = ""; - Log.debug("ical offset=" + current_offset + " date=" + date); - mm = moment(date); - let x = parseInt(moment(new Date()).utcOffset()); - Log.debug("net mins=" + (current_offset * 60 - x)); - - mm = mm.add(x - current_offset * 60, "minutes"); - adjustHours = (current_offset * 60 - x) / 60; - event.start = mm.toDate(); - Log.debug("adjusted date=" + event.start); - } else { - // get the start time in that timezone - let es = moment(event.start); - // check for start date prior to start of daylight changing date - if (es.format("YYYY") < 2007) { - es.set("year", 2013); // if so, use a closer date - } - Log.debug("start date/time=" + es.toDate()); - start_offset = moment.tz(es, event.start.tz).utcOffset(); - Log.debug("start offset=" + start_offset); - - Log.debug("start date/time w tz =" + moment.tz(moment(event.start), event.start.tz).toDate()); - - // get the specified date in that timezone - mm = moment.tz(moment(date), event.start.tz); - Log.debug("event date=" + mm.toDate()); - current_offset = mm.utcOffset(); + case 24: { + return { longDateFormat: { LT: "HH:mm" } }; } - Log.debug("event offset=" + current_offset + " hour=" + mm.format("H") + " event date=" + mm.toDate()); - - // if the offset is greater than 0, east of london - if (current_offset !== start_offset) { - // big offset - Log.debug("offset"); - let h = parseInt(mm.format("H")); - // check if the event time is less than the offset - if (h > 0 && h < Math.abs(current_offset) / 60) { - // if so, rrule created a wrong date (utc day, oops, with utc yesterday adjusted time) - // we need to fix that - //adjustHours = 24; - // Log.debug("adjusting date") - } - //-300 > -240 - //if (Math.abs(current_offset) > Math.abs(start_offset)){ - if (current_offset > start_offset) { - adjustHours -= 1; - Log.debug("adjust down 1 hour dst change"); - //} else if (Math.abs(current_offset) < Math.abs(start_offset)) { - } else if (current_offset < start_offset) { - adjustHours += 1; - Log.debug("adjust up 1 hour dst change"); - } + default: { + return { longDateFormat: { LT: moment.localeData().longDateFormat("LT") } }; } } - Log.debug("adjustHours=" + adjustHours); - return adjustHours; }, /** - * Filter the events from ical according to the given config - * - * @param {object} data the calendar data from ical - * @param {object} config The configuration object - * @returns {string[]} the filtered events + * Shortens a string if it's longer than maxLength and add an ellipsis to the end + * @param {string} string Text string to shorten + * @param {number} maxLength The max length of the string + * @param {boolean} wrapEvents Wrap the text after the line has reached maxLength + * @param {number} maxTitleLines The max number of vertical lines before cutting event title + * @returns {string} The shortened string */ - filterEvents: function (data, config) { - const newEvents = []; - - // limitFunction doesn't do much limiting, see comment re: the dates - // array in rrule section below as to why we need to do the filtering - // ourselves - const limitFunction = function (date, i) { - return true; - }; - - const eventDate = function (event, time) { - return CalendarUtils.isFullDayEvent(event) ? moment(event[time], "YYYYMMDD") : moment(new Date(event[time])); - }; - - Log.debug("There are " + Object.entries(data).length + " calendar entries."); - Object.entries(data).forEach(([key, event]) => { - Log.debug("Processing entry..."); - const now = new Date(); - const today = moment().startOf("day").toDate(); - const future = moment().startOf("day").add(config.maximumNumberOfDays, "days").subtract(1, "seconds").toDate(); // Subtract 1 second so that events that start on the middle of the night will not repeat. - let past = today; - - if (config.includePastEvents) { - past = moment().startOf("day").subtract(config.maximumNumberOfDays, "days").toDate(); - } - - // FIXME: Ugly fix to solve the facebook birthday issue. - // Otherwise, the recurring events only show the birthday for next year. - let isFacebookBirthday = false; - if (typeof event.uid !== "undefined") { - if (event.uid.indexOf("@facebook.com") !== -1) { - isFacebookBirthday = true; - } - } - - if (event.type === "VEVENT") { - Log.debug("Event:\n" + JSON.stringify(event)); - let startDate = eventDate(event, "start"); - let endDate; + shorten (string, maxLength, wrapEvents, maxTitleLines) { + if (typeof string !== "string") { + return ""; + } - if (typeof event.end !== "undefined") { - endDate = eventDate(event, "end"); - } else if (typeof event.duration !== "undefined") { - endDate = startDate.clone().add(moment.duration(event.duration)); + if (wrapEvents === true) { + const words = string.split(" "); + let temp = ""; + let currentLine = ""; + let line = 0; + + for (let i = 0; i < words.length; i++) { + const word = words[i]; + if (currentLine.length + word.length < (typeof maxLength === "number" ? maxLength : 25) - 1) { + // max - 1 to account for a space + currentLine += `${word} `; } else { - if (!isFacebookBirthday) { - // make copy of start date, separate storage area - endDate = moment(startDate.format("x"), "x"); - } else { - endDate = moment(startDate).add(1, "days"); - } - } - - Log.debug("start: " + startDate.toDate()); - Log.debug("end:: " + endDate.toDate()); - - // Calculate the duration of the event for use with recurring events. - let duration = parseInt(endDate.format("x")) - parseInt(startDate.format("x")); - Log.debug("duration: " + duration); - - // FIXME: Since the parsed json object from node-ical comes with time information - // this check could be removed (?) - if (event.start.length === 8) { - startDate = startDate.startOf("day"); - } - - const title = CalendarUtils.getTitleFromEvent(event); - Log.debug("title: " + title); - - let excluded = false, - dateFilter = null; - - for (let f in config.excludedEvents) { - let filter = config.excludedEvents[f], - testTitle = title.toLowerCase(), - until = null, - useRegex = false, - regexFlags = "g"; - - if (filter instanceof Object) { - if (typeof filter.until !== "undefined") { - until = filter.until; - } - - if (typeof filter.regex !== "undefined") { - useRegex = filter.regex; - } - - // If additional advanced filtering is added in, this section - // must remain last as we overwrite the filter object with the - // filterBy string - if (filter.caseSensitive) { - filter = filter.filterBy; - testTitle = title; - } else if (useRegex) { - filter = filter.filterBy; - testTitle = title; - regexFlags += "i"; - } else { - filter = filter.filterBy.toLowerCase(); - } - } else { - filter = filter.toLowerCase(); - } - - if (CalendarUtils.titleFilterApplies(testTitle, filter, useRegex, regexFlags)) { - if (until) { - dateFilter = until; - } else { - excluded = true; + line++; + if (line > maxTitleLines - 1) { + if (i < words.length) { + currentLine += "…"; } break; } - } - - if (excluded) { - return; - } - - const location = event.location || false; - const geo = event.geo || false; - const description = event.description || false; - - if (typeof event.rrule !== "undefined" && event.rrule !== null && !isFacebookBirthday) { - const rule = event.rrule; - let addedEvents = 0; - - const pastMoment = moment(past); - const futureMoment = moment(future); - - // can cause problems with e.g. birthdays before 1900 - if ((rule.options && rule.origOptions && rule.origOptions.dtstart && rule.origOptions.dtstart.getFullYear() < 1900) || (rule.options && rule.options.dtstart && rule.options.dtstart.getFullYear() < 1900)) { - rule.origOptions.dtstart.setYear(1900); - rule.options.dtstart.setYear(1900); - } - - // For recurring events, get the set of start dates that fall within the range - // of dates we're looking for. - // kblankenship1989 - to fix issue #1798, converting all dates to locale time first, then converting back to UTC time - let pastLocal = 0; - let futureLocal = 0; - if (CalendarUtils.isFullDayEvent(event)) { - Log.debug("fullday"); - // if full day event, only use the date part of the ranges - pastLocal = pastMoment.toDate(); - futureLocal = futureMoment.toDate(); - - Log.debug("pastLocal: " + pastLocal); - Log.debug("futureLocal: " + futureLocal); - } else { - // if we want past events - if (config.includePastEvents) { - // use the calculated past time for the between from - pastLocal = pastMoment.toDate(); - } else { - // otherwise use NOW.. cause we shouldn't use any before now - pastLocal = moment().toDate(); //now - } - futureLocal = futureMoment.toDate(); // future - } - Log.debug("Search for recurring events between: " + pastLocal + " and " + futureLocal); - const dates = rule.between(pastLocal, futureLocal, true, limitFunction); - Log.debug("Title: " + event.summary + ", with dates: " + JSON.stringify(dates)); - // The "dates" array contains the set of dates within our desired date range range that are valid - // for the recurrence rule. *However*, it's possible for us to have a specific recurrence that - // had its date changed from outside the range to inside the range. For the time being, - // we'll handle this by adding *all* recurrence entries into the set of dates that we check, - // because the logic below will filter out any recurrences that don't actually belong within - // our display range. - // Would be great if there was a better way to handle this. - Log.debug("event.recurrences: " + event.recurrences); - if (event.recurrences !== undefined) { - for (let r in event.recurrences) { - // Only add dates that weren't already in the range we added from the rrule so that - // we don"t double-add those events. - if (moment(new Date(r)).isBetween(pastMoment, futureMoment) !== true) { - dates.push(new Date(r)); - } - } - } - // Loop through the set of date entries to see which recurrences should be added to our event list. - for (let d in dates) { - let date = dates[d]; - // Remove the time information of each date by using its substring, using the following method: - // .toISOString().substring(0,10). - // since the date is given as ISOString with YYYY-MM-DDTHH:MM:SS.SSSZ - // (see https://momentjs.com/docs/#/displaying/as-iso-string/). - const dateKey = date.toISOString().substring(0, 10); - let curEvent = event; - let showRecurrence = true; - - // Get the offset of today where we are processing - // This will be the correction, we need to apply. - let nowOffset = new Date().getTimezoneOffset(); - // For full day events, the time might be off from RRULE/Luxon problem - // Get time zone offset of the rule calculated event - let dateoffset = date.getTimezoneOffset(); - - // Reduce the time by the following offset. - Log.debug(" recurring date is " + date + " offset is " + dateoffset); - - let dh = moment(date).format("HH"); - Log.debug(" recurring date is " + date + " offset is " + dateoffset / 60 + " Hour is " + dh); - - if (CalendarUtils.isFullDayEvent(event)) { - Log.debug("Fullday"); - // If the offset is negative (east of GMT), where the problem is - if (dateoffset < 0) { - if (dh < Math.abs(dateoffset / 60)) { - // if the rrule byweekday WAS explicitly set , correct it - // reduce the time by the offset - if (curEvent.rrule.origOptions.byweekday !== undefined) { - // Apply the correction to the date/time to get it UTC relative - date = new Date(date.getTime() - Math.abs(24 * 60) * 60000); - } - // the duration was calculated way back at the top before we could correct the start time.. - // fix it for this event entry - //duration = 24 * 60 * 60 * 1000; - Log.debug("new recurring date1 fulldate is " + date); - } - } else { - // if the timezones are the same, correct date if needed - //if (event.start.tz === moment.tz.guess()) { - // if the date hour is less than the offset - if (24 - dh <= Math.abs(dateoffset / 60)) { - // if the rrule byweekday WAS explicitly set , correct it - if (curEvent.rrule.origOptions.byweekday !== undefined) { - // apply the correction to the date/time back to right day - date = new Date(date.getTime() + Math.abs(24 * 60) * 60000); - } - // the duration was calculated way back at the top before we could correct the start time.. - // fix it for this event entry - //duration = 24 * 60 * 60 * 1000; - Log.debug("new recurring date2 fulldate is " + date); - } - //} - } - } else { - // not full day, but luxon can still screw up the date on the rule processing - // we need to correct the date to get back to the right event for - if (dateoffset < 0) { - // if the date hour is less than the offset - if (dh <= Math.abs(dateoffset / 60)) { - // if the rrule byweekday WAS explicitly set , correct it - if (curEvent.rrule.origOptions.byweekday !== undefined) { - // Reduce the time by t: - // Apply the correction to the date/time to get it UTC relative - date = new Date(date.getTime() - Math.abs(24 * 60) * 60000); - } - // the duration was calculated way back at the top before we could correct the start time.. - // fix it for this event entry - //duration = 24 * 60 * 60 * 1000; - Log.debug("new recurring date1 is " + date); - } - } else { - // if the timezones are the same, correct date if needed - //if (event.start.tz === moment.tz.guess()) { - // if the date hour is less than the offset - if (24 - dh <= Math.abs(dateoffset / 60)) { - // if the rrule byweekday WAS explicitly set , correct it - if (curEvent.rrule.origOptions.byweekday !== undefined) { - // apply the correction to the date/time back to right day - date = new Date(date.getTime() + Math.abs(24 * 60) * 60000); - } - // the duration was calculated way back at the top before we could correct the start time.. - // fix it for this event entry - //duration = 24 * 60 * 60 * 1000; - Log.debug("new recurring date2 is " + date); - } - //} - } - } - startDate = moment(date); - Log.debug("Corrected startDate: " + startDate.toDate()); - - let adjustDays = CalendarUtils.calculateTimezoneAdjustment(event, date); - - // For each date that we're checking, it's possible that there is a recurrence override for that one day. - if (curEvent.recurrences !== undefined && curEvent.recurrences[dateKey] !== undefined) { - // We found an override, so for this recurrence, use a potentially different title, start date, and duration. - curEvent = curEvent.recurrences[dateKey]; - startDate = moment(curEvent.start); - duration = parseInt(moment(curEvent.end).format("x")) - parseInt(startDate.format("x")); - } - // If there's no recurrence override, check for an exception date. Exception dates represent exceptions to the rule. - else if (curEvent.exdate !== undefined && curEvent.exdate[dateKey] !== undefined) { - // This date is an exception date, which means we should skip it in the recurrence pattern. - showRecurrence = false; - } - Log.debug("duration: " + duration); - - endDate = moment(parseInt(startDate.format("x")) + duration, "x"); - if (startDate.format("x") === endDate.format("x")) { - endDate = endDate.endOf("day"); - } - - const recurrenceTitle = CalendarUtils.getTitleFromEvent(curEvent); - - // If this recurrence ends before the start of the date range, or starts after the end of the date range, don"t add - // it to the event list. - if (endDate.isBefore(past) || startDate.isAfter(future)) { - showRecurrence = false; - } - - if (CalendarUtils.timeFilterApplies(now, endDate, dateFilter)) { - showRecurrence = false; - } - - if (showRecurrence === true) { - Log.debug("saving event: " + description); - addedEvents++; - newEvents.push({ - title: recurrenceTitle, - startDate: (adjustDays ? (adjustDays > 0 ? startDate.add(adjustDays, "hours") : startDate.subtract(Math.abs(adjustDays), "hours")) : startDate).format("x"), - endDate: (adjustDays ? (adjustDays > 0 ? endDate.add(adjustDays, "hours") : endDate.subtract(Math.abs(adjustDays), "hours")) : endDate).format("x"), - fullDayEvent: CalendarUtils.isFullDayEvent(event), - recurringEvent: true, - class: event.class, - firstYear: event.start.getFullYear(), - location: location, - geo: geo, - description: description - }); - } - } - // End recurring event parsing. - } else { - // Single event. - const fullDayEvent = isFacebookBirthday ? true : CalendarUtils.isFullDayEvent(event); - // Log.debug("full day event") - if (config.includePastEvents) { - // Past event is too far in the past, so skip. - if (endDate < past) { - return; - } + if (currentLine.length > 0) { + temp += `${currentLine}
${word} `; } else { - // It's not a fullday event, and it is in the past, so skip. - if (!fullDayEvent && endDate < new Date()) { - return; - } - - // It's a fullday event, and it is before today, So skip. - if (fullDayEvent && endDate <= today) { - return; - } - } - - // It exceeds the maximumNumberOfDays limit, so skip. - if (startDate > future) { - return; + temp += `${word}
`; } - - if (CalendarUtils.timeFilterApplies(now, endDate, dateFilter)) { - return; - } - - // if the start and end are the same, then make end the 'end of day' value (start is at 00:00:00) - if (fullDayEvent && startDate.format("x") === endDate.format("x")) { - endDate = endDate.endOf("day"); - } - // get correction for date saving and dst change between now and then - let adjustDays = CalendarUtils.calculateTimezoneAdjustment(event, startDate.toDate()); - // Every thing is good. Add it to the list. - newEvents.push({ - title: title, - startDate: (adjustDays ? (adjustDays > 0 ? startDate.add(adjustDays, "hours") : startDate.subtract(Math.abs(adjustDays), "hours")) : startDate).format("x"), - endDate: (adjustDays ? (adjustDays > 0 ? endDate.add(adjustDays, "hours") : endDate.subtract(Math.abs(adjustDays), "hours")) : endDate).format("x"), - fullDayEvent: fullDayEvent, - class: event.class, - location: location, - geo: geo, - description: description - }); + currentLine = ""; } } - }); - - newEvents.sort(function (a, b) { - return a.startDate - b.startDate; - }); - - return newEvents; - }, - /** - * Lookup iana tz from windows - * - * @param {string} msTZName the timezone name to lookup - * @returns {string|null} the iana name or null of none is found - */ - getIanaTZFromMS: function (msTZName) { - // Get hash entry - const he = zoneTable[msTZName]; - // If found return iana name, else null - return he ? he.iana[0] : null; - }, - - /** - * Gets the title from the event. - * - * @param {object} event The event object to check. - * @returns {string} The title of the event, or "Event" if no title is found. - */ - getTitleFromEvent: function (event) { - let title = "Event"; - if (event.summary) { - title = typeof event.summary.val !== "undefined" ? event.summary.val : event.summary; - } else if (event.description) { - title = event.description; - } - - return title; - }, - - /** - * Checks if an event is a fullday event. - * - * @param {object} event The event object to check. - * @returns {boolean} True if the event is a fullday event, false otherwise - */ - isFullDayEvent: function (event) { - if (event.start.length === 8 || event.start.dateOnly || event.datetype === "date") { - return true; - } - - const start = event.start || 0; - const startDate = new Date(start); - const end = event.end || 0; - if ((end - start) % (24 * 60 * 60 * 1000) === 0 && startDate.getHours() === 0 && startDate.getMinutes() === 0) { - // Is 24 hours, and starts on the middle of the night. - return true; + return (temp + currentLine).trim(); + } else { + if (maxLength && typeof maxLength === "number" && string.length > maxLength) { + return `${string.trim().slice(0, maxLength)}…`; + } else { + return string.trim(); + } } - - return false; }, /** - * Determines if the user defined time filter should apply - * - * @param {Date} now Date object using previously created object for consistency - * @param {Moment} endDate Moment object representing the event end date - * @param {string} filter The time to subtract from the end date to determine if an event should be shown - * @returns {boolean} True if the event should be filtered out, false otherwise + * Transforms the title of an event for usage. + * Replaces parts of the text as defined in config.titleReplace. + * @param {string} title The title to transform. + * @param {object} titleReplace object definition of parts to be replaced in the title + * object definition: + * search: {string,required} RegEx in format //x or simple string to be searched. For (birthday) year calcluation, the element matching the year must be in a RegEx group + * replace: {string,required} Replacement string, may contain match group references (latter is required for year calculation) + * yearmatchgroup: {number,optional} match group for year element + * @returns {string} The transformed title. */ - timeFilterApplies: function (now, endDate, filter) { - if (filter) { - const until = filter.split(" "), - value = parseInt(until[0]), - increment = until[1].slice(-1) === "s" ? until[1] : until[1] + "s", // Massage the data for moment js - filterUntil = moment(endDate.format()).subtract(value, increment); - - return now < filterUntil.format("x"); - } - - return false; - }, + titleTransform (title, titleReplace) { + let transformedTitle = title; + for (let tr in titleReplace) { + let transform = titleReplace[tr]; + if (typeof transform === "object") { + if (typeof transform.search !== "undefined" && transform.search !== "" && typeof transform.replace !== "undefined") { + let regParts = transform.search.match(/^\/(.+)\/([gim]*)$/); + let needle = new RegExp(transform.search, "g"); + if (regParts) { + // the parsed pattern is a regexp with flags. + needle = new RegExp(regParts[1], regParts[2]); + } - /** - * Determines if the user defined title filter should apply - * - * @param {string} title the title of the event - * @param {string} filter the string to look for, can be a regex also - * @param {boolean} useRegex true if a regex should be used, otherwise it just looks for the filter as a string - * @param {string} regexFlags flags that should be applied to the regex - * @returns {boolean} True if the title should be filtered out, false otherwise - */ - titleFilterApplies: function (title, filter, useRegex, regexFlags) { - if (useRegex) { - // Assume if leading slash, there is also trailing slash - if (filter[0] === "/") { - // Strip leading and trailing slashes - filter = filter.substr(1).slice(0, -1); + let replacement = transform.replace; + if (typeof transform.yearmatchgroup !== "undefined" && transform.yearmatchgroup !== "") { + const yearmatch = [...title.matchAll(needle)]; + if (yearmatch[0].length >= transform.yearmatchgroup + 1 && yearmatch[0][transform.yearmatchgroup] * 1 >= 1900) { + let calcage = new Date().getFullYear() - yearmatch[0][transform.yearmatchgroup] * 1; + let searchstr = `$${transform.yearmatchgroup}`; + replacement = replacement.replace(searchstr, calcage); + } + } + transformedTitle = transformedTitle.replace(needle, replacement); + } } - - filter = new RegExp(filter, regexFlags); - - return filter.test(title); - } else { - return title.includes(filter); } + return transformedTitle; } }; diff --git a/modules/default/calendar/debug.js b/modules/default/calendar/debug.js index 08cd377006..71ed2f4abd 100644 --- a/modules/default/calendar/debug.js +++ b/modules/default/calendar/debug.js @@ -1,14 +1,11 @@ /* CalendarFetcher Tester * use this script with `node debug.js` to test the fetcher without the need * of starting the MagicMirror² core. Adjust the values below to your desire. - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. */ // Alias modules mentioned in package.js under _moduleAliases. require("module-alias/register"); -const CalendarFetcher = require("./calendarfetcher.js"); +const CalendarFetcher = require("./calendarfetcher"); const url = "https://calendar.google.com/calendar/ical/pkm1t2uedjbp0uvq1o7oj1jouo%40group.calendar.google.com/private-08ba559f89eec70dd74bbd887d0a3598/basic.ics"; // Standard test URL //const url = "https://www.googleapis.com/calendar/v3/calendars/primary/events/"; // URL for Bearer auth (must be configured in Google OAuth2 first) diff --git a/modules/default/calendar/node_helper.js b/modules/default/calendar/node_helper.js index 2121c30925..7901abf099 100644 --- a/modules/default/calendar/node_helper.js +++ b/modules/default/calendar/node_helper.js @@ -1,22 +1,16 @@ -/* MagicMirror² - * Node Helper: Calendar - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. - */ const NodeHelper = require("node_helper"); -const CalendarFetcher = require("./calendarfetcher.js"); const Log = require("logger"); +const CalendarFetcher = require("./calendarfetcher"); module.exports = NodeHelper.create({ // Override start method. - start: function () { - Log.log("Starting node helper for: " + this.name); + start () { + Log.log(`Starting node helper for: ${this.name}`); this.fetchers = []; }, // Override socketNotificationReceived method. - socketNotificationReceived: function (notification, payload) { + socketNotificationReceived (notification, payload) { if (notification === "ADD_CALENDAR") { this.createFetcher(payload.url, payload.fetchInterval, payload.excludedEvents, payload.maximumEntries, payload.maximumNumberOfDays, payload.auth, payload.broadcastPastEvents, payload.selfSignedCert, payload.id); } else if (notification === "FETCH_CALENDAR") { @@ -33,7 +27,6 @@ module.exports = NodeHelper.create({ /** * Creates a fetcher for a new url if it doesn't exist yet. * Otherwise it reuses the existing one. - * * @param {string} url The url of the calendar * @param {number} fetchInterval How often does the calendar needs to be fetched in ms * @param {string[]} excludedEvents An array of words / phrases from event titles that will be excluded from being shown. @@ -44,7 +37,7 @@ module.exports = NodeHelper.create({ * @param {boolean} selfSignedCert If true, the server certificate is not verified against the list of supplied CAs. * @param {string} identifier ID of the module */ - createFetcher: function (url, fetchInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth, broadcastPastEvents, selfSignedCert, identifier) { + createFetcher (url, fetchInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth, broadcastPastEvents, selfSignedCert, identifier) { try { new URL(url); } catch (error) { @@ -54,9 +47,14 @@ module.exports = NodeHelper.create({ } let fetcher; + let fetchIntervalCorrected; if (typeof this.fetchers[identifier + url] === "undefined") { - Log.log("Create new calendarfetcher for url: " + url + " - Interval: " + fetchInterval); - fetcher = new CalendarFetcher(url, fetchInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth, broadcastPastEvents, selfSignedCert); + if (fetchInterval < 60000) { + Log.warn(`fetchInterval for url ${url} must be >= 60000`); + fetchIntervalCorrected = 60000; + } + Log.log(`Create new calendarfetcher for url: ${url} - Interval: ${fetchIntervalCorrected || fetchInterval}`); + fetcher = new CalendarFetcher(url, fetchIntervalCorrected || fetchInterval, excludedEvents, maximumEntries, maximumNumberOfDays, auth, broadcastPastEvents, selfSignedCert); fetcher.onReceive((fetcher) => { this.broadcastEvents(fetcher, identifier); @@ -73,7 +71,7 @@ module.exports = NodeHelper.create({ this.fetchers[identifier + url] = fetcher; } else { - Log.log("Use existing calendarfetcher for url: " + url); + Log.log(`Use existing calendarfetcher for url: ${url}`); fetcher = this.fetchers[identifier + url]; fetcher.broadcastEvents(); } @@ -86,7 +84,7 @@ module.exports = NodeHelper.create({ * @param {object} fetcher the fetcher associated with the calendar * @param {string} identifier the identifier of the calendar */ - broadcastEvents: function (fetcher, identifier) { + broadcastEvents (fetcher, identifier) { this.sendSocketNotification("CALENDAR_EVENTS", { id: identifier, url: fetcher.url(), diff --git a/modules/default/clock/clock.js b/modules/default/clock/clock.js index 7c9310f008..42b066ab58 100644 --- a/modules/default/clock/clock.js +++ b/modules/default/clock/clock.js @@ -1,11 +1,5 @@ -/* global SunCalc */ - -/* MagicMirror² - * Module: Clock - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. - */ +/* global SunCalc, formatTime */ + Module.register("clock", { // Module config defaults. defaults: { @@ -22,6 +16,7 @@ Module.register("clock", { showTime: true, showWeek: false, dateFormat: "dddd, LL", + sendNotifications: false, /* specific to the analog clock */ analogSize: "200px", @@ -31,21 +26,21 @@ Module.register("clock", { secondsColor: "#888888", showSunTimes: false, - showMoonTimes: false, + showMoonTimes: false, // options: false, 'times' (rise/set), 'percent' (lit percent), 'phase' (current phase), or 'both' (percent & phase) lat: 47.630539, lon: -122.344147 }, // Define required scripts. - getScripts: function () { + getScripts () { return ["moment.js", "moment-timezone.js", "suncalc.js"]; }, // Define styles. - getStyles: function () { + getStyles () { return ["clock_styles.css"]; }, // Define start sequence. - start: function () { - Log.info("Starting module: " + this.name); + start () { + Log.info(`Starting module: ${this.name}`); // Schedule update interval. this.second = moment().second(); @@ -66,41 +61,44 @@ Module.register("clock", { const notificationTimer = () => { this.updateDom(); - // If seconds is displayed CLOCK_SECOND-notification should be sent (but not when CLOCK_MINUTE-notification is sent) - if (this.config.displaySeconds) { - this.second = moment().second(); - if (this.second !== 0) { - this.sendNotification("CLOCK_SECOND", this.second); - setTimeout(notificationTimer, delayCalculator(0)); - return; + if (this.config.sendNotifications) { + // If seconds is displayed CLOCK_SECOND-notification should be sent (but not when CLOCK_MINUTE-notification is sent) + if (this.config.displaySeconds) { + this.second = moment().second(); + if (this.second !== 0) { + this.sendNotification("CLOCK_SECOND", this.second); + setTimeout(notificationTimer, delayCalculator(0)); + return; + } } + + // If minute changed or seconds isn't displayed send CLOCK_MINUTE-notification + this.minute = moment().minute(); + this.sendNotification("CLOCK_MINUTE", this.minute); } - // If minute changed or seconds isn't displayed send CLOCK_MINUTE-notification - this.minute = moment().minute(); - this.sendNotification("CLOCK_MINUTE", this.minute); setTimeout(notificationTimer, delayCalculator(0)); }; - // Set the initial timeout with the amount of seconds elapsed as reducedSeconds so it will trigger when the minute changes + // Set the initial timeout with the amount of seconds elapsed as + // reducedSeconds, so it will trigger when the minute changes setTimeout(notificationTimer, delayCalculator(this.second)); // Set locale. moment.locale(config.language); }, // Override dom generator. - getDom: function () { + getDom () { const wrapper = document.createElement("div"); - wrapper.classList.add("clockGrid"); + wrapper.classList.add("clock-grid"); /************************************ * Create wrappers for analog and digital clock */ const analogWrapper = document.createElement("div"); - analogWrapper.className = "clockCircle"; + analogWrapper.className = "clock-circle"; const digitalWrapper = document.createElement("div"); digitalWrapper.className = "digital"; - digitalWrapper.style.gridArea = "center"; /************************************ * Create wrappers for DIGITAL clock @@ -124,7 +122,7 @@ Module.register("clock", { // Set content of wrappers. // The moment().format("h") method has a bug on the Raspberry Pi. // So we need to generate the timestring manually. - // See issue: https://github.com/MichMich/MagicMirror/issues/181 + // See issue: https://github.com/MagicMirrorOrg/MagicMirror/issues/181 let timeString; const now = moment(); if (this.config.timezone) { @@ -137,9 +135,9 @@ Module.register("clock", { } if (this.config.clockBold) { - timeString = now.format(hourSymbol + '[]mm[]'); + timeString = now.format(`${hourSymbol}[]mm[]`); } else { - timeString = now.format(hourSymbol + ":mm"); + timeString = now.format(`${hourSymbol}:mm`); } if (this.config.showDate) { @@ -164,21 +162,6 @@ Module.register("clock", { digitalWrapper.appendChild(timeWrapper); } - /** - * Format the time according to the config - * - * @param {object} config The config of the module - * @param {object} time time to format - * @returns {string} The formatted time string - */ - function formatTime(config, time) { - let formatString = hourSymbol + ":mm"; - if (config.showPeriod && config.timeFormat !== 24) { - formatString += config.showPeriodUpper ? "A" : "a"; - } - return moment(time).format(formatString); - } - /**************************************************************** * Create wrappers for Sun Times, only if specified in config */ @@ -195,19 +178,11 @@ Module.register("clock", { nextEvent = tomorrowSunTimes.sunrise; } const untilNextEvent = moment.duration(moment(nextEvent).diff(now)); - const untilNextEventString = untilNextEvent.hours() + "h " + untilNextEvent.minutes() + "m"; - sunWrapper.innerHTML = - ' ' + - untilNextEventString + - "" + - ' ' + - formatTime(this.config, sunTimes.sunrise) + - "" + - ' ' + - formatTime(this.config, sunTimes.sunset) + - ""; + const untilNextEventString = `${untilNextEvent.hours()}h ${untilNextEvent.minutes()}m`; + sunWrapper.innerHTML + = ` ${untilNextEventString}` + + ` ${formatTime(this.config, sunTimes.sunrise)}` + + ` ${formatTime(this.config, sunTimes.sunset)}`; digitalWrapper.appendChild(sunWrapper); } @@ -226,19 +201,15 @@ Module.register("clock", { moonSet = nextMoonTimes.set; } const isVisible = now.isBetween(moonRise, moonSet) || moonTimes.alwaysUp === true; - const illuminatedFractionString = Math.round(moonIllumination.fraction * 100) + "%"; - moonWrapper.innerHTML = - ' ' + - illuminatedFractionString + - "" + - ' ' + - (moonRise ? formatTime(this.config, moonRise) : "...") + - "" + - ' ' + - (moonSet ? formatTime(this.config, moonSet) : "...") + - ""; + const showFraction = ["both", "percent"].includes(this.config.showMoonTimes); + const showUnicode = ["both", "phase"].includes(this.config.showMoonTimes); + const illuminatedFractionString = `${Math.round(moonIllumination.fraction * 100)}%`; + const image = showUnicode ? [..."🌑🌒🌓🌔🌕🌖🌗🌘"][Math.floor(moonIllumination.phase * 8)] : ""; + + moonWrapper.innerHTML + = `${image} ${showFraction ? illuminatedFractionString : ""}` + + ` ${moonRise ? formatTime(this.config, moonRise) : "..."}` + + ` ${moonSet ? formatTime(this.config, moonSet) : "..."}`; digitalWrapper.appendChild(moonWrapper); } @@ -266,26 +237,26 @@ Module.register("clock", { analogWrapper.style.height = this.config.analogSize; if (this.config.analogFace !== "" && this.config.analogFace !== "simple" && this.config.analogFace !== "none") { - analogWrapper.style.background = "url(" + this.data.path + "faces/" + this.config.analogFace + ".svg)"; + analogWrapper.style.background = `url(${this.data.path}faces/${this.config.analogFace}.svg)`; analogWrapper.style.backgroundSize = "100%"; - // The following line solves issue: https://github.com/MichMich/MagicMirror/issues/611 + // The following line solves issue: https://github.com/MagicMirrorOrg/MagicMirror/issues/611 // analogWrapper.style.border = "1px solid black"; analogWrapper.style.border = "rgba(0, 0, 0, 0.1)"; //Updated fix for Issue 611 where non-black backgrounds are used } else if (this.config.analogFace !== "none") { analogWrapper.style.border = "2px solid white"; } const clockFace = document.createElement("div"); - clockFace.className = "clockFace"; + clockFace.className = "clock-face"; const clockHour = document.createElement("div"); - clockHour.id = "clockHour"; - clockHour.style.transform = "rotate(" + hour + "deg)"; - clockHour.className = "clockHour"; + clockHour.id = "clock-hour"; + clockHour.style.transform = `rotate(${hour}deg)`; + clockHour.className = "clock-hour"; const clockMinute = document.createElement("div"); - clockMinute.id = "clockMinute"; - clockMinute.style.transform = "rotate(" + minute + "deg)"; - clockMinute.className = "clockMinute"; + clockMinute.id = "clock-minute"; + clockMinute.style.transform = `rotate(${minute}deg)`; + clockMinute.className = "clock-minute"; // Combine analog wrappers clockFace.appendChild(clockHour); @@ -293,9 +264,9 @@ Module.register("clock", { if (this.config.displaySeconds) { const clockSecond = document.createElement("div"); - clockSecond.id = "clockSecond"; - clockSecond.style.transform = "rotate(" + second + "deg)"; - clockSecond.className = "clockSecond"; + clockSecond.id = "clock-second"; + clockSecond.style.transform = `rotate(${second}deg)`; + clockSecond.className = "clock-second"; clockSecond.style.backgroundColor = this.config.secondsColor; clockFace.appendChild(clockSecond); } @@ -303,24 +274,29 @@ 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 - if (this.config.analogShowDate === "top") { - wrapper.classList.add("clockGrid--bottom"); - } else if (this.config.analogShowDate === "bottom") { - wrapper.classList.add("clockGrid--top"); - } else { - //analogWrapper.style.gridArea = "center"; + if (this.config.showDate) { + // Add date to the analog clock + dateWrapper.innerHTML = now.format(this.config.dateFormat); + wrapper.appendChild(dateWrapper); } + if (this.config.analogShowDate === "bottom") { + wrapper.classList.add("clock-grid-bottom"); + } else if (this.config.analogShowDate === "top") { + wrapper.classList.add("clock-grid-top"); + } + wrapper.appendChild(analogWrapper); + } else if (this.config.displayType === "digital") { + wrapper.appendChild(digitalWrapper); } else if (this.config.displayType === "both") { - wrapper.classList.add("clockGrid--" + this.config.analogPlacement); + wrapper.classList.add(`clock-grid-${this.config.analogPlacement}`); + wrapper.appendChild(analogWrapper); + wrapper.appendChild(digitalWrapper); } - wrapper.appendChild(analogWrapper); - wrapper.appendChild(digitalWrapper); - // Return the wrapper to the dom. return wrapper; } diff --git a/modules/default/clock/clock_styles.css b/modules/default/clock/clock_styles.css index e3eb7e94cc..e938dd2e8e 100644 --- a/modules/default/clock/clock_styles.css +++ b/modules/default/clock/clock_styles.css @@ -1,37 +1,37 @@ -.clockGrid { +.clock-grid { display: inline-flex; gap: 15px; } -.clockGrid--left { +.clock-grid-left { flex-direction: row; } -.clockGrid--right { +.clock-grid-right { flex-direction: row-reverse; } -.clockGrid--top { +.clock-grid-top { flex-direction: column; } -.clockGrid--bottom { +.clock-grid-bottom { flex-direction: column-reverse; } -.clockCircle { +.clock-circle { place-self: center; position: relative; border-radius: 50%; background-size: 100%; } -.clockFace { +.clock-face { width: 100%; height: 100%; } -.clockFace::after { +.clock-face::after { position: absolute; top: 50%; left: 50%; @@ -44,7 +44,7 @@ display: block; } -.clockHour { +.clock-hour { width: 0; height: 0; position: absolute; @@ -57,7 +57,7 @@ border-radius: 3px 0 0 3px; } -.clockMinute { +.clock-minute { width: 0; height: 0; position: absolute; @@ -70,7 +70,7 @@ border-radius: 3px 0 0 3px; } -.clockSecond { +.clock-second { width: 0; height: 0; position: absolute; diff --git a/modules/default/compliments/compliments.js b/modules/default/compliments/compliments.js index 23c1a6831e..39e6c34d49 100644 --- a/modules/default/compliments/compliments.js +++ b/modules/default/compliments/compliments.js @@ -1,9 +1,3 @@ -/* MagicMirror² - * Module: Compliments - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. - */ Module.register("compliments", { // Module config defaults. defaults: { @@ -28,21 +22,20 @@ Module.register("compliments", { currentWeatherType: "", // Define required scripts. - getScripts: function () { + getScripts () { return ["moment.js"]; }, // Define start sequence. - start: function () { - Log.info("Starting module: " + this.name); + async start () { + Log.info(`Starting module: ${this.name}`); this.lastComplimentIndex = -1; if (this.config.remoteFile !== null) { - this.complimentFile((response) => { - this.config.compliments = JSON.parse(response); - this.updateDom(); - }); + const response = await this.loadComplimentFile(); + this.config.compliments = JSON.parse(response); + this.updateDom(); } // Schedule update timer. @@ -53,12 +46,11 @@ Module.register("compliments", { /** * Generate a random index for a list of compliments. - * * @param {string[]} compliments Array with compliments. * @returns {number} a random index of given array */ - randomIndex: function (compliments) { - if (compliments.length === 1) { + randomIndex (compliments) { + if (compliments.length <= 1) { return 0; } @@ -79,35 +71,34 @@ Module.register("compliments", { /** * Retrieve an array of compliments for the time of the day. - * * @returns {string[]} array with compliments for the time of the day. */ - complimentArray: function () { + complimentArray () { const hour = moment().hour(); const date = moment().format("YYYY-MM-DD"); - let compliments; + 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]); } } @@ -116,29 +107,20 @@ 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); + async loadComplimentFile () { + 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(); }, /** * Retrieve a random compliment. - * * @returns {string} a compliment */ - randomCompliment: function () { + getRandomCompliment () { // get the current time of day compliments list const compliments = this.complimentArray(); // variable for index to next message to display @@ -157,38 +139,37 @@ Module.register("compliments", { }, // Override dom generator. - getDom: function () { + getDom () { 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) { + notificationReceived (notification, payload, sender) { if (notification === "CURRENTWEATHER_TYPE") { - this.setCurrentWeatherType(payload.type); + this.currentWeatherType = payload.type; } } }); diff --git a/modules/default/defaultmodules.js b/modules/default/defaultmodules.js index c74e94a45c..e28413ff7b 100644 --- a/modules/default/defaultmodules.js +++ b/modules/default/defaultmodules.js @@ -1,8 +1,5 @@ -/* MagicMirror² Default Modules List +/* Default Modules List * Modules listed below can be loaded without the 'default/' prefix. Omitting the default folder name. - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. */ const defaultModules = ["alert", "calendar", "clock", "compliments", "helloworld", "newsfeed", "updatenotification", "weather"]; diff --git a/modules/default/helloworld/helloworld.js b/modules/default/helloworld/helloworld.js index 53357d0fd2..53fbd80c03 100644 --- a/modules/default/helloworld/helloworld.js +++ b/modules/default/helloworld/helloworld.js @@ -1,20 +1,14 @@ -/* MagicMirror² - * Module: HelloWorld - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. - */ Module.register("helloworld", { // Default module config. defaults: { text: "Hello World!" }, - getTemplate: function () { + getTemplate () { return "helloworld.njk"; }, - getTemplateData: function () { + getTemplateData () { return this.config; } }); diff --git a/modules/default/helloworld/helloworld.njk b/modules/default/helloworld/helloworld.njk index 005ca28e3f..05e5edd37f 100644 --- a/modules/default/helloworld/helloworld.njk +++ b/modules/default/helloworld/helloworld.njk @@ -2,4 +2,4 @@ Use ` | safe` to allow html tages within the text string. https://mozilla.github.io/nunjucks/templating.html#autoescaping --> -
{{text | safe}}
+
{{ text | safe }}
diff --git a/modules/default/newsfeed/fullarticle.njk b/modules/default/newsfeed/fullarticle.njk index 6570396e5e..0be4b04256 100644 --- a/modules/default/newsfeed/fullarticle.njk +++ b/modules/default/newsfeed/fullarticle.njk @@ -1,3 +1,3 @@
-
\ No newline at end of file +
diff --git a/modules/default/newsfeed/newsfeed.css b/modules/default/newsfeed/newsfeed.css index ea65eca294..2c690a48e2 100644 --- a/modules/default/newsfeed/newsfeed.css +++ b/modules/default/newsfeed/newsfeed.css @@ -1,5 +1,6 @@ iframe.newsfeed-fullarticle { width: 100vw; + /* very large height value to allow scrolling */ height: 3000px; top: 0; diff --git a/modules/default/newsfeed/newsfeed.js b/modules/default/newsfeed/newsfeed.js index 6b3bba7d29..c66f8990d8 100644 --- a/modules/default/newsfeed/newsfeed.js +++ b/modules/default/newsfeed/newsfeed.js @@ -1,9 +1,3 @@ -/* MagicMirror² - * Module: NewsFeed - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. - */ Module.register("newsfeed", { // Default module config. defaults: { @@ -42,26 +36,26 @@ Module.register("newsfeed", { dangerouslyDisableAutoEscaping: false }, - getUrlPrefix: function (item) { + getUrlPrefix (item) { if (item.useCorsProxy) { - return location.protocol + "//" + location.host + "/cors?url="; + return `${location.protocol}//${location.host}/cors?url=`; } else { return ""; } }, // Define required scripts. - getScripts: function () { + getScripts () { return ["moment.js"]; }, //Define required styles. - getStyles: function () { + getStyles () { return ["newsfeed.css"]; }, // Define required translations. - getTranslations: function () { + getTranslations () { // The translations for the default modules are defined in the core translation files. // Therefor we can just return false. Otherwise we should have returned a dictionary. // If you're trying to build your own module including translations, check out the documentation. @@ -69,8 +63,8 @@ Module.register("newsfeed", { }, // Define start sequence. - start: function () { - Log.info("Starting module: " + this.name); + start () { + Log.info(`Starting module: ${this.name}`); // Set locale. moment.locale(config.language); @@ -87,7 +81,7 @@ Module.register("newsfeed", { }, // Override socket notification handler. - socketNotificationReceived: function (notification, payload) { + socketNotificationReceived (notification, payload) { if (notification === "NEWS_ITEMS") { this.generateFeed(payload); @@ -107,7 +101,7 @@ Module.register("newsfeed", { }, //Override fetching of template name - getTemplate: function () { + getTemplate () { if (this.config.feedUrl) { return "oldconfig.njk"; } else if (this.config.showFullArticle) { @@ -117,28 +111,34 @@ Module.register("newsfeed", { }, //Override template data and return whats used for the current template - getTemplateData: function () { + getTemplateData () { + if (this.activeItem >= this.newsItems.length) { + this.activeItem = 0; + } + this.activeItemCount = this.newsItems.length; // this.config.showFullArticle is a run-time configuration, triggered by optional notifications if (this.config.showFullArticle) { + this.activeItemHash = this.newsItems[this.activeItem]?.hash; return { url: this.getActiveItemURL() }; } if (this.error) { + this.activeItemHash = undefined; return { error: this.error }; } if (this.newsItems.length === 0) { + this.activeItemHash = undefined; return { empty: true }; } - if (this.activeItem >= this.newsItems.length) { - this.activeItem = 0; - } const item = this.newsItems[this.activeItem]; + this.activeItemHash = item.hash; + const items = this.newsItems.map(function (item) { item.publishDate = moment(new Date(item.pubdate)).fromNow(); return item; @@ -150,13 +150,13 @@ Module.register("newsfeed", { sourceTitle: item.sourceTitle, publishDate: moment(new Date(item.pubdate)).fromNow(), title: item.title, - url: this.getUrlPrefix(item) + item.url, + url: this.getActiveItemURL(), description: item.description, items: items }; }, - getActiveItemURL: function () { + getActiveItemURL () { const item = this.newsItems[this.activeItem]; if (item) { return typeof item.url === "string" ? this.getUrlPrefix(item) + item.url : this.getUrlPrefix(item) + item.url.href; @@ -168,7 +168,7 @@ Module.register("newsfeed", { /** * Registers the feeds to be used by the backend. */ - registerFeeds: function () { + registerFeeds () { for (let feed of this.config.feeds) { this.sendSocketNotification("ADD_FEED", { feed: feed, @@ -179,10 +179,9 @@ Module.register("newsfeed", { /** * Generate an ordered list of items for this configured module. - * * @param {object} feeds An object with feeds returned by the node helper. */ - generateFeed: function (feeds) { + generateFeed (feeds) { let newsItems = []; for (let feed in feeds) { const feedItems = feeds[feed]; @@ -272,11 +271,10 @@ Module.register("newsfeed", { /** * Check if this module is configured to show this feed. - * * @param {string} feedUrl Url of the feed to check. * @returns {boolean} True if it is subscribed, false otherwise */ - subscribedToFeed: function (feedUrl) { + subscribedToFeed (feedUrl) { for (let feed of this.config.feeds) { if (feed.url === feedUrl) { return true; @@ -287,11 +285,10 @@ Module.register("newsfeed", { /** * Returns title for the specific feed url. - * * @param {string} feedUrl Url of the feed * @returns {string} The title of the feed */ - titleForFeed: function (feedUrl) { + titleForFeed (feedUrl) { for (let feed of this.config.feeds) { if (feed.url === feedUrl) { return feed.title || ""; @@ -303,7 +300,7 @@ Module.register("newsfeed", { /** * Schedule visual update. */ - scheduleUpdateInterval: function () { + scheduleUpdateInterval () { this.updateDom(this.config.animationSpeed); // Broadcast NewsFeed if needed @@ -315,8 +312,27 @@ Module.register("newsfeed", { if (this.timer) clearInterval(this.timer); this.timer = setInterval(() => { - this.activeItem++; - this.updateDom(this.config.animationSpeed); + + /* + * When animations are enabled, don't update the DOM unless we are actually changing what we are displaying. + * (Animating from a headline to itself is unsightly.) + * Cases: + * + * Number of items | Number of items | Display + * at last update | right now | Behaviour + * ---------------------------------------------------- + * 0 | 0 | do not update + * 0 | >0 | update + * 1 | 0 or >1 | update + * 1 | 1 | update only if item details (hash value) changed + * >1 | any | update + * + * (N.B. We set activeItemCount and activeItemHash in getTemplateData().) + */ + if (this.newsItems.length > 1 || this.newsItems.length !== this.activeItemCount || this.activeItemHash !== this.newsItems[0]?.hash) { + this.activeItem++; // this is OK if newsItems.Length==1; getTemplateData will wrap it around + this.updateDom(this.config.animationSpeed); + } // Broadcast NewsFeed if needed if (this.config.broadcastNewsFeeds) { @@ -325,7 +341,7 @@ Module.register("newsfeed", { }, this.config.updateInterval); }, - resetDescrOrFullArticleAndTimer: function () { + resetDescrOrFullArticleAndTimer () { this.isShowingDescription = this.config.showDescription; this.config.showFullArticle = false; this.scrollPosition = 0; @@ -336,7 +352,7 @@ Module.register("newsfeed", { } }, - notificationReceived: function (notification, payload, sender) { + notificationReceived (notification, payload, sender) { const before = this.activeItem; if (notification === "MODULE_DOM_CREATED" && this.config.hideLoading) { this.hide(); @@ -346,7 +362,7 @@ Module.register("newsfeed", { this.activeItem = 0; } this.resetDescrOrFullArticleAndTimer(); - Log.debug(this.name + " - going from article #" + before + " to #" + this.activeItem + " (of " + this.newsItems.length + ")"); + Log.debug(`${this.name} - going from article #${before} to #${this.activeItem} (of ${this.newsItems.length})`); this.updateDom(100); } else if (notification === "ARTICLE_PREVIOUS") { this.activeItem--; @@ -354,7 +370,7 @@ Module.register("newsfeed", { this.activeItem = this.newsItems.length - 1; } this.resetDescrOrFullArticleAndTimer(); - Log.debug(this.name + " - going from article #" + before + " to #" + this.activeItem + " (of " + this.newsItems.length + ")"); + Log.debug(`${this.name} - going from article #${before} to #${this.activeItem} (of ${this.newsItems.length})`); this.updateDom(100); } // if "more details" is received the first time: show article summary, on second time show full article @@ -363,8 +379,8 @@ Module.register("newsfeed", { if (this.config.showFullArticle === true) { this.scrollPosition += this.config.scrollLength; window.scrollTo(0, this.scrollPosition); - Log.debug(this.name + " - scrolling down"); - Log.debug(this.name + " - ARTICLE_MORE_DETAILS, scroll position: " + this.config.scrollLength); + Log.debug(`${this.name} - scrolling down`); + Log.debug(`${this.name} - ARTICLE_MORE_DETAILS, scroll position: ${this.config.scrollLength}`); } else { this.showFullArticle(); } @@ -372,12 +388,12 @@ Module.register("newsfeed", { if (this.config.showFullArticle === true) { this.scrollPosition -= this.config.scrollLength; window.scrollTo(0, this.scrollPosition); - Log.debug(this.name + " - scrolling up"); - Log.debug(this.name + " - ARTICLE_SCROLL_UP, scroll position: " + this.config.scrollLength); + Log.debug(`${this.name} - scrolling up`); + Log.debug(`${this.name} - ARTICLE_SCROLL_UP, scroll position: ${this.config.scrollLength}`); } } else if (notification === "ARTICLE_LESS_DETAILS") { this.resetDescrOrFullArticleAndTimer(); - Log.debug(this.name + " - showing only article titles again"); + Log.debug(`${this.name} - showing only article titles again`); this.updateDom(100); } else if (notification === "ARTICLE_TOGGLE_FULL") { if (this.config.showFullArticle) { @@ -397,7 +413,7 @@ Module.register("newsfeed", { } }, - showFullArticle: function () { + showFullArticle () { this.isShowingDescription = !this.isShowingDescription; this.config.showFullArticle = !this.isShowingDescription; // make bottom bar align to top to allow scrolling @@ -406,7 +422,7 @@ Module.register("newsfeed", { } clearInterval(this.timer); this.timer = null; - Log.debug(this.name + " - showing " + this.isShowingDescription ? "article description" : "full article"); + Log.debug(`${this.name} - showing ${this.isShowingDescription ? "article description" : "full article"}`); this.updateDom(100); } }); diff --git a/modules/default/newsfeed/newsfeed.njk b/modules/default/newsfeed/newsfeed.njk index 9e7e9d78bb..5bdfe2cd49 100644 --- a/modules/default/newsfeed/newsfeed.njk +++ b/modules/default/newsfeed/newsfeed.njk @@ -1,27 +1,31 @@ {% macro escapeText(text, dangerouslyDisableAutoEscaping=false) %} - {% if dangerouslyDisableAutoEscaping %} - {{ text | safe}} - {% else %} - {{ text }} - {% endif %} + {% if dangerouslyDisableAutoEscaping -%} + {{ text | safe }} + {%- else -%} + {{ text }} + {%- endif %} {% endmacro %} - {% macro escapeTitle(title, url, dangerouslyDisableAutoEscaping=false, showTitleAsUrl=false) %} - {% if dangerouslyDisableAutoEscaping %} - {% if showTitleAsUrl %} - {{ title | safe }} + {% if dangerouslyDisableAutoEscaping %} + {% if showTitleAsUrl %} + {{ title | safe }} + {% else %} + {{ title | safe }} + {% endif %} {% else %} - {{ title | safe}} + {% if showTitleAsUrl %} + {{ title }} + {% else %} + {{ title }} + {% endif %} {% endif %} - {% else %} - {% if showTitleAsUrl %} - {{ title }} - {% else %} - {{ title }} - {% endif %} - {% endif %} {% endmacro %} - {% if loaded %} {% if config.showAsList %}
    @@ -30,11 +34,9 @@ {% if (config.showSourceTitle and item.sourceTitle) or config.showPublishDate %}
    {% if item.sourceTitle and config.showSourceTitle %} - {{ item.sourceTitle }}{% if config.showPublishDate %}, {% else %}: {% endif %} - {% endif %} - {% if config.showPublishDate %} - {{ item.publishDate }}: + {{ item.sourceTitle }}{% if config.showPublishDate %}, {% else %}:{% endif %} {% endif %} + {% if config.showPublishDate %}{{ item.publishDate }}:{% endif %}
    {% endif %}
    @@ -43,7 +45,7 @@ {% if config.showDescription %}
    {% if config.truncDescription %} - {{ escapeText(item.description | truncate(config.lengthDescription), config.dangerouslyDisableAutoEscaping) }} + {{ escapeText(item.description | truncate(config.lengthDescription) , config.dangerouslyDisableAutoEscaping) }} {% else %} {{ escapeText(item.description, config.dangerouslyDisableAutoEscaping) }} {% endif %} @@ -57,11 +59,9 @@ {% if (config.showSourceTitle and sourceTitle) or config.showPublishDate %}
    {% if sourceTitle and config.showSourceTitle %} - {{ escapeText(sourceTitle, config.dangerouslyDisableAutoEscaping) }}{% if config.showPublishDate %}, {% else %}: {% endif %} - {% endif %} - {% if config.showPublishDate %} - {{ publishDate }}: + {{ escapeText(sourceTitle, config.dangerouslyDisableAutoEscaping) }}{% if config.showPublishDate %}, {% else %}:{% endif %} {% endif %} + {% if config.showPublishDate %}{{ publishDate }}:{% endif %}
    {% endif %}
    @@ -70,7 +70,7 @@ {% if config.showDescription %}
    {% if config.truncDescription %} - {{ escapeText(description | truncate(config.lengthDescription), config.dangerouslyDisableAutoEscaping) }} + {{ escapeText(description | truncate(config.lengthDescription) , config.dangerouslyDisableAutoEscaping) }} {% else %} {{ escapeText(description, config.dangerouslyDisableAutoEscaping) }} {% endif %} @@ -79,15 +79,11 @@
    {% endif %} {% elseif empty %} -
    - {{ "NEWSFEED_NO_ITEMS" | translate | safe }} -
    +
    {{ "NEWSFEED_NO_ITEMS" | translate | safe }}
    {% elseif error %}
    {{ "MODULE_CONFIG_ERROR" | translate({MODULE_NAME: "Newsfeed", ERROR: error}) | safe }}
    {% else %} -
    - {{ "LOADING" | translate | safe }} -
    +
    {{ "LOADING" | translate | safe }}
    {% endif %} diff --git a/modules/default/newsfeed/newsfeedfetcher.js b/modules/default/newsfeed/newsfeedfetcher.js index be979b9311..ea181b60b4 100644 --- a/modules/default/newsfeed/newsfeedfetcher.js +++ b/modules/default/newsfeed/newsfeedfetcher.js @@ -1,19 +1,13 @@ -/* MagicMirror² - * Node Helper: Newsfeed - NewsfeedFetcher - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. - */ -const Log = require("logger"); +const crypto = require("node:crypto"); +const stream = require("node:stream"); const FeedMe = require("feedme"); -const NodeHelper = require("node_helper"); -const fetch = require("fetch"); const iconv = require("iconv-lite"); -const stream = require("stream"); +const { htmlToText } = require("html-to-text"); +const Log = require("logger"); +const NodeHelper = require("node_helper"); /** * Responsible for requesting an update on the set interval and broadcasting the data. - * * @param {string} url URL of the news feed. * @param {number} reloadInterval Reload interval in milliseconds. * @param {string} encoding Encoding of the feed. @@ -24,12 +18,13 @@ const stream = require("stream"); const NewsfeedFetcher = function (url, reloadInterval, encoding, logFeedWarnings, useCorsProxy) { let reloadTimer = null; let items = []; + let reloadIntervalMS = reloadInterval; let fetchFailedCallback = function () {}; let itemsReceivedCallback = function () {}; - if (reloadInterval < 1000) { - reloadInterval = 1000; + if (reloadIntervalMS < 1000) { + reloadIntervalMS = 1000; } /* private methods */ @@ -47,32 +42,39 @@ const NewsfeedFetcher = function (url, reloadInterval, encoding, logFeedWarnings parser.on("item", (item) => { const title = item.title; let description = item.description || item.summary || item.content || ""; - const pubdate = item.pubdate || item.published || item.updated || item["dc:date"]; + const pubdate = item.pubdate || item.published || item.updated || item["dc:date"] || item["a10:updated"]; const url = item.url || item.link || ""; if (title && pubdate) { - const regex = /(<([^>]+)>)/gi; - description = description.toString().replace(regex, ""); + // Convert HTML entities, codes and tag + description = htmlToText(description, { + wordwrap: false, + selectors: [ + { selector: "a", options: { ignoreHref: true, noAnchorUrl: true } }, + { selector: "br", format: "inlineSurround", options: { prefix: " " } }, + { selector: "img", format: "skip" } + ] + }); items.push({ title: title, description: description, pubdate: pubdate, url: url, - useCorsProxy: useCorsProxy + useCorsProxy: useCorsProxy, + hash: crypto.createHash("sha256").update(`${pubdate} :: ${title} :: ${url}`).digest("hex") }); } else if (logFeedWarnings) { Log.warn("Can't parse feed item:"); Log.warn(item); - Log.warn("Title: " + title); - Log.warn("Description: " + description); - Log.warn("Pubdate: " + pubdate); + Log.warn(`Title: ${title}`); + Log.warn(`Description: ${description}`); + Log.warn(`Pubdate: ${pubdate}`); } }); parser.on("end", () => { this.broadcastItems(); - scheduleTimer(); }); parser.on("error", (error) => { @@ -80,22 +82,27 @@ const NewsfeedFetcher = function (url, reloadInterval, encoding, logFeedWarnings scheduleTimer(); }); + //"end" event is not broadcast if the feed is empty but "finish" is used for both + parser.on("finish", () => { + scheduleTimer(); + }); + parser.on("ttl", (minutes) => { try { // 86400000 = 24 hours is mentioned in the docs as maximum value: const ttlms = Math.min(minutes * 60 * 1000, 86400000); - if (ttlms > reloadInterval) { - reloadInterval = ttlms; - Log.info("Newsfeed-Fetcher: reloadInterval set to ttl=" + reloadInterval + " for url " + url); + if (ttlms > reloadIntervalMS) { + reloadIntervalMS = ttlms; + Log.info(`Newsfeed-Fetcher: reloadInterval set to ttl=${reloadIntervalMS} for url ${url}`); } } catch (error) { - Log.warn("Newsfeed-Fetcher: feed ttl is no valid integer=" + minutes + " for url " + url); + Log.warn(`Newsfeed-Fetcher: feed ttl is no valid integer=${minutes} for url ${url}`); } }); const nodeVersion = Number(process.version.match(/^v(\d+\.\d+)/)[1]); const headers = { - "User-Agent": "Mozilla/5.0 (Node.js " + nodeVersion + ") MagicMirror/" + global.version, + "User-Agent": `Mozilla/5.0 (Node.js ${nodeVersion}) MagicMirror/${global.version}`, "Cache-Control": "max-age=0, no-cache, no-store, must-revalidate", Pragma: "no-cache" }; @@ -124,19 +131,18 @@ const NewsfeedFetcher = function (url, reloadInterval, encoding, logFeedWarnings clearTimeout(reloadTimer); reloadTimer = setTimeout(function () { fetchNews(); - }, reloadInterval); + }, reloadIntervalMS); }; /* public methods */ /** * Update the reload interval, but only if we need to increase the speed. - * * @param {number} interval Interval for the update in milliseconds. */ this.setReloadInterval = function (interval) { - if (interval > 1000 && interval < reloadInterval) { - reloadInterval = interval; + if (interval > 1000 && interval < reloadIntervalMS) { + reloadIntervalMS = interval; } }; @@ -155,7 +161,7 @@ const NewsfeedFetcher = function (url, reloadInterval, encoding, logFeedWarnings Log.info("Newsfeed-Fetcher: No items to broadcast yet."); return; } - Log.info("Newsfeed-Fetcher: Broadcasting " + items.length + " items."); + Log.info(`Newsfeed-Fetcher: Broadcasting ${items.length} items.`); itemsReceivedCallback(this); }; diff --git a/modules/default/newsfeed/node_helper.js b/modules/default/newsfeed/node_helper.js index 13b0f94aa2..c8cdaa0c37 100644 --- a/modules/default/newsfeed/node_helper.js +++ b/modules/default/newsfeed/node_helper.js @@ -1,23 +1,16 @@ -/* MagicMirror² - * Node Helper: Newsfeed - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. - */ - const NodeHelper = require("node_helper"); -const NewsfeedFetcher = require("./newsfeedfetcher.js"); const Log = require("logger"); +const NewsfeedFetcher = require("./newsfeedfetcher"); module.exports = NodeHelper.create({ // Override start method. - start: function () { - Log.log("Starting node helper for: " + this.name); + start () { + Log.log(`Starting node helper for: ${this.name}`); this.fetchers = []; }, // Override socketNotificationReceived received. - socketNotificationReceived: function (notification, payload) { + socketNotificationReceived (notification, payload) { if (notification === "ADD_FEED") { this.createFetcher(payload.feed, payload.config); } @@ -26,11 +19,10 @@ module.exports = NodeHelper.create({ /** * Creates a fetcher for a new feed if it doesn't exist yet. * Otherwise it reuses the existing one. - * * @param {object} feed The feed object * @param {object} config The configuration object */ - createFetcher: function (feed, config) { + createFetcher (feed, config) { const url = feed.url || ""; const encoding = feed.encoding || "UTF-8"; const reloadInterval = feed.reloadInterval || config.reloadInterval || 5 * 60 * 1000; @@ -47,7 +39,7 @@ module.exports = NodeHelper.create({ let fetcher; if (typeof this.fetchers[url] === "undefined") { - Log.log("Create new newsfetcher for url: " + url + " - Interval: " + reloadInterval); + Log.log(`Create new newsfetcher for url: ${url} - Interval: ${reloadInterval}`); fetcher = new NewsfeedFetcher(url, reloadInterval, encoding, config.logFeedWarnings, useCorsProxy); fetcher.onReceive(() => { @@ -64,7 +56,7 @@ module.exports = NodeHelper.create({ this.fetchers[url] = fetcher; } else { - Log.log("Use existing newsfetcher for url: " + url); + Log.log(`Use existing newsfetcher for url: ${url}`); fetcher = this.fetchers[url]; fetcher.setReloadInterval(reloadInterval); fetcher.broadcastItems(); @@ -77,7 +69,7 @@ module.exports = NodeHelper.create({ * Creates an object with all feed items of the different registered feeds, * and broadcasts these using sendSocketNotification. */ - broadcastFeeds: function () { + broadcastFeeds () { const feeds = {}; for (let f in this.fetchers) { feeds[f] = this.fetchers[f].items(); diff --git a/modules/default/newsfeed/oldconfig.njk b/modules/default/newsfeed/oldconfig.njk index db0f8d4b63..0e3b9b5d5a 100644 --- a/modules/default/newsfeed/oldconfig.njk +++ b/modules/default/newsfeed/oldconfig.njk @@ -1,3 +1,3 @@
    {{ "MODULE_CONFIG_CHANGED" | translate({MODULE_NAME: "Newsfeed"}) | safe }} -
    \ No newline at end of file +
    diff --git a/modules/default/updatenotification/git_helper.js b/modules/default/updatenotification/git_helper.js index 80cb75320a..4fb8c18928 100644 --- a/modules/default/updatenotification/git_helper.js +++ b/modules/default/updatenotification/git_helper.js @@ -1,27 +1,28 @@ -const util = require("util"); -const exec = util.promisify(require("child_process").exec); -const fs = require("fs"); -const path = require("path"); +const util = require("node:util"); +const exec = util.promisify(require("node:child_process").exec); +const fs = require("node:fs"); +const path = require("node:path"); const Log = require("logger"); const BASE_DIR = path.normalize(`${__dirname}/../../../`); class GitHelper { - constructor() { + constructor () { this.gitRepos = []; + this.gitResultList = []; } - getRefRegex(branch) { + getRefRegex (branch) { return new RegExp(`s*([a-z,0-9]+[.][.][a-z,0-9]+) ${branch}`, "g"); } - async execShell(command) { + async execShell (command) { const { stdout = "", stderr = "" } = await exec(command); return { stdout, stderr }; } - async isGitRepo(moduleFolder) { + async isGitRepo (moduleFolder) { const { stderr } = await this.execShell(`cd ${moduleFolder} && git remote -v`); if (stderr) { @@ -33,10 +34,10 @@ class GitHelper { return true; } - async add(moduleName) { + async add (moduleName) { let moduleFolder = BASE_DIR; - if (moduleName !== "default") { + if (moduleName !== "MagicMirror") { moduleFolder = `${moduleFolder}modules/${moduleName}`; } @@ -58,7 +59,7 @@ class GitHelper { } } - async getStatusInfo(repo) { + async getStatusInfo (repo) { let gitInfo = { module: repo.module, behind: 0, // commits behind @@ -68,7 +69,7 @@ class GitHelper { isBehindInStatus: false }; - if (repo.module === "default") { + if (repo.module === "MagicMirror") { // the hash is only needed for the mm repo const { stderr, stdout } = await this.execShell(`cd ${repo.folder} && git rev-parse HEAD`); @@ -93,74 +94,119 @@ class GitHelper { // ## develop...origin/develop // ## master...origin/master [behind 8] // ## master...origin/master [ahead 8, behind 1] + // ## HEAD (no branch) status = status.match(/## (.*)\.\.\.([^ ]*)(?: .*behind (\d+))?/); // examples for status: // [ '## 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[3]) { - // git fetch was already called before so `git status -sb` delivers already the behind number - gitInfo.behind = parseInt(status[3]); - gitInfo.isBehindInStatus = true; + if (status) { + gitInfo.current = status[1]; + gitInfo.tracking = status[2]; + + if (status[3]) { + // git fetch was already called before so `git status -sb` delivers already the behind number + gitInfo.behind = parseInt(status[3]); + gitInfo.isBehindInStatus = true; + } } return gitInfo; } - async getRepoInfo(repo) { + async getRepoInfo (repo) { const gitInfo = await this.getStatusInfo(repo); - if (!gitInfo) { + if (!gitInfo || !gitInfo.current) { return; } - if (gitInfo.isBehindInStatus) { + if (gitInfo.isBehindInStatus && (gitInfo.module !== "MagicMirror" || gitInfo.current !== "master")) { return gitInfo; } - const { stderr } = await this.execShell(`cd ${repo.folder} && git fetch --dry-run`); + const { stderr } = await this.execShell(`cd ${repo.folder} && git fetch -n --dry-run`); // example output: - // From https://github.com/MichMich/MagicMirror + // From https://github.com/MagicMirrorOrg/MagicMirror // e40ddd4..06389e3 develop -> origin/develop // here the result is in stderr (this is a git default, don't ask why ...) const matches = stderr.match(this.getRefRegex(gitInfo.current)); - if (!matches || !matches[0]) { - // no refs found, nothing to do - return; + // this is the default if there was no match from "git fetch -n --dry-run". + // Its a fallback because if there was a real "git fetch", the above "git fetch -n --dry-run" would deliver nothing. + let refDiff = `${gitInfo.current}..origin/${gitInfo.current}`; + if (matches && matches[0]) { + refDiff = matches[0]; } // get behind with refs try { - const { stdout } = await this.execShell(`cd ${repo.folder} && git rev-list --ancestry-path --count ${matches[0]}`); + const { stdout } = await this.execShell(`cd ${repo.folder} && git rev-list --ancestry-path --count ${refDiff}`); gitInfo.behind = parseInt(stdout); + // for MagicMirror-Repo and "master" branch avoid getting notified when no tag is in refDiff + // so only releases are reported and we can change e.g. the README.md without sending notifications + if (gitInfo.behind > 0 && gitInfo.module === "MagicMirror" && gitInfo.current === "master") { + let tagList = ""; + try { + const { stdout } = await this.execShell(`cd ${repo.folder} && git ls-remote -q --tags --refs`); + tagList = stdout.trim(); + } catch (err) { + Log.error(`Failed to get tag list for ${repo.module}: ${err}`); + } + // check if tag is between commits and only report behind > 0 if so + try { + const { stdout } = await this.execShell(`cd ${repo.folder} && git rev-list --ancestry-path ${refDiff}`); + let cnt = 0; + for (const ref of stdout.trim().split("\n")) { + if (tagList.includes(ref)) cnt++; // tag found + } + if (cnt === 0) gitInfo.behind = 0; + } catch (err) { + Log.error(`Failed to get git revisions for ${repo.module}: ${err}`); + } + } + return gitInfo; } catch (err) { Log.error(`Failed to get git revisions for ${repo.module}: ${err}`); } } - async getRepos() { - const gitResultList = []; + async getRepos () { + this.gitResultList = []; for (const repo of this.gitRepos) { try { const gitInfo = await this.getRepoInfo(repo); if (gitInfo) { - gitResultList.push(gitInfo); + this.gitResultList.push(gitInfo); } } catch (e) { Log.error(`Failed to retrieve repo info for ${repo.module}: ${e}`); } } - return gitResultList; + return this.gitResultList; + } + + async checkUpdates () { + var updates = []; + + const allRepos = await this.gitResultList.map((module) => { + return new Promise((resolve) => { + if (module.behind > 0 && module.module !== "MagicMirror") { + Log.info(`Update found for module: ${module.module}`); + updates.push(module); + } + resolve(module); + }); + }); + await Promise.all(allRepos); + + return updates; } } diff --git a/modules/default/updatenotification/node_helper.js b/modules/default/updatenotification/node_helper.js index a0e6830509..c78f413dc9 100644 --- a/modules/default/updatenotification/node_helper.js +++ b/modules/default/updatenotification/node_helper.js @@ -1,6 +1,7 @@ -const GitHelper = require("./git_helper"); -const defaultModules = require("../defaultmodules"); const NodeHelper = require("node_helper"); +const defaultModules = require("../defaultmodules"); +const GitHelper = require("./git_helper"); +const UpdateHelper = require("./update_helper"); const ONE_MINUTE = 60 * 1000; @@ -11,49 +12,82 @@ module.exports = NodeHelper.create({ updateProcessStarted: false, gitHelper: new GitHelper(), + updateHelper: null, - async configureModules(modules) { + async configureModules (modules) { for (const moduleName of modules) { if (!this.ignoreUpdateChecking(moduleName)) { await this.gitHelper.add(moduleName); } } - await this.gitHelper.add("default"); + if (!this.ignoreUpdateChecking("MagicMirror")) { + await this.gitHelper.add("MagicMirror"); + } }, - async socketNotificationReceived(notification, payload) { - if (notification === "CONFIG") { - this.config = payload; - } else if (notification === "MODULES") { - // if this is the 1st time thru the update check process - if (!this.updateProcessStarted) { - this.updateProcessStarted = true; - await this.configureModules(payload); - await this.performFetch(); - } + async socketNotificationReceived (notification, payload) { + switch (notification) { + case "CONFIG": + this.config = payload; + this.updateHelper = new UpdateHelper(this.config); + await this.updateHelper.check_PM2_Process(); + break; + case "MODULES": + // if this is the 1st time thru the update check process + if (!this.updateProcessStarted) { + this.updateProcessStarted = true; + await this.configureModules(payload); + await this.performFetch(); + } + break; + case "SCAN_UPDATES": + // 1st time of check allows to force new scan + if (this.updateProcessStarted) { + clearTimeout(this.updateTimer); + await this.performFetch(); + } + break; } }, - async performFetch() { + async performFetch () { const repos = await this.gitHelper.getRepos(); for (const repo of repos) { - this.sendSocketNotification("STATUS", repo); + this.sendSocketNotification("REPO_STATUS", repo); + } + + const updates = await this.gitHelper.checkUpdates(); + + if (this.config.sendUpdatesNotifications && updates.length) { + this.sendSocketNotification("UPDATES", updates); + } + + if (updates.length) { + const updateResult = await this.updateHelper.parse(updates); + for (const update of updateResult) { + if (update.inProgress) { + this.sendSocketNotification("UPDATE_STATUS", update); + } + } } this.scheduleNextFetch(this.config.updateInterval); }, - scheduleNextFetch(delay) { + scheduleNextFetch (delay) { clearTimeout(this.updateTimer); - this.updateTimer = setTimeout(() => { - this.performFetch(); - }, Math.max(delay, ONE_MINUTE)); + this.updateTimer = setTimeout( + () => { + this.performFetch(); + }, + Math.max(delay, ONE_MINUTE) + ); }, - ignoreUpdateChecking(moduleName) { + ignoreUpdateChecking (moduleName) { // Should not check for updates for default modules if (defaultModules.includes(moduleName)) { return true; diff --git a/modules/default/updatenotification/update_helper.js b/modules/default/updatenotification/update_helper.js new file mode 100644 index 0000000000..33130f1988 --- /dev/null +++ b/modules/default/updatenotification/update_helper.js @@ -0,0 +1,213 @@ +const Exec = require("node:child_process").exec; +const Spawn = require("node:child_process").spawn; +const pm2 = require("pm2"); + +const Log = require("logger"); + +/* class Updater + * Allow to self updating 3rd party modules from command defined in config + * + * [constructor] read value in config: + * updates: [ // array of modules update commands + * { + * : + * }, + * { + * ... + * } + * ], + * updateTimeout: 2 * 60 * 1000, // max update duration + * updateAutorestart: false // autoRestart MM when update done ? + * + * [main command]: parse(): + * parse if module update is needed + * --> Apply ONLY one update (first of the module list) + * --> auto-restart MagicMirror or wait manual restart by user + * return array with modules update state information for `updatenotification` module displayer information + * [ + * { + * name = , // name of the module + * updateCommand = , // update command (if found) + * inProgress = , // an update if in progress for this module + * error = , // an error if detected when updating + * updated = , // updated successfully + * needRestart = // manual restart of MagicMirror is required by user + * }, + * { + * ... + * } + * ] + */ + +class Updater { + constructor (config) { + this.updates = config.updates; + this.timeout = config.updateTimeout; + this.autoRestart = config.updateAutorestart; + this.moduleList = {}; + this.updating = false; + this.usePM2 = false; + this.PM2 = null; + this.version = global.version; + this.root_path = global.root_path; + Log.info("updatenotification: Updater Class Loaded!"); + } + + // [main command] parse if module update is needed + async parse (modules) { + var parser = modules.map(async (module) => { + if (this.moduleList[module.module] === undefined) { + this.moduleList[module.module] = {}; + this.moduleList[module.module].name = module.module; + this.moduleList[module.module].updateCommand = await this.applyCommand(module.module); + this.moduleList[module.module].inProgress = false; + this.moduleList[module.module].error = null; + this.moduleList[module.module].updated = false; + this.moduleList[module.module].needRestart = false; + } + if (!this.moduleList[module.module].inProgress) { + if (!this.updating) { + if (!this.moduleList[module.module].updateCommand) { + this.updating = false; + } else { + this.updating = true; + this.moduleList[module.module].inProgress = true; + Object.assign(this.moduleList[module.module], await this.updateProcess(this.moduleList[module.module])); + } + } + } + }); + + await Promise.all(parser); + let updater = Object.values(this.moduleList); + Log.debug("updatenotification Update Result:", updater); + return updater; + } + + // module updater with his proper command + // return object as result + //{ + // error: , // if error detected + // updated: , // if updated successfully + // needRestart: // if magicmirror restart required + //}; + updateProcess (module) { + let Result = { + error: false, + updated: false, + needRestart: false + }; + let Command = null; + const Path = `${this.root_path}/modules/`; + const modulePath = Path + module.name; + + if (module.updateCommand) { + Command = module.updateCommand; + } else { + Log.warn(`updatenotification: Update of ${module.name} is not supported.`); + return Result; + } + Log.info(`updatenotification: Updating ${module.name}...`); + + return new Promise((resolve) => { + Exec(Command, { cwd: modulePath, timeout: this.timeout }, (error, stdout, stderr) => { + if (error) { + Log.error(`updatenotification: exec error: ${error}`); + Result.error = true; + } else { + Log.info(`updatenotification: Update logs of ${module.name}: ${stdout}`); + Result.updated = true; + if (this.autoRestart) { + Log.info("updatenotification: Update done"); + setTimeout(() => this.restart(), 3000); + } else { + Log.info("updatenotification: Update done, don't forget to restart MagicMirror!"); + Result.needRestart = true; + } + } + resolve(Result); + }); + }); + } + + // restart rules (pm2 or npm start) + restart () { + if (this.usePM2) this.pm2Restart(); + else this.npmRestart(); + } + + // restart MagicMiror with "pm2" + pm2Restart () { + Log.info("updatenotification: PM2 will restarting MagicMirror..."); + pm2.restart(this.PM2, (err, proc) => { + if (err) { + Log.error("updatenotification:[PM2] restart Error", err); + } + }); + } + + // restart MagicMiror with "npm start" + npmRestart () { + Log.info("updatenotification: Restarting MagicMirror..."); + const out = process.stdout; + const err = process.stderr; + const subprocess = Spawn("npm start", { cwd: this.root_path, shell: true, detached: true, stdio: ["ignore", out, err] }); + subprocess.unref(); + process.exit(); + } + + // Check using pm2 + check_PM2_Process () { + Log.info("updatenotification: Checking PM2 using..."); + return new Promise((resolve) => { + pm2.connect((err) => { + if (err) { + Log.error("updatenotification: [PM2]", err); + this.usePM2 = false; + resolve(false); + return; + } + pm2.list((err, list) => { + if (err) { + Log.error("updatenotification: [PM2] Can't get process List!"); + this.usePM2 = false; + resolve(false); + return; + } + list.forEach((pm) => { + if (pm.pm2_env.version === this.version && pm.pm2_env.status === "online" && pm.pm2_env.pm_cwd.includes(`${this.root_path}/`)) { + this.PM2 = pm.name; + this.usePM2 = true; + Log.info("updatenotification: [PM2] You are using pm2 with", this.PM2); + resolve(true); + } + }); + pm2.disconnect(); + if (!this.PM2) { + Log.info("updatenotification: [PM2] You are not using pm2"); + this.usePM2 = false; + resolve(false); + } + }); + }); + }); + } + + // check if module is MagicMirror + isMagicMirror (module) { + if (module === "MagicMirror") return true; + return false; + } + + // search update module command + applyCommand (module) { + if (this.isMagicMirror(module.module) || !this.updates.length) return null; + let command = null; + this.updates.forEach((updater) => { + if (updater[module]) command = updater[module]; + }); + return command; + } +} + +module.exports = Updater; diff --git a/modules/default/updatenotification/updatenotification.js b/modules/default/updatenotification/updatenotification.js index 7b4945c914..a18bc4db0e 100644 --- a/modules/default/updatenotification/updatenotification.js +++ b/modules/default/updatenotification/updatenotification.js @@ -1,20 +1,20 @@ -/* MagicMirror² - * Module: UpdateNotification - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. - */ Module.register("updatenotification", { defaults: { updateInterval: 10 * 60 * 1000, // every 10 minutes refreshInterval: 24 * 60 * 60 * 1000, // one day - ignoreModules: [] + ignoreModules: [], + sendUpdatesNotifications: false, + updates: [], + updateTimeout: 2 * 60 * 1000, // max update duration + updateAutorestart: false // autoRestart MM when update done ? }, suspended: false, moduleList: {}, + needRestart: false, + updates: [], - start() { + start () { Log.info(`Starting module: ${this.name}`); this.addFilters(); setInterval(() => { @@ -23,41 +23,54 @@ Module.register("updatenotification", { }, this.config.refreshInterval); }, - suspend() { + suspend () { this.suspended = true; }, - resume() { + resume () { this.suspended = false; this.updateDom(2); }, - notificationReceived(notification) { - if (notification === "DOM_OBJECTS_CREATED") { - this.sendSocketNotification("CONFIG", this.config); - this.sendSocketNotification("MODULES", Object.keys(Module.definitions)); + notificationReceived (notification) { + switch (notification) { + case "DOM_OBJECTS_CREATED": + this.sendSocketNotification("CONFIG", this.config); + this.sendSocketNotification("MODULES", Object.keys(Module.definitions)); + break; + case "SCAN_UPDATES": + this.sendSocketNotification("SCAN_UPDATES"); + break; } }, - socketNotificationReceived(notification, payload) { - if (notification === "STATUS") { - this.updateUI(payload); + socketNotificationReceived (notification, payload) { + switch (notification) { + case "REPO_STATUS": + this.updateUI(payload); + break; + case "UPDATES": + this.sendNotification("UPDATES", payload); + break; + case "UPDATE_STATUS": + this.updatesNotifier(payload); + break; } }, - getStyles() { + getStyles () { return [`${this.name}.css`]; }, - getTemplate() { + getTemplate () { return `${this.name}.njk`; }, - getTemplateData() { - return { moduleList: this.moduleList, suspended: this.suspended }; + getTemplateData () { + return { moduleList: this.moduleList, updatesList: this.updates, suspended: this.suspended, needRestart: this.needRestart }; }, - updateUI(payload) { + updateUI (payload) { if (payload && payload.behind > 0) { // if we haven't seen info for this module if (this.moduleList[payload.module] === undefined) { @@ -75,15 +88,39 @@ Module.register("updatenotification", { } }, - addFilters() { + addFilters () { this.nunjucksEnvironment().addFilter("diffLink", (text, status) => { - if (status.module !== "default") { + if (status.module !== "MagicMirror") { return text; } const localRef = status.hash; const remoteRef = status.tracking.replace(/.*\//, ""); - return `${text}`; + return `${text}`; }); + }, + + updatesNotifier (payload, done = true) { + if (this.updates[payload.name] === undefined) { + this.updates[payload.name] = { + name: payload.name, + done: done + }; + + if (payload.error) { + this.sendSocketNotification("UPDATE_ERROR", payload.name); + this.updates[payload.name].done = false; + } else { + if (payload.updated) { + delete this.moduleList[payload.name]; + this.updates[payload.name].done = true; + } + if (payload.needRestart) { + this.needRestart = true; + } + } + + this.updateDom(2); + } } }); diff --git a/modules/default/updatenotification/updatenotification.njk b/modules/default/updatenotification/updatenotification.njk index 3149816f0b..fbc43f22fb 100644 --- a/modules/default/updatenotification/updatenotification.njk +++ b/modules/default/updatenotification/updatenotification.njk @@ -1,15 +1,41 @@ {% if not suspended %} - {% for name, status in moduleList %} -
    - - - {% set mainTextLabel = "UPDATE_NOTIFICATION" if name === "default" else "UPDATE_NOTIFICATION_MODULE" %} - {{ mainTextLabel | translate({MODULE_NAME: name}) }} - -
    -
    - {% set subTextLabel = "UPDATE_INFO_SINGLE" if status.behind === 1 else "UPDATE_INFO_MULTIPLE" %} - {{ subTextLabel | translate({COMMIT_COUNT: status.behind, BRANCH_NAME: status.current}) | diffLink(status) | safe }} -
    - {% endfor %} + {% if needRestart %} +
    + + + {% set restartTextLabel = "UPDATE_NOTIFICATION_NEED-RESTART" %} + {{ restartTextLabel | translate() | safe }} + +
    + {% endif %} + {% for name, status in moduleList %} +
    + + + {% set mainTextLabel = "UPDATE_NOTIFICATION" if name === "MagicMirror" else "UPDATE_NOTIFICATION_MODULE" %} + {{ mainTextLabel | translate({MODULE_NAME: name}) }} + +
    +
    + {% set subTextLabel = "UPDATE_INFO_SINGLE" if status.behind === 1 else "UPDATE_INFO_MULTIPLE" %} + {{ subTextLabel | translate({COMMIT_COUNT: status.behind, BRANCH_NAME: status.current}) | diffLink(status) | safe }} +
    + {% endfor %} + {% for name, status in updatesList %} +
    + {% if status.done %} + + + {% set updateTextLabel = "UPDATE_NOTIFICATION_DONE" %} + {{ updateTextLabel | translate({MODULE_NAME: name}) | safe }} + + {% else %} + + + {% set updateTextLabel = "UPDATE_NOTIFICATION_ERROR" %} + {{ updateTextLabel | translate({MODULE_NAME: name}) | safe }} + + {% endif %} +
    + {% endfor %} {% endif %} diff --git a/modules/default/utils.js b/modules/default/utils.js index fb2cab8f31..ca0166935c 100644 --- a/modules/default/utils.js +++ b/modules/default/utils.js @@ -1,21 +1,22 @@ /** * 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). + * @param {Array.} expectedResponseHeaders the expected HTTP headers to receive + * @returns {Promise} resolved when the fetch is done. The response headers is placed in a headers-property (provided the response does not already contain a headers-property). */ -async function performWebRequest(url, type = "json", useCorsProxy = false, requestHeaders = undefined, expectedResponseHeaders = undefined) { +async function performWebRequest (url, type = "json", useCorsProxy = false, requestHeaders = undefined, expectedResponseHeaders = undefined) { const request = {}; + let requestUrl; if (useCorsProxy) { - url = getCorsUrl(url, requestHeaders, expectedResponseHeaders); + requestUrl = getCorsUrl(url, requestHeaders, expectedResponseHeaders); } else { + requestUrl = url; request.headers = getHeadersToSend(requestHeaders); } - const response = await fetch(url, request); + const response = await fetch(requestUrl, request); const data = await response.text(); if (type === "xml") { @@ -33,10 +34,9 @@ async function performWebRequest(url, type = "json", useCorsProxy = false, reque /** * 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 + * @param {Array.} expectedResponseHeaders the expected HTTP headers to receive * @returns {string} to be used as URL when calling CORS-method on server. */ const getCorsUrl = function (url, requestHeaders, expectedResponseHeaders) { @@ -64,7 +64,6 @@ const getCorsUrl = function (url, requestHeaders, expectedResponseHeaders) { /** * 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. */ @@ -84,8 +83,7 @@ const getRequestHeaderString = function (requestHeaders) { }; /** - * Gets headers and values to attatch to the web request. - * + * Gets headers and values to attach to the web request. * @param {Array.<{name: string, value:string}>} requestHeaders the HTTP headers to send * @returns {object} An object specifying name and value of the headers. */ @@ -101,9 +99,8 @@ const getHeadersToSend = (requestHeaders) => { }; /** - * Gets the part of the CORS URL that represents the expected HTTP headers to recieve. - * - * @param {Array.} expectedResponseHeaders the expected HTTP headers to recieve + * Gets the part of the CORS URL that represents the expected HTTP headers to receive. + * @param {Array.} expectedResponseHeaders the expected HTTP headers to receive * @returns {string} to be used as the expected HTTP-headers component in CORS URL. */ const getExpectedResponseHeadersString = function (expectedResponseHeaders) { @@ -123,8 +120,7 @@ const getExpectedResponseHeadersString = function (expectedResponseHeaders) { /** * Gets the values for the expected headers from the response. - * - * @param {Array.} expectedResponseHeaders the expected HTTP headers to recieve + * @param {Array.} expectedResponseHeaders the expected HTTP headers to receive * @param {Response} response the HTTP response * @returns {string} to be used as the expected HTTP-headers component in CORS URL. */ @@ -141,7 +137,35 @@ const getHeadersFromResponse = (expectedResponseHeaders, response) => { return responseHeaders; }; -if (typeof module !== "undefined") - module.exports = { - performWebRequest - }; +/** + * Format the time according to the config + * @param {object} config The config of the module + * @param {object} time time to format + * @returns {string} The formatted time string + */ +const formatTime = (config, time) => { + let date = moment(time); + + if (config.timezone) { + date = date.tz(config.timezone); + } + + if (config.timeFormat !== 24) { + if (config.showPeriod) { + if (config.showPeriodUpper) { + return date.format("h:mm A"); + } else { + return date.format("h:mm a"); + } + } else { + return date.format("h:mm"); + } + } + + return date.format("HH:mm"); +}; + +if (typeof module !== "undefined") module.exports = { + performWebRequest, + formatTime +}; diff --git a/modules/default/weather/current.njk b/modules/default/weather/current.njk index ae542caa9a..d19848954e 100644 --- a/modules/default/weather/current.njk +++ b/modules/default/weather/current.njk @@ -1,3 +1,8 @@ +{% macro humidity() %} + {% if current.humidity %} + {{ current.humidity | decimalSymbol }}  + {% endif %} +{% endmacro %} {% if current %} {% if not config.onlyTemp %}
    @@ -7,7 +12,7 @@ {% if config.showWindDirection %} {% if config.showWindDirectionAsArrow %} - + {% else %} {{ current.cardinalWindDirection() | translate }} {% endif %} @@ -15,8 +20,8 @@ {% endif %} - {% if config.showHumidity and current.humidity %} - {{ current.humidity | decimalSymbol }}  + {% if config.showHumidity === "wind" %} + {{ humidity() }} {% endif %} {% if config.showSun %} @@ -28,51 +33,69 @@ {% endif %} {% endif %} + {% if config.showUVIndex %} + +
    + {{ current.uv_index }} + + {% endif %}
    {% endif %} -
    - - - {{ current.temperature | roundValue | unit("temperature") | decimalSymbol }} - -
    -
    - {% if config.showIndoorTemperature and indoor.temperature %} -
    - - - {{ indoor.temperature | roundValue | unit("temperature") | decimalSymbol }} - -
    +
    + {% if config.showIndoorTemperature and indoor.temperature or config.showIndoorHumidity and indoor.humidity %} + + + {% if config.showIndoorTemperature and indoor.temperature %} + + + {{ indoor.temperature | roundValue | unit("temperature") | decimalSymbol }} + + + {% endif %} + {% if config.showIndoorHumidity and indoor.humidity %} + + + {{ indoor.humidity | roundValue | unit("humidity") | decimalSymbol }} + + + {% endif %} + {% endif %} - {% if config.showIndoorHumidity and indoor.humidity %} -
    - - - {{ indoor.humidity | roundValue | unit("humidity") | decimalSymbol }} - -
    + + {{ current.temperature | roundValue | unit("temperature") | decimalSymbol }} + {% if config.showHumidity === "temp" %} + {{ humidity() }} {% endif %}
    - {% if (config.showFeelsLike or config.showPrecipitationAmount) and not config.onlyTemp %} + {% if (config.showFeelsLike or config.showPrecipitationAmount or config.showPrecipitationProbability) and not config.onlyTemp %}
    {% if config.showFeelsLike %} + {% if config.showHumidity === "feelslike" %} + {{ humidity() }} + {% endif %} {{ "FEELS" | translate({DEGREE: current.feelsLike() | roundValue | unit("temperature") | decimalSymbol }) }} +
    {% endif %} - {% if config.showPrecipitationAmount %} + {% if config.showPrecipitationAmount and current.precipitationAmount %} - {{ "PRECIP" | translate }} {{ current.precipitation | unit("precip") }} + {{ "PRECIP_AMOUNT" | translate }} {{ current.precipitationAmount | unit("precip", current.precipitationUnits) }} + +
    + {% endif %} + {% if config.showPrecipitationProbability and current.precipitationProbability %} + + {{ "PRECIP_POP" | translate }} {{ current.precipitationProbability }}% {% endif %}
    {% endif %} + {% if config.showHumidity === "below" %} + {{ humidity() }} + {% endif %} {% else %} -
    - {{ "LOADING" | translate }} -
    +
    {{ "LOADING" | translate }}
    {% endif %} - diff --git a/modules/default/weather/forecast.njk b/modules/default/weather/forecast.njk index 2bac7eae4b..85570fbbd0 100644 --- a/modules/default/weather/forecast.njk +++ b/modules/default/weather/forecast.njk @@ -7,15 +7,18 @@ {% endif %} {% set forecast = forecast.slice(0, numSteps) %} {% for f in forecast %} - + {% if (currentStep == 0) and config.ignoreToday == false and config.absoluteDates == false %} {{ "TODAY" | translate }} {% elif (currentStep == 1) and config.ignoreToday == false and config.absoluteDates == false %} {{ "TOMORROW" | translate }} {% else %} - {{ f.date.format('ddd') }} + {{ f.date.format("ddd") }} {% endif %} - + + + {{ f.maxTemperature | roundValue | unit("temperature") | decimalSymbol }} @@ -23,25 +26,27 @@ {{ f.minTemperature | roundValue | unit("temperature") | decimalSymbol }} {% if config.showPrecipitationAmount %} - {% if f.precipitationUnits %} - - {{ f.precipitation }}{{ f.precipitationUnits }} - - {% else %} - - {{ f.precipitation | unit("precip") }} - - {% endif %} + + {{ f.precipitationAmount | unit("precip", f.precipitationUnits) }} + + {% endif %} + {% if config.showPrecipitationProbability %} + + {{ f.precipitationProbability | unit('precip', '%') }} + + {% endif %} + {% if config.showUVIndex %} + + {{ f.uv_index }} + + {% endif %} {% set currentStep = currentStep + 1 %} {% endfor %} {% else %} -
    - {{ "LOADING" | translate }} -
    +
    {{ "LOADING" | translate }}
    {% endif %} - diff --git a/modules/default/weather/hourly.njk b/modules/default/weather/hourly.njk index f58d31a0cf..0e464f77e6 100644 --- a/modules/default/weather/hourly.njk +++ b/modules/default/weather/hourly.njk @@ -4,32 +4,39 @@ {% set hours = hourly.slice(0, numSteps) %} {% for hour in hours %} - + - + + {% if config.showUVIndex %} + + {% endif %} {% if config.showPrecipitationAmount %} - {% if hour.precipitationUnits %} - - {% else %} - - {% endif %} + + {% endif %} + {% if config.showPrecipitationProbability %} + {% endif %} {% set currentStep = currentStep + 1 %} {% endfor %}
    {{ hour.date | formatTime }} + + {{ hour.temperature | roundValue | unit("temperature") }} + {% if hour.uv_index!=0 %} + {{ hour.uv_index }} + + {% endif %} + - {{ hour.precipitation }}{{ hour.precipitationUnits }} - - {{ hour.precipitation | unit("precip") }} - + {{ hour.precipitationAmount | unit("precip", hour.precipitationUnits) }} + + {{ hour.precipitationProbability | unit('precip', '%') }} +
    {% else %} -
    - {{ "LOADING" | translate }} -
    +
    {{ "LOADING" | translate }}
    {% endif %} - diff --git a/modules/default/weather/providers/envcanada.js b/modules/default/weather/providers/envcanada.js index 4842446be6..7372e17689 100644 --- a/modules/default/weather/providers/envcanada.js +++ b/modules/default/weather/providers/envcanada.js @@ -1,10 +1,6 @@ /* global WeatherProvider, WeatherObject, WeatherUtils */ -/* MagicMirror² - * Module: Weather - * Provider: Environment Canada (EC) - * - * This class is a provider for Environment Canada MSC Datamart +/* This class is a provider for Environment Canada MSC Datamart * Note that this is only for Canadian locations and does not require an API key (access is anonymous) * * EC Documentation at following links: @@ -27,8 +23,6 @@ * with locations you can search under column B (English Names), with the corresponding siteCode under * column A (Codes) and provCode under column C (Province). * - * Original by Kevin Godin - * * License to use Environment Canada (EC) data is detailed here: * https://eccc-msc.github.io/open-data/licence/readme_en/ * @@ -49,7 +43,7 @@ WeatherProvider.register("envcanada", { // Set config values (equates to weather module config values). Also set values pertaining to caching of // Today's temperature forecast (for use in the Forecast functions below) // - setConfig: function (config) { + setConfig (config) { this.config = config; this.todayTempCacheMin = 0; @@ -61,7 +55,7 @@ WeatherProvider.register("envcanada", { // // Called when the weather provider is started // - start: function () { + start () { Log.info(`Weather provider: ${this.providerName} started.`); this.setFetchedLocation(this.config.location); }, @@ -69,7 +63,7 @@ WeatherProvider.register("envcanada", { // // Override the fetchCurrentWeather method to query EC and construct a Current weather object // - fetchCurrentWeather() { + fetchCurrentWeather () { this.fetchData(this.getUrl(), "xml") .then((data) => { if (!data) { @@ -89,7 +83,7 @@ WeatherProvider.register("envcanada", { // // Override the fetchWeatherForecast method to query EC and construct Forecast weather objects // - fetchWeatherForecast() { + fetchWeatherForecast () { this.fetchData(this.getUrl(), "xml") .then((data) => { if (!data) { @@ -109,7 +103,7 @@ WeatherProvider.register("envcanada", { // // Override the fetchWeatherHourly method to query EC and construct Forecast weather objects // - fetchWeatherHourly() { + fetchWeatherHourly () { this.fetchData(this.getUrl(), "xml") .then((data) => { if (!data) { @@ -137,15 +131,15 @@ WeatherProvider.register("envcanada", { // 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() { - return "https://dd.weather.gc.ca/citypage_weather/xml/" + this.config.provCode + "/" + this.config.siteCode + "_e.xml"; + getUrl () { + return `https://dd.weather.gc.ca/citypage_weather/xml/${this.config.provCode}/${this.config.siteCode}_e.xml`; }, // // Generate a WeatherObject based on current EC weather conditions // - generateWeatherObjectFromCurrentWeather(ECdoc) { + generateWeatherObjectFromCurrentWeather (ECdoc) { const currentWeather = new WeatherObject(); // There are instances where EC will update weather data and current temperature will not be @@ -165,7 +159,7 @@ WeatherProvider.register("envcanada", { currentWeather.windSpeed = WeatherUtils.convertWindToMs(ECdoc.querySelector("siteData currentConditions wind speed").textContent); - currentWeather.windDirection = ECdoc.querySelector("siteData currentConditions wind bearing").textContent; + currentWeather.windFromDirection = ECdoc.querySelector("siteData currentConditions wind bearing").textContent; currentWeather.humidity = ECdoc.querySelector("siteData currentConditions relativeHumidity").textContent; @@ -216,7 +210,7 @@ WeatherProvider.register("envcanada", { // Generate an array of WeatherObjects based on EC weather forecast // - generateWeatherObjectsFromForecast(ECdoc) { + generateWeatherObjectsFromForecast (ECdoc) { // Declare an array to hold each day's forecast object const days = []; @@ -230,12 +224,7 @@ WeatherProvider.register("envcanada", { const foreGroup = ECdoc.querySelectorAll("siteData forecastGroup forecast"); - // For simplicity, we will only accumulate precipitation and will not try to break out - // rain vs snow accumulations - - weather.rain = null; - weather.snow = null; - weather.precipitation = null; + weather.precipitationAmount = null; // // The EC forecast is held in a 12-element array - Elements 0 to 11 - with each day encompassing @@ -336,16 +325,14 @@ WeatherProvider.register("envcanada", { // Add 1 to the date to reflect the current forecast day we are building lastDate = lastDate.add(1, "day"); - weather.date = moment.unix(lastDate); + weather.date = moment(lastDate); // Capture the temperatures for the current Element and the next Element in order to set // the Min and Max temperatures for the forecast this.setMinMaxTemps(weather, foreGroup, stepDay, true, currentTemp); - weather.rain = null; - weather.snow = null; - weather.precipitation = null; + weather.precipitationAmount = null; this.setPrecipitation(weather, foreGroup, stepDay); @@ -367,7 +354,7 @@ WeatherProvider.register("envcanada", { // Generate an array of WeatherObjects based on EC hourly weather forecast // - generateWeatherObjectsFromHourly(ECdoc) { + generateWeatherObjectsFromHourly (ECdoc) { // Declare an array to hold each hour's forecast object const hours = []; @@ -391,7 +378,7 @@ WeatherProvider.register("envcanada", { const foreTime = moment(hourGroup[stepHour].getAttribute("dateTimeUTC"), "YYYYMMDDhhmmss"); const currTime = foreTime.add(hourOffset, "hours"); - weather.date = moment.unix(currTime); + weather.date = moment(currTime); // Capture the temperature @@ -402,8 +389,7 @@ WeatherProvider.register("envcanada", { const precipLOP = hourGroup[stepHour].querySelector("lop").textContent * 1.0; if (precipLOP > 0) { - weather.precipitation = precipLOP; - weather.precipitationUnits = hourGroup[stepHour].querySelector("lop").getAttribute("units"); + weather.precipitationProbability = precipLOP; } // @@ -424,7 +410,7 @@ WeatherProvider.register("envcanada", { // the next Forecast element should be considered - i.e. look at Today *and* Tonight vs.Tonight-only // - setMinMaxTemps(weather, foreGroup, today, fullDay, currentTemp) { + setMinMaxTemps (weather, foreGroup, today, fullDay, currentTemp) { const todayTemp = foreGroup[today].querySelector("temperatures temperature").textContent; const todayClass = foreGroup[today].querySelector("temperatures temperature").getAttribute("class"); @@ -506,36 +492,23 @@ WeatherProvider.register("envcanada", { // the nightime forecast after a certain point in that specific scenario. // - setPrecipitation(weather, foreGroup, today) { + setPrecipitation (weather, foreGroup, today) { if (foreGroup[today].querySelector("precipitation accumulation")) { - weather.precipitation = foreGroup[today].querySelector("precipitation accumulation amount").textContent * 1.0; - - weather.precipitationUnits = " " + foreGroup[today].querySelector("precipitation accumulation amount").getAttribute("units"); - - if (this.config.units === "imperial") { - if (weather.precipitationUnits === " cm") { - weather.precipitation = (weather.precipitation * 0.394).toFixed(2); - weather.precipitationUnits = " in"; - } - if (weather.precipitationUnits === " mm") { - weather.precipitation = (weather.precipitation * 0.0394).toFixed(2); - weather.precipitationUnits = " in"; - } - } + weather.precipitationAmount = foreGroup[today].querySelector("precipitation accumulation amount").textContent * 1.0; + weather.precipitationUnits = foreGroup[today].querySelector("precipitation accumulation amount").getAttribute("units"); } // Check Today element for POP - - if (foreGroup[today].querySelector("abbreviatedForecast pop").textContent > 0) { - weather.precipitation = foreGroup[today].querySelector("abbreviatedForecast pop").textContent; - weather.precipitationUnits = foreGroup[today].querySelector("abbreviatedForecast pop").getAttribute("units"); + const precipPOP = foreGroup[today].querySelector("abbreviatedForecast pop").textContent * 1.0; + if (precipPOP > 0) { + weather.precipitationProbability = precipPOP; } }, // // Convert the icons to a more usable name. // - convertWeatherType(weatherType) { + convertWeatherType (weatherType) { const weatherTypes = { "00": "day-sunny", "01": "day-sunny", diff --git a/modules/default/weather/providers/openmeteo.js b/modules/default/weather/providers/openmeteo.js new file mode 100644 index 0000000000..e199caff65 --- /dev/null +++ b/modules/default/weather/providers/openmeteo.js @@ -0,0 +1,541 @@ +/* global WeatherProvider, WeatherObject */ + +/* This class is a provider for Open-Meteo, + * see https://open-meteo.com/ + */ + +// 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, + pastDays: 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", + // Precipitation Probability + "precipitation_probability", + // UV index + "uv_index", + // 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", + //UV Index + "uv_index_max", + // Daily sum of ET₀ Reference Evapotranspiration of a well watered grass field + "et0_fao_evapotranspiration" + ], + + fetchedLocation () { + 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.pastDays ?? 0, + daily: this.dailyParams, + hourly: this.hourlyParams, + // Fixed units as metric + temperature_unit: "celsius", + windspeed_unit: "ms", + 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(); + + currentWeather.date = weather.current_weather.time; + currentWeather.windSpeed = weather.current_weather.windspeed; + currentWeather.windFromDirection = weather.current_weather.winddirection; + currentWeather.sunrise = weather.daily[0].sunrise; + currentWeather.sunset = weather.daily[0].sunset; + currentWeather.temperature = parseFloat(weather.current_weather.temperature); + 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.precipitationAmount = parseFloat(weather.hourly[h].precipitation); + currentWeather.precipitationProbability = parseFloat(weather.hourly[h].precipitation_probability); + currentWeather.uv_index = parseFloat(weather.hourly[h].uv_index); + + return currentWeather; + }, + + // Implement WeatherForecast generator. + generateWeatherObjectsFromForecast (weathers) { + const days = []; + + weathers.daily.forEach((weather) => { + const currentWeather = new WeatherObject(); + + currentWeather.date = weather.time; + currentWeather.windSpeed = weather.windspeed_10m_max; + currentWeather.windFromDirection = weather.winddirection_10m_dominant; + currentWeather.sunrise = weather.sunrise; + currentWeather.sunset = weather.sunset; + currentWeather.temperature = parseFloat((weather.apparent_temperature_max + weather.apparent_temperature_min) / 2); + currentWeather.minTemperature = parseFloat(weather.apparent_temperature_min); + currentWeather.maxTemperature = parseFloat(weather.apparent_temperature_max); + currentWeather.weatherType = this.convertWeatherType(weather.weathercode, true); + currentWeather.rain = parseFloat(weather.rain_sum); + currentWeather.snow = parseFloat(weather.snowfall_sum * 10); + currentWeather.precipitationAmount = parseFloat(weather.precipitation_sum); + currentWeather.precipitationProbability = parseFloat(weather.precipitation_hours * 100 / 24); + currentWeather.uv_index = parseFloat(weather.uv_index_max); + + 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 <= now) || hours.length >= this.config.maxEntries) { + return; + } + + const currentWeather = new WeatherObject(); + const h = Math.ceil((i + 1) / 24) - 1; + + currentWeather.date = weather.time; + currentWeather.windSpeed = weather.windspeed_10m; + currentWeather.windFromDirection = 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.precipitationAmount = parseFloat(weather.precipitation); + currentWeather.precipitationProbability = parseFloat(weather.precipitation_probability); + currentWeather.uv_index = parseFloat(weather.uv_index); + + 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 () { + return ["moment.js"]; + } +}); diff --git a/modules/default/weather/providers/openweathermap.js b/modules/default/weather/providers/openweathermap.js index f5f786fa01..0999c83f0a 100644 --- a/modules/default/weather/providers/openweathermap.js +++ b/modules/default/weather/providers/openweathermap.js @@ -1,12 +1,7 @@ /* global WeatherProvider, WeatherObject */ -/* MagicMirror² - * Module: Weather - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. - * - * This class is the blueprint for a weather provider. +/* This class is a provider for Openweathermap, + * see https://openweathermap.org/ */ WeatherProvider.register("openweathermap", { // Set the name of the provider. @@ -27,7 +22,7 @@ WeatherProvider.register("openweathermap", { }, // Overwrite the fetchCurrentWeather method. - fetchCurrentWeather() { + fetchCurrentWeather () { this.fetchData(this.getUrl()) .then((data) => { let currentWeather; @@ -46,7 +41,7 @@ WeatherProvider.register("openweathermap", { }, // Overwrite the fetchWeatherForecast method. - fetchWeatherForecast() { + fetchWeatherForecast () { this.fetchData(this.getUrl()) .then((data) => { let forecast; @@ -68,7 +63,7 @@ WeatherProvider.register("openweathermap", { }, // Overwrite the fetchWeatherHourly method. - fetchWeatherHourly() { + fetchWeatherHourly () { this.fetchData(this.getUrl()) .then((data) => { if (!data) { @@ -90,10 +85,9 @@ WeatherProvider.register("openweathermap", { /** * Overrides method for setting config to check if endpoint is correct for hourly - * * @param {object} config The configuration object */ - setConfig(config) { + setConfig (config) { this.config = config; if (!this.config.weatherEndpoint) { switch (this.config.type) { @@ -117,14 +111,14 @@ WeatherProvider.register("openweathermap", { /* * Gets the complete url for the request */ - getUrl() { + getUrl () { return this.config.apiBase + this.config.apiVersion + this.config.weatherEndpoint + this.getParams(); }, /* * Generate a WeatherObject based on currentWeatherInformation */ - generateWeatherObjectFromCurrentWeather(currentWeatherData) { + generateWeatherObjectFromCurrentWeather (currentWeatherData) { const currentWeather = new WeatherObject(); currentWeather.date = moment.unix(currentWeatherData.dt); @@ -132,7 +126,7 @@ WeatherProvider.register("openweathermap", { currentWeather.temperature = currentWeatherData.main.temp; currentWeather.feelsLikeTemp = currentWeatherData.main.feels_like; currentWeather.windSpeed = currentWeatherData.wind.speed; - currentWeather.windDirection = currentWeatherData.wind.deg; + currentWeather.windFromDirection = currentWeatherData.wind.deg; currentWeather.weatherType = this.convertWeatherType(currentWeatherData.weather[0].icon); currentWeather.sunrise = moment.unix(currentWeatherData.sys.sunrise); currentWeather.sunset = moment.unix(currentWeatherData.sys.sunset); @@ -143,11 +137,11 @@ WeatherProvider.register("openweathermap", { /* * Generate WeatherObjects based on forecast information */ - generateWeatherObjectsFromForecast(forecasts) { + generateWeatherObjectsFromForecast (forecasts) { if (this.config.weatherEndpoint === "/forecast") { - return this.fetchForecastHourly(forecasts); + return this.generateForecastHourly(forecasts); } else if (this.config.weatherEndpoint === "/forecast/daily") { - return this.fetchForecastDaily(forecasts); + return this.generateForecastDaily(forecasts); } // if weatherEndpoint does not match forecast or forecast/daily, what should be returned? return [new WeatherObject()]; @@ -156,7 +150,7 @@ WeatherProvider.register("openweathermap", { /* * Generate WeatherObjects based on One Call forecast information */ - generateWeatherObjectsFromOnecall(data) { + generateWeatherObjectsFromOnecall (data) { if (this.config.weatherEndpoint === "/onecall") { return this.fetchOnecall(data); } @@ -165,9 +159,10 @@ WeatherProvider.register("openweathermap", { }, /* - * fetch forecast information for 3-hourly forecast (available for free subscription). + * Generate forecast information for 3-hourly forecast (available for free + * subscription). */ - fetchForecastHourly(forecasts) { + generateForecastHourly (forecasts) { // initial variable declaration const days = []; // variables for temperature range and rain @@ -186,7 +181,7 @@ WeatherProvider.register("openweathermap", { weather.maxTemperature = Math.max.apply(null, maxTemp); weather.rain = rain; weather.snow = snow; - weather.precipitation = weather.rain + weather.snow; + weather.precipitationAmount = (weather.rain ?? 0) + (weather.snow ?? 0); // push weather information to days array days.push(weather); // create new weather-object @@ -216,20 +211,12 @@ WeatherProvider.register("openweathermap", { minTemp.push(forecast.main.temp_min); maxTemp.push(forecast.main.temp_max); - if (forecast.hasOwnProperty("rain")) { - if (this.config.units === "imperial" && !isNaN(forecast.rain["3h"])) { - rain += forecast.rain["3h"] / 25.4; - } else if (!isNaN(forecast.rain["3h"])) { - rain += forecast.rain["3h"]; - } + if (forecast.hasOwnProperty("rain") && !isNaN(forecast.rain["3h"])) { + rain += forecast.rain["3h"]; } - if (forecast.hasOwnProperty("snow")) { - if (this.config.units === "imperial" && !isNaN(forecast.snow["3h"])) { - snow += forecast.snow["3h"] / 25.4; - } else if (!isNaN(forecast.snow["3h"])) { - snow += forecast.snow["3h"]; - } + if (forecast.hasOwnProperty("snow") && !isNaN(forecast.snow["3h"])) { + snow += forecast.snow["3h"]; } } @@ -239,16 +226,17 @@ WeatherProvider.register("openweathermap", { weather.maxTemperature = Math.max.apply(null, maxTemp); weather.rain = rain; weather.snow = snow; - weather.precipitation = weather.rain + weather.snow; + weather.precipitationAmount = (weather.rain ?? 0) + (weather.snow ?? 0); // push weather information to days array days.push(weather); return days.slice(1); }, /* - * fetch forecast information for daily forecast (available for paid subscription or old apiKey). + * Generate forecast information for daily forecast (available for paid + * subscription or old apiKey). */ - fetchForecastDaily(forecasts) { + generateForecastDaily (forecasts) { // initial variable declaration const days = []; @@ -264,25 +252,18 @@ WeatherProvider.register("openweathermap", { // forecast.rain not available if amount is zero // The API always returns in millimeters - if (forecast.hasOwnProperty("rain")) { - if (this.config.units === "imperial" && !isNaN(forecast.rain)) { - weather.rain = forecast.rain / 25.4; - } else if (!isNaN(forecast.rain)) { - weather.rain = forecast.rain; - } + if (forecast.hasOwnProperty("rain") && !isNaN(forecast.rain)) { + weather.rain = forecast.rain; } // forecast.snow not available if amount is zero // The API always returns in millimeters - if (forecast.hasOwnProperty("snow")) { - if (this.config.units === "imperial" && !isNaN(forecast.snow)) { - weather.snow = forecast.snow / 25.4; - } else if (!isNaN(forecast.snow)) { - weather.snow = forecast.snow; - } + if (forecast.hasOwnProperty("snow") && !isNaN(forecast.snow)) { + weather.snow = forecast.snow; } - weather.precipitation = weather.rain + weather.snow; + weather.precipitationAmount = weather.rain + weather.snow; + weather.precipitationProbability = forecast.pop ? forecast.pop * 100 : undefined; days.push(weather); } @@ -295,7 +276,7 @@ WeatherProvider.register("openweathermap", { * Factors in timezone offsets. * Minutely forecasts are excluded for the moment, see getParams(). */ - fetchOnecall(data) { + fetchOnecall (data) { let precip = false; // get current weather, if requested @@ -303,30 +284,23 @@ WeatherProvider.register("openweathermap", { if (data.hasOwnProperty("current")) { current.date = moment.unix(data.current.dt).utcOffset(data.timezone_offset / 60); current.windSpeed = data.current.wind_speed; - current.windDirection = data.current.wind_deg; + current.windFromDirection = data.current.wind_deg; current.sunrise = moment.unix(data.current.sunrise).utcOffset(data.timezone_offset / 60); current.sunset = moment.unix(data.current.sunset).utcOffset(data.timezone_offset / 60); current.temperature = data.current.temp; current.weatherType = this.convertWeatherType(data.current.weather[0].icon); current.humidity = data.current.humidity; + current.uv_index = data.current.uvi; if (data.current.hasOwnProperty("rain") && !isNaN(data.current["rain"]["1h"])) { - if (this.config.units === "imperial") { - current.rain = data.current["rain"]["1h"] / 25.4; - } else { - current.rain = data.current["rain"]["1h"]; - } + current.rain = data.current["rain"]["1h"]; precip = true; } if (data.current.hasOwnProperty("snow") && !isNaN(data.current["snow"]["1h"])) { - if (this.config.units === "imperial") { - current.snow = data.current["snow"]["1h"] / 25.4; - } else { - current.snow = data.current["snow"]["1h"]; - } + current.snow = data.current["snow"]["1h"]; precip = true; } if (precip) { - current.precipitation = current.rain + current.snow; + current.precipitationAmount = (current.rain ?? 0) + (current.snow ?? 0); } current.feelsLikeTemp = data.current.feels_like; } @@ -342,27 +316,21 @@ WeatherProvider.register("openweathermap", { weather.feelsLikeTemp = hour.feels_like; weather.humidity = hour.humidity; weather.windSpeed = hour.wind_speed; - weather.windDirection = hour.wind_deg; + weather.windFromDirection = hour.wind_deg; weather.weatherType = this.convertWeatherType(hour.weather[0].icon); + weather.precipitationProbability = hour.pop ? hour.pop * 100 : undefined; + weather.uv_index = hour.uvi; precip = false; if (hour.hasOwnProperty("rain") && !isNaN(hour.rain["1h"])) { - if (this.config.units === "imperial") { - weather.rain = hour.rain["1h"] / 25.4; - } else { - weather.rain = hour.rain["1h"]; - } + weather.rain = hour.rain["1h"]; precip = true; } if (hour.hasOwnProperty("snow") && !isNaN(hour.snow["1h"])) { - if (this.config.units === "imperial") { - weather.snow = hour.snow["1h"] / 25.4; - } else { - weather.snow = hour.snow["1h"]; - } + weather.snow = hour.snow["1h"]; precip = true; } if (precip) { - weather.precipitation = weather.rain + weather.snow; + weather.precipitationAmount = (weather.rain ?? 0) + (weather.snow ?? 0); } hours.push(weather); @@ -381,27 +349,21 @@ WeatherProvider.register("openweathermap", { weather.maxTemperature = day.temp.max; weather.humidity = day.humidity; weather.windSpeed = day.wind_speed; - weather.windDirection = day.wind_deg; + weather.windFromDirection = day.wind_deg; weather.weatherType = this.convertWeatherType(day.weather[0].icon); + weather.precipitationProbability = day.pop ? day.pop * 100 : undefined; + weather.uv_index = day.uvi; precip = false; if (!isNaN(day.rain)) { - if (this.config.units === "imperial") { - weather.rain = day.rain / 25.4; - } else { - weather.rain = day.rain; - } + weather.rain = day.rain; precip = true; } if (!isNaN(day.snow)) { - if (this.config.units === "imperial") { - weather.snow = day.snow / 25.4; - } else { - weather.snow = day.snow; - } + weather.snow = day.snow; precip = true; } if (precip) { - weather.precipitation = weather.rain + weather.snow; + weather.precipitationAmount = (weather.rain ?? 0) + (weather.snow ?? 0); } days.push(weather); @@ -415,7 +377,7 @@ WeatherProvider.register("openweathermap", { /* * Convert the OpenWeatherMap icons to a more usable name. */ - convertWeatherType(weatherType) { + convertWeatherType (weatherType) { const weatherTypes = { "01d": "day-sunny", "02d": "day-cloudy", @@ -445,11 +407,11 @@ WeatherProvider.register("openweathermap", { * * return String - URL params. */ - getParams() { + getParams () { let params = "?"; if (this.config.weatherEndpoint === "/onecall") { - params += "lat=" + this.config.lat; - params += "&lon=" + this.config.lon; + params += `lat=${this.config.lat}`; + params += `&lon=${this.config.lon}`; if (this.config.type === "current") { params += "&exclude=minutely,hourly,daily"; } else if (this.config.type === "hourly") { @@ -460,23 +422,24 @@ WeatherProvider.register("openweathermap", { params += "&exclude=minutely"; } } else if (this.config.lat && this.config.lon) { - params += "lat=" + this.config.lat + "&lon=" + this.config.lon; + params += `lat=${this.config.lat}&lon=${this.config.lon}`; } else if (this.config.locationID) { - params += "id=" + this.config.locationID; + params += `id=${this.config.locationID}`; } else if (this.config.location) { - params += "q=" + this.config.location; + params += `q=${this.config.location}`; } else if (this.firstEvent && this.firstEvent.geo) { - params += "lat=" + this.firstEvent.geo.lat + "&lon=" + this.firstEvent.geo.lon; + params += `lat=${this.firstEvent.geo.lat}&lon=${this.firstEvent.geo.lon}`; } else if (this.firstEvent && this.firstEvent.location) { - params += "q=" + this.firstEvent.location; + params += `q=${this.firstEvent.location}`; } else { + // TODO hide doesnt exist! this.hide(this.config.animationSpeed, { lockString: this.identifier }); return; } params += "&units=metric"; // WeatherProviders should use metric internally and use the units only for when displaying data - params += "&lang=" + this.config.lang; - params += "&APPID=" + this.config.apiKey; + params += `&lang=${this.config.lang}`; + params += `&APPID=${this.config.apiKey}`; return params; } diff --git a/modules/default/weather/providers/overrideWrapper.js b/modules/default/weather/providers/overrideWrapper.js new file mode 100644 index 0000000000..a9002809a1 --- /dev/null +++ b/modules/default/weather/providers/overrideWrapper.js @@ -0,0 +1,112 @@ +/* global Class, WeatherObject */ + +/* + * Wrapper class to enable overrides of currentOverrideWeatherObject. + * + * Sits between the weather.js module and the provider implementations to allow us to + * combine the incoming data from the CURRENT_WEATHER_OVERRIDE notification with the + * existing data received from the current api provider. If no notifications have + * been received then the api provider's data is used. + * + * The intent is to allow partial WeatherObjects from local sensors to augment or + * replace the WeatherObjects from the api providers. + * + * This class shares the signature of WeatherProvider, and passes any methods not + * concerning the current weather directly to the api provider implementation that + * is currently in use. + */ +const OverrideWrapper = Class.extend({ + baseProvider: null, + providerName: "localWrapper", + notificationWeatherObject: null, + currentOverrideWeatherObject: null, + + init (baseProvider) { + this.baseProvider = baseProvider; + + // Binding the scope of current weather functions so any fetchData calls with + // setCurrentWeather nested in them call this classes implementation instead + // of the provider's default + this.baseProvider.setCurrentWeather = this.setCurrentWeather.bind(this); + this.baseProvider.currentWeather = this.currentWeather.bind(this); + }, + + /* Unchanged Api Provider Methods */ + + setConfig (config) { + this.baseProvider.setConfig(config); + }, + start () { + this.baseProvider.start(); + }, + fetchCurrentWeather () { + this.baseProvider.fetchCurrentWeather(); + }, + fetchWeatherForecast () { + this.baseProvider.fetchWeatherForecast(); + }, + fetchWeatherHourly () { + this.baseProvider.fetchEatherHourly(); + }, + weatherForecast () { + this.baseProvider.weatherForecast(); + }, + weatherHourly () { + this.baseProvider.weatherHourly(); + }, + fetchedLocation () { + this.baseProvider.fetchedLocation(); + }, + setWeatherForecast (weatherForecastArray) { + this.baseProvider.setWeatherForecast(weatherForecastArray); + }, + setWeatherHourly (weatherHourlyArray) { + this.baseProvider.setWeatherHourly(weatherHourlyArray); + }, + setFetchedLocation (name) { + this.baseProvider.setFetchedLocation(name); + }, + updateAvailable () { + this.baseProvider.updateAvailable(); + }, + async fetchData (url, type = "json", requestHeaders = undefined, expectedResponseHeaders = undefined) { + this.baseProvider.fetchData(url, type, requestHeaders, expectedResponseHeaders); + }, + + /* Override Methods */ + + /** + * Override to return this scope's + * @returns {WeatherObject} The current weather object. May or may not contain overridden data. + */ + currentWeather () { + return this.currentOverrideWeatherObject; + }, + + /** + * Override to combine the overrideWeatherObejct provided in the + * notificationReceived method with the currentOverrideWeatherObject provided by the + * api provider fetchData implementation. + * @param {WeatherObject} currentWeatherObject - the api provider weather object + */ + setCurrentWeather (currentWeatherObject) { + this.currentOverrideWeatherObject = Object.assign(currentWeatherObject, this.notificationWeatherObject); + }, + + /** + * Updates the overrideWeatherObject, calls setCurrentWeather to combine it with + * the existing current weather object provided by the base provider, and signals + * that an update is ready. + * @param {WeatherObject} payload - the weather object received from the CURRENT_WEATHER_OVERRIDE + * notification. Represents information to augment the + * existing currentOverrideWeatherObject with. + */ + notificationReceived (payload) { + this.notificationWeatherObject = payload; + + // setCurrentWeather combines the newly received notification weather with + // the existing weather object we return for current weather + this.setCurrentWeather(this.currentOverrideWeatherObject); + this.updateAvailable(); + } +}); diff --git a/modules/default/weather/providers/darksky.js b/modules/default/weather/providers/pirateweather.js similarity index 70% rename from modules/default/weather/providers/darksky.js rename to modules/default/weather/providers/pirateweather.js index aa48a12bd8..dd20ccf47d 100644 --- a/modules/default/weather/providers/darksky.js +++ b/modules/default/weather/providers/pirateweather.js @@ -1,32 +1,24 @@ /* global WeatherProvider, WeatherObject */ -/* MagicMirror² - * Module: Weather - * Provider: Dark Sky - * - * By Nicholas Hubbard https://github.com/nhubbard - * MIT Licensed - * - * This class is a provider for Dark Sky. - * Note that the Dark Sky API does not provide rainfall. Instead it provides - * snowfall and precipitation probability +/* This class is a provider for Pirate Weather, it is a replacement for Dark Sky (same api), + * see http://pirateweather.net/en/latest/ */ -WeatherProvider.register("darksky", { +WeatherProvider.register("pirateweather", { // Set the name of the provider. // Not strictly required, but helps for debugging. - providerName: "Dark Sky", + providerName: "pirateweather", // Set the default config properties that is specific to this provider defaults: { useCorsProxy: true, - apiBase: "https://api.darksky.net", + apiBase: "https://api.pirateweather.net", weatherEndpoint: "/forecast", apiKey: "", lat: 0, lon: 0 }, - fetchCurrentWeather() { + fetchCurrentWeather () { this.fetchData(this.getUrl()) .then((data) => { if (!data || !data.currently || typeof data.currently.temperature === "undefined") { @@ -43,7 +35,7 @@ WeatherProvider.register("darksky", { .finally(() => this.updateAvailable()); }, - fetchWeatherForecast() { + fetchWeatherForecast () { this.fetchData(this.getUrl()) .then((data) => { if (!data || !data.daily || !data.daily.data.length) { @@ -61,19 +53,19 @@ WeatherProvider.register("darksky", { }, // Create a URL from the config and base URL. - getUrl() { + getUrl () { 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) { + generateWeatherDayFromCurrentWeather (currentWeatherData) { const currentWeather = new WeatherObject(); currentWeather.date = moment(); currentWeather.humidity = parseFloat(currentWeatherData.currently.humidity); currentWeather.temperature = parseFloat(currentWeatherData.currently.temperature); currentWeather.windSpeed = parseFloat(currentWeatherData.currently.windSpeed); - currentWeather.windDirection = currentWeatherData.currently.windBearing; + currentWeather.windFromDirection = currentWeatherData.currently.windBearing; currentWeather.weatherType = this.convertWeatherType(currentWeatherData.currently.icon); currentWeather.sunrise = moment.unix(currentWeatherData.daily.data[0].sunriseTime); currentWeather.sunset = moment.unix(currentWeatherData.daily.data[0].sunsetTime); @@ -81,7 +73,7 @@ WeatherProvider.register("darksky", { return currentWeather; }, - generateWeatherObjectsFromForecast(forecasts) { + generateWeatherObjectsFromForecast (forecasts) { const days = []; for (const forecast of forecasts) { @@ -92,19 +84,21 @@ WeatherProvider.register("darksky", { weather.maxTemperature = forecast.temperatureMax; weather.weatherType = this.convertWeatherType(forecast.icon); weather.snow = 0; + weather.rain = 0; - // The API will return centimeters if units is 'si' and will return inches for 'us' - // Note that the Dark Sky API does not provide rainfall. - // Instead it provides snowfall and precipitation probability + let precip = 0; if (forecast.hasOwnProperty("precipAccumulation")) { - if (this.config.units === "imperial" && !isNaN(forecast.precipAccumulation)) { - weather.snow = forecast.precipAccumulation; - } else if (!isNaN(forecast.precipAccumulation)) { - weather.snow = forecast.precipAccumulation * 10; - } + precip = forecast.precipAccumulation * 10; } - weather.precipitation = weather.snow; + weather.precipitationAmount = precip; + if (forecast.hasOwnProperty("precipType")) { + if (forecast.precipType === "snow") { + weather.snow = precip; + } else { + weather.rain = precip; + } + } days.push(weather); } @@ -112,8 +106,8 @@ WeatherProvider.register("darksky", { return days; }, - // Map icons from Dark Sky to our icons. - convertWeatherType(weatherType) { + // Map icons from Pirate Weather to our icons. + convertWeatherType (weatherType) { const weatherTypes = { "clear-day": "day-sunny", "clear-night": "night-clear", diff --git a/modules/default/weather/providers/smhi.js b/modules/default/weather/providers/smhi.js index c3f51498a0..d7dcdf1b6f 100644 --- a/modules/default/weather/providers/smhi.js +++ b/modules/default/weather/providers/smhi.js @@ -1,14 +1,8 @@ /* global WeatherProvider, WeatherObject */ -/* MagicMirror² - * Module: Weather - * Provider: SMHI - * - * By BuXXi https://github.com/buxxi - * MIT Licensed - * - * This class is a provider for SMHI (Sweden only). Metric system is the only - * supported unit. +/* This class is a provider for SMHI (Sweden only). + * Metric system is the only supported unit, + * see https://www.smhi.se/ */ WeatherProvider.register("smhi", { providerName: "SMHI", @@ -24,7 +18,7 @@ WeatherProvider.register("smhi", { /** * Implements method in interface for fetching current weather. */ - fetchCurrentWeather() { + fetchCurrentWeather () { this.fetchData(this.getURL()) .then((data) => { const closest = this.getClosestToCurrentTime(data.timeSeries); @@ -33,14 +27,14 @@ WeatherProvider.register("smhi", { this.setFetchedLocation(this.config.location || `(${coordinates.lat},${coordinates.lon})`); this.setCurrentWeather(weatherObject); }) - .catch((error) => Log.error("Could not load data: " + error.message)) + .catch((error) => Log.error(`Could not load data: ${error.message}`)) .finally(() => this.updateAvailable()); }, /** * Implements method in interface for fetching a multi-day forecast. */ - fetchWeatherForecast() { + fetchWeatherForecast () { this.fetchData(this.getURL()) .then((data) => { const coordinates = this.resolveCoordinates(data); @@ -48,14 +42,14 @@ WeatherProvider.register("smhi", { this.setFetchedLocation(this.config.location || `(${coordinates.lat},${coordinates.lon})`); this.setWeatherForecast(weatherObjects); }) - .catch((error) => Log.error("Could not load data: " + error.message)) + .catch((error) => Log.error(`Could not load data: ${error.message}`)) .finally(() => this.updateAvailable()); }, /** * Implements method in interface for fetching hourly forecasts. */ - fetchWeatherHourly() { + fetchWeatherHourly () { this.fetchData(this.getURL()) .then((data) => { const coordinates = this.resolveCoordinates(data); @@ -63,30 +57,28 @@ WeatherProvider.register("smhi", { this.setFetchedLocation(this.config.location || `(${coordinates.lat},${coordinates.lon})`); this.setWeatherHourly(weatherObjects); }) - .catch((error) => Log.error("Could not load data: " + error.message)) + .catch((error) => Log.error(`Could not load data: ${error.message}`)) .finally(() => this.updateAvailable()); }, /** * Overrides method for setting config with checks for the precipitationValue being unset or invalid - * * @param {object} config The configuration object */ - setConfig(config) { + setConfig (config) { this.config = config; if (!config.precipitationValue || ["pmin", "pmean", "pmedian", "pmax"].indexOf(config.precipitationValue) === -1) { - Log.log("invalid or not set: " + config.precipitationValue); + Log.log(`invalid or not set: ${config.precipitationValue}`); config.precipitationValue = this.defaults.precipitationValue; } }, /** * Of all the times returned find out which one is closest to the current time, should be the first if the data isn't old. - * * @param {object[]} times Array of time objects * @returns {object} The weatherdata closest to the current time */ - getClosestToCurrentTime(times) { + getClosestToCurrentTime (times) { let now = moment(); let minDiff = undefined; for (const time of times) { @@ -100,10 +92,9 @@ WeatherProvider.register("smhi", { /** * Get the forecast url for the configured coordinates - * * @returns {string} the url for the specified coordinates */ - getURL() { + getURL () { const formatter = new Intl.NumberFormat("en-US", { minimumFractionDigits: 6, maximumFractionDigits: 6 @@ -115,11 +106,10 @@ WeatherProvider.register("smhi", { /** * Calculates the apparent temperature based on known atmospheric data. - * * @param {object} weatherData Weatherdata to use for the calculation * @returns {number} The apparent temperature */ - calculateApparentTemperature(weatherData) { + calculateApparentTemperature (weatherData) { const Ta = this.paramValue(weatherData, "t"); const rh = this.paramValue(weatherData, "r"); const ws = this.paramValue(weatherData, "ws"); @@ -132,12 +122,11 @@ WeatherProvider.register("smhi", { * Converts the returned data into a WeatherObject with required properties set for both current weather and forecast. * The returned units is always in metric system. * Requires coordinates to determine if its daytime or nighttime to know which icon to use and also to set sunrise and sunset. - * * @param {object} weatherData Weatherdata to convert * @param {object} coordinates Coordinates of the locations of the weather * @returns {WeatherObject} The converted weatherdata at the specified location */ - convertWeatherDataToObject(weatherData, coordinates) { + convertWeatherDataToObject (weatherData, coordinates) { let currentWeather = new WeatherObject(); currentWeather.date = moment(weatherData.validTime); @@ -145,7 +134,7 @@ WeatherProvider.register("smhi", { currentWeather.humidity = this.paramValue(weatherData, "r"); currentWeather.temperature = this.paramValue(weatherData, "t"); currentWeather.windSpeed = this.paramValue(weatherData, "ws"); - currentWeather.windDirection = this.paramValue(weatherData, "wd"); + currentWeather.windFromDirection = this.paramValue(weatherData, "wd"); currentWeather.weatherType = this.convertWeatherType(this.paramValue(weatherData, "Wsymb2"), currentWeather.isDayTime()); currentWeather.feelsLikeTemp = this.calculateApparentTemperature(weatherData); @@ -157,19 +146,19 @@ WeatherProvider.register("smhi", { // 0 = No precipitation case 1: // Snow currentWeather.snow += precipitationValue; - currentWeather.precipitation += precipitationValue; + currentWeather.precipitationAmount += precipitationValue; break; case 2: // Snow and rain, treat it as 50/50 snow and rain currentWeather.snow += precipitationValue / 2; currentWeather.rain += precipitationValue / 2; - currentWeather.precipitation += precipitationValue; + currentWeather.precipitationAmount += precipitationValue; break; case 3: // Rain case 4: // Drizzle case 5: // Freezing rain case 6: // Freezing drizzle currentWeather.rain += precipitationValue; - currentWeather.precipitation += precipitationValue; + currentWeather.precipitationAmount += precipitationValue; break; } @@ -178,13 +167,12 @@ WeatherProvider.register("smhi", { /** * 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 * @param {string} groupBy The interval to use for grouping the data (day, hour) * @returns {WeatherObject[]} Array of weatherobjects */ - convertWeatherDataGroupedBy(allWeatherData, coordinates, groupBy = "day") { + convertWeatherDataGroupedBy (allWeatherData, coordinates, groupBy = "day") { let currentWeather; let result = []; @@ -202,7 +190,7 @@ WeatherProvider.register("smhi", { currentWeather.maxTemperature = -Infinity; currentWeather.snow = 0; currentWeather.rain = 0; - currentWeather.precipitation = 0; + currentWeather.precipitationAmount = 0; result.push(currentWeather); } @@ -221,7 +209,7 @@ WeatherProvider.register("smhi", { currentWeather.maxTemperature = Math.max(currentWeather.maxTemperature, weatherObject.temperature); currentWeather.snow += weatherObject.snow; currentWeather.rain += weatherObject.rain; - currentWeather.precipitation += weatherObject.precipitation; + currentWeather.precipitationAmount += weatherObject.precipitationAmount; } return result; @@ -230,22 +218,20 @@ WeatherProvider.register("smhi", { /** * Resolve coordinates from the response data (probably preferably to use * this if it's not matching the config values exactly) - * * @param {object} data Response data from the weather service * @returns {{lon, lat}} the lat/long coordinates of the data */ - resolveCoordinates(data) { + resolveCoordinates (data) { return { lat: data.geometry.coordinates[0][1], lon: data.geometry.coordinates[0][0] }; }, /** * The distance between the data points is increasing in the data the more distant the prediction is. * Find these gaps and fill them with the previous hours data to make the data returned a complete set. - * * @param {object[]} data Response data from the weather service * @returns {object[]} Given data with filled gaps */ - fillInGaps(data) { + fillInGaps (data) { let result = []; for (let i = 1; i < data.length; i++) { let to = moment(data[i].validTime); @@ -263,12 +249,11 @@ WeatherProvider.register("smhi", { /** * Helper method to get a property from the returned data set. - * * @param {object} currentWeatherData Weatherdata to get from * @param {string} name The name of the property * @returns {*} The value of the property in the weatherdata */ - paramValue(currentWeatherData, name) { + paramValue (currentWeatherData, name) { return currentWeatherData.parameters.filter((p) => p.name === name).flatMap((p) => p.values)[0]; }, @@ -276,12 +261,11 @@ WeatherProvider.register("smhi", { * Map the icon value from SMHI to an icon that MagicMirror² understands. * 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 * @param {boolean} isDayTime True if the icon should be for daytime, false for nighttime * @returns {string} The icon name for the MagicMirror */ - convertWeatherType(input, isDayTime) { + convertWeatherType (input, isDayTime) { switch (input) { case 1: return isDayTime ? "day-sunny" : "night-clear"; // Clear sky diff --git a/modules/default/weather/providers/ukmetoffice.js b/modules/default/weather/providers/ukmetoffice.js index d572e53eba..c2db4cda37 100644 --- a/modules/default/weather/providers/ukmetoffice.js +++ b/modules/default/weather/providers/ukmetoffice.js @@ -1,12 +1,7 @@ /* global WeatherProvider, WeatherObject, WeatherUtils */ -/* MagicMirror² - * Module: Weather - * - * By Malcolm Oakes https://github.com/maloakes - * MIT Licensed. - * - * This class is a provider for UK Met Office Datapoint. +/* This class is a provider for UK Met Office Datapoint, + * see https://www.metoffice.gov.uk/ */ WeatherProvider.register("ukmetoffice", { // Set the name of the provider. @@ -22,7 +17,7 @@ WeatherProvider.register("ukmetoffice", { }, // Overwrite the fetchCurrentWeather method. - fetchCurrentWeather() { + fetchCurrentWeather () { this.fetchData(this.getUrl("3hourly")) .then((data) => { if (!data || !data.SiteRep || !data.SiteRep.DV || !data.SiteRep.DV.Location || !data.SiteRep.DV.Location.Period || data.SiteRep.DV.Location.Period.length === 0) { @@ -43,7 +38,7 @@ WeatherProvider.register("ukmetoffice", { }, // Overwrite the fetchCurrentWeather method. - fetchWeatherForecast() { + fetchWeatherForecast () { this.fetchData(this.getUrl("daily")) .then((data) => { if (!data || !data.SiteRep || !data.SiteRep.DV || !data.SiteRep.DV.Location || !data.SiteRep.DV.Location.Period || data.SiteRep.DV.Location.Period.length === 0) { @@ -67,14 +62,14 @@ WeatherProvider.register("ukmetoffice", { /* * Gets the complete url for the request */ - getUrl(forecastType) { + getUrl (forecastType) { return this.config.apiBase + this.config.locationID + this.getParams(forecastType); }, /* * Generate a WeatherObject based on currentWeatherInformation */ - generateWeatherObjectFromCurrentWeather(currentWeatherData) { + generateWeatherObjectFromCurrentWeather (currentWeatherData) { const currentWeather = new WeatherObject(); const location = currentWeatherData.SiteRep.DV.Location; @@ -100,9 +95,9 @@ WeatherProvider.register("ukmetoffice", { currentWeather.humidity = rep.H; currentWeather.temperature = rep.T; currentWeather.feelsLikeTemp = rep.F; - currentWeather.precipitation = parseInt(rep.Pp); + currentWeather.precipitationProbability = parseInt(rep.Pp); currentWeather.windSpeed = WeatherUtils.convertWindToMetric(rep.S); - currentWeather.windDirection = WeatherUtils.convertWindDirection(rep.D); + currentWeather.windFromDirection = WeatherUtils.convertWindDirection(rep.D); currentWeather.weatherType = this.convertWeatherType(rep.W); } } @@ -119,7 +114,7 @@ WeatherProvider.register("ukmetoffice", { /* * Generate WeatherObjects based on forecast information */ - generateWeatherObjectsFromForecast(forecasts) { + generateWeatherObjectsFromForecast (forecasts) { const days = []; // loop round the (5) periods getting the data @@ -138,7 +133,7 @@ WeatherProvider.register("ukmetoffice", { weather.minTemperature = period.Rep[1].Nm; weather.maxTemperature = period.Rep[0].Dm; weather.weatherType = this.convertWeatherType(period.Rep[0].W); - weather.precipitation = parseInt(period.Rep[0].PPd); + weather.precipitationProbability = parseInt(period.Rep[0].PPd); days.push(weather); } @@ -150,7 +145,7 @@ WeatherProvider.register("ukmetoffice", { /* * Convert the Met Office icons to a more usable name. */ - convertWeatherType(weatherType) { + convertWeatherType (weatherType) { const weatherTypes = { 0: "night-clear", 1: "day-sunny", @@ -189,14 +184,13 @@ WeatherProvider.register("ukmetoffice", { /** * Generates an url with api parameters based on the config. - * * @param {string} forecastType daily or 3hourly forecast * @returns {string} url */ - getParams(forecastType) { + getParams (forecastType) { let params = "?"; - params += "res=" + forecastType; - params += "&key=" + this.config.apiKey; + params += `res=${forecastType}`; + params += `&key=${this.config.apiKey}`; return params; } }); diff --git a/modules/default/weather/providers/ukmetofficedatahub.js b/modules/default/weather/providers/ukmetofficedatahub.js index 049f9c4da3..1ca4da5c01 100644 --- a/modules/default/weather/providers/ukmetofficedatahub.js +++ b/modules/default/weather/providers/ukmetofficedatahub.js @@ -1,13 +1,6 @@ /* global WeatherProvider, WeatherObject */ -/* MagicMirror² - * Module: Weather - * - * By Malcolm Oakes https://github.com/maloakes - * Existing Met Office provider edited for new MetOffice Data Hub by CreepinJesus https://github.com/XBCreepinJesus - * MIT Licensed. - * - * This class is a provider for UK Met Office Data Hub (the replacement for their Data Point services). +/* This class is a provider for UK Met Office Data Hub (the replacement for their Data Point services). * For more information on Data Hub, see https://www.metoffice.gov.uk/services/data/datapoint/notifications/weather-datahub * Data available: * Hourly data for next 2 days ("hourly") - https://www.metoffice.gov.uk/binaries/content/assets/metofficegovuk/pdf/data/global-spot-data-hourly.pdf @@ -53,11 +46,11 @@ WeatherProvider.register("ukmetofficedatahub", { }, // Build URL with query strings according to DataHub API (https://metoffice.apiconnect.ibmcloud.com/metoffice/production/api) - getUrl(forecastType) { + getUrl (forecastType) { let queryStrings = "?"; - queryStrings += "latitude=" + this.config.lat; - queryStrings += "&longitude=" + this.config.lon; - queryStrings += "&includeLocationName=" + true; + queryStrings += `latitude=${this.config.lat}`; + queryStrings += `&longitude=${this.config.lon}`; + queryStrings += `&includeLocationName=${true}`; // Return URL, making sure there is a trailing "/" in the base URL. return this.config.apiBase + (this.config.apiBase.endsWith("/") ? "" : "/") + forecastType + queryStrings; @@ -66,7 +59,7 @@ WeatherProvider.register("ukmetofficedatahub", { // Build the list of headers for the request // For DataHub requests, the API key/secret are sent in the headers rather than as query strings. // Headers defined according to Data Hub API (https://metoffice.apiconnect.ibmcloud.com/metoffice/production/api) - getHeaders() { + getHeaders () { return { accept: "application/json", "x-ibm-client-id": this.config.apiKey, @@ -75,7 +68,7 @@ WeatherProvider.register("ukmetofficedatahub", { }, // Fetch data using supplied URL and request headers - async fetchWeather(url, headers) { + async fetchWeather (url, headers) { const response = await fetch(url, { headers: headers }); // Return JSON data @@ -83,7 +76,7 @@ WeatherProvider.register("ukmetofficedatahub", { }, // Fetch hourly forecast data (to use for current weather) - fetchCurrentWeather() { + fetchCurrentWeather () { this.fetchWeather(this.getUrl("hourly"), this.getHeaders()) .then((data) => { // Check data is usable @@ -104,14 +97,14 @@ WeatherProvider.register("ukmetofficedatahub", { }) // Catch any error(s) - .catch((error) => Log.error("Could not load data: " + error.message)) + .catch((error) => Log.error(`Could not load data: ${error.message}`)) // Let the module know there is data available .finally(() => this.updateAvailable()); }, // Create a WeatherObject using current weather data (data for the current hour) - generateWeatherObjectFromCurrentWeather(currentWeatherData) { + generateWeatherObjectFromCurrentWeather (currentWeatherData) { const currentWeather = new WeatherObject(); // Extract the actual forecasts @@ -126,7 +119,7 @@ WeatherProvider.register("ukmetofficedatahub", { if (nowUtc.isSameOrAfter(forecastTime) && nowUtc.isBefore(moment(forecastTime.add(1, "h")))) { currentWeather.date = forecastTime; currentWeather.windSpeed = forecastDataHours[hour].windSpeed10m; - currentWeather.windDirection = forecastDataHours[hour].windDirectionFrom10m; + currentWeather.windFromDirection = forecastDataHours[hour].windDirectionFrom10m; currentWeather.temperature = forecastDataHours[hour].screenTemperature; currentWeather.minTemperature = forecastDataHours[hour].minScreenAirTemp; currentWeather.maxTemperature = forecastDataHours[hour].maxScreenAirTemp; @@ -134,7 +127,7 @@ WeatherProvider.register("ukmetofficedatahub", { currentWeather.humidity = forecastDataHours[hour].screenRelativeHumidity; currentWeather.rain = forecastDataHours[hour].totalPrecipAmount; currentWeather.snow = forecastDataHours[hour].totalSnowAmount; - currentWeather.precipitation = forecastDataHours[hour].probOfPrecipitation; + currentWeather.precipitationProbability = forecastDataHours[hour].probOfPrecipitation; currentWeather.feelsLikeTemp = forecastDataHours[hour].feelsLikeTemperature; // Pass on full details, so they can be used in custom templates @@ -152,7 +145,7 @@ WeatherProvider.register("ukmetofficedatahub", { }, // Fetch daily forecast data - fetchWeatherForecast() { + fetchWeatherForecast () { this.fetchWeather(this.getUrl("daily"), this.getHeaders()) .then((data) => { // Check data is usable @@ -173,14 +166,14 @@ WeatherProvider.register("ukmetofficedatahub", { }) // Catch any error(s) - .catch((error) => Log.error("Could not load data: " + error.message)) + .catch((error) => Log.error(`Could not load data: ${error.message}`)) // Let the module know there is new data available .finally(() => this.updateAvailable()); }, // Create a WeatherObject for each day using daily forecast data - generateWeatherObjectsFromForecast(forecasts) { + generateWeatherObjectsFromForecast (forecasts) { const dailyForecasts = []; // Extract the actual forecasts @@ -204,9 +197,9 @@ WeatherProvider.register("ukmetofficedatahub", { // Using daytime forecast values forecastWeather.windSpeed = forecastDataDays[day].midday10MWindSpeed; - forecastWeather.windDirection = forecastDataDays[day].midday10MWindDirection; + forecastWeather.windFromDirection = forecastDataDays[day].midday10MWindDirection; forecastWeather.weatherType = this.convertWeatherType(forecastDataDays[day].daySignificantWeatherCode); - forecastWeather.precipitation = forecastDataDays[day].dayProbabilityOfPrecipitation; + forecastWeather.precipitationProbability = forecastDataDays[day].dayProbabilityOfPrecipitation; forecastWeather.temperature = forecastDataDays[day].dayMaxScreenTemperature; forecastWeather.humidity = forecastDataDays[day].middayRelativeHumidity; forecastWeather.rain = forecastDataDays[day].dayProbabilityOfRain; @@ -225,14 +218,14 @@ WeatherProvider.register("ukmetofficedatahub", { }, // Set the fetched location name. - setFetchedLocation: function (name) { + setFetchedLocation (name) { this.fetchedLocationName = name; }, // 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/ - convertWeatherType(weatherType) { + convertWeatherType (weatherType) { const weatherTypes = { 0: "night-clear", 1: "day-sunny", diff --git a/modules/default/weather/providers/weatherbit.js b/modules/default/weather/providers/weatherbit.js index 75f49a6984..7c01f5d6be 100644 --- a/modules/default/weather/providers/weatherbit.js +++ b/modules/default/weather/providers/weatherbit.js @@ -1,14 +1,7 @@ /* global WeatherProvider, WeatherObject */ -/* MagicMirror² - * Module: Weather - * Provider: Weatherbit - * - * By Andrew Pometti - * MIT Licensed - * - * This class is a provider for Weatherbit, based on Nicholas Hubbard's class - * for Dark Sky & Vince Peri's class for Weather.gov. +/* This class is a provider for Weatherbit, + * see https://www.weatherbit.io/ */ WeatherProvider.register("weatherbit", { // Set the name of the provider. @@ -23,11 +16,11 @@ WeatherProvider.register("weatherbit", { lon: 0 }, - fetchedLocation: function () { + fetchedLocation () { return this.fetchedLocationName || ""; }, - fetchCurrentWeather() { + fetchCurrentWeather () { this.fetchData(this.getUrl()) .then((data) => { if (!data || !data.data[0] || typeof data.data[0].temp === "undefined") { @@ -44,7 +37,7 @@ WeatherProvider.register("weatherbit", { .finally(() => this.updateAvailable()); }, - fetchWeatherForecast() { + fetchWeatherForecast () { this.fetchData(this.getUrl()) .then((data) => { if (!data || !data.data) { @@ -55,7 +48,7 @@ WeatherProvider.register("weatherbit", { const forecast = this.generateWeatherObjectsFromForecast(data.data); this.setWeatherForecast(forecast); - this.fetchedLocationName = data.city_name + ", " + data.state_code; + this.fetchedLocationName = `${data.city_name}, ${data.state_code}`; }) .catch(function (request) { Log.error("Could not load data ... ", request); @@ -65,10 +58,9 @@ WeatherProvider.register("weatherbit", { /** * Overrides method for setting config to check if endpoint is correct for hourly - * * @param {object} config The configuration object */ - setConfig(config) { + setConfig (config) { this.config = config; if (!this.config.weatherEndpoint) { switch (this.config.type) { @@ -89,12 +81,12 @@ WeatherProvider.register("weatherbit", { }, // Create a URL from the config and base URL. - getUrl() { + getUrl () { return `${this.config.apiBase}${this.config.weatherEndpoint}?lat=${this.config.lat}&lon=${this.config.lon}&units=M&key=${this.config.apiKey}`; }, // Implement WeatherDay generator. - generateWeatherDayFromCurrentWeather(currentWeatherData) { + generateWeatherDayFromCurrentWeather (currentWeatherData) { //Calculate TZ Offset and invert to convert Sunrise/Sunset times to Local const d = new Date(); let tzOffset = d.getTimezoneOffset(); @@ -106,17 +98,17 @@ WeatherProvider.register("weatherbit", { currentWeather.humidity = parseFloat(currentWeatherData.data[0].rh); currentWeather.temperature = parseFloat(currentWeatherData.data[0].temp); currentWeather.windSpeed = parseFloat(currentWeatherData.data[0].wind_spd); - currentWeather.windDirection = currentWeatherData.data[0].wind_dir; + currentWeather.windFromDirection = currentWeatherData.data[0].wind_dir; currentWeather.weatherType = this.convertWeatherType(currentWeatherData.data[0].weather.icon); currentWeather.sunrise = moment(currentWeatherData.data[0].sunrise, "HH:mm").add(tzOffset, "m"); currentWeather.sunset = moment(currentWeatherData.data[0].sunset, "HH:mm").add(tzOffset, "m"); - this.fetchedLocationName = currentWeatherData.data[0].city_name + ", " + currentWeatherData.data[0].state_code; + this.fetchedLocationName = `${currentWeatherData.data[0].city_name}, ${currentWeatherData.data[0].state_code}`; return currentWeather; }, - generateWeatherObjectsFromForecast(forecasts) { + generateWeatherObjectsFromForecast (forecasts) { const days = []; for (const forecast of forecasts) { @@ -125,7 +117,8 @@ WeatherProvider.register("weatherbit", { weather.date = moment(forecast.datetime, "YYYY-MM-DD"); weather.minTemperature = forecast.min_temp; weather.maxTemperature = forecast.max_temp; - weather.precipitation = forecast.precip; + weather.precipitationAmount = forecast.precip; + weather.precipitationProbability = forecast.pop; weather.weatherType = this.convertWeatherType(forecast.weather.icon); days.push(weather); @@ -135,7 +128,7 @@ WeatherProvider.register("weatherbit", { }, // Map icons from Dark Sky to our icons. - convertWeatherType(weatherType) { + convertWeatherType (weatherType) { const weatherTypes = { t01d: "day-thunderstorm", t01n: "night-alt-thunderstorm", diff --git a/modules/default/weather/providers/weatherflow.js b/modules/default/weather/providers/weatherflow.js index d15023b5ab..54066d7b40 100644 --- a/modules/default/weather/providers/weatherflow.js +++ b/modules/default/weather/providers/weatherflow.js @@ -1,16 +1,8 @@ /* global WeatherProvider, WeatherObject, WeatherUtils */ -/* MagicMirror² - * Module: Weather - * Provider: Weatherflow - * - * By Tobias Dreyem https://github.com/10bias - * MIT Licensed - * - * This class is a provider for Weatherflow. +/* This class is a provider for Weatherflow. * Note that the Weatherflow API does not provide snowfall. */ - WeatherProvider.register("weatherflow", { // Set the name of the provider. // Not strictly required, but helps for debugging @@ -23,7 +15,7 @@ WeatherProvider.register("weatherflow", { stationid: "" }, - fetchCurrentWeather() { + fetchCurrentWeather () { this.fetchData(this.getUrl()) .then((data) => { const currentWeather = new WeatherObject(); @@ -32,7 +24,7 @@ WeatherProvider.register("weatherflow", { currentWeather.humidity = data.current_conditions.relative_humidity; currentWeather.temperature = data.current_conditions.air_temperature; currentWeather.windSpeed = WeatherUtils.convertWindToMs(data.current_conditions.wind_avg); - currentWeather.windDirection = data.current_conditions.wind_direction; + currentWeather.windFromDirection = data.current_conditions.wind_direction; currentWeather.weatherType = data.forecast.daily[0].icon; currentWeather.sunrise = moment.unix(data.forecast.daily[0].sunrise); currentWeather.sunset = moment.unix(data.forecast.daily[0].sunset); @@ -44,7 +36,7 @@ WeatherProvider.register("weatherflow", { .finally(() => this.updateAvailable()); }, - fetchWeatherForecast() { + fetchWeatherForecast () { this.fetchData(this.getUrl()) .then((data) => { const days = []; @@ -55,6 +47,7 @@ WeatherProvider.register("weatherflow", { weather.date = moment.unix(forecast.day_start_local); weather.minTemperature = forecast.air_temp_low; weather.maxTemperature = forecast.air_temp_high; + weather.precipitationProbability = forecast.precip_probability; weather.weatherType = forecast.icon; weather.snow = 0; @@ -70,7 +63,7 @@ WeatherProvider.register("weatherflow", { }, // Create a URL from the config and base URL. - getUrl() { + getUrl () { 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 19ce22e313..3c16bd7344 100644 --- a/modules/default/weather/providers/weathergov.js +++ b/modules/default/weather/providers/weathergov.js @@ -1,13 +1,8 @@ /* global WeatherProvider, WeatherObject, WeatherUtils */ -/* MagicMirror² - * Module: Weather - * Provider: weather.gov +/* Provider: weather.gov * https://weather-gov.github.io/api/general-faqs * - * Original by Vince Peri - * MIT Licensed. - * * This class is a provider for weather.gov. * Note that this is only for US locations (lat and lon) and does not require an API key * Since it is free, there are some items missing - like sunrise, sunset @@ -37,24 +32,23 @@ WeatherProvider.register("weathergov", { stationObsURL: "tbd", // Called to set the config, this config is the same as the weather module's config. - setConfig: function (config) { + setConfig (config) { this.config = config; - this.config.apiBase = "https://api.weather.gov"; this.fetchWxGovURLs(this.config); }, // Called when the weather provider is about to start. - start: function () { + start () { Log.info(`Weather provider: ${this.providerName} started.`); }, // This returns the name of the fetched location or an empty string. - fetchedLocation: function () { + fetchedLocation () { return this.fetchedLocationName || ""; }, // Overwrite the fetchCurrentWeather method. - fetchCurrentWeather() { + fetchCurrentWeather () { if (!this.configURLs) { Log.info("fetchCurrentWeather: fetch wx waiting on config URLs"); return; @@ -75,7 +69,7 @@ WeatherProvider.register("weathergov", { }, // Overwrite the fetchWeatherForecast method. - fetchWeatherForecast() { + fetchWeatherForecast () { if (!this.configURLs) { Log.info("fetchWeatherForecast: fetch wx waiting on config URLs"); return; @@ -96,7 +90,7 @@ WeatherProvider.register("weathergov", { }, // Overwrite the fetchWeatherHourly method. - fetchWeatherHourly() { + fetchWeatherHourly () { if (!this.configURLs) { Log.info("fetchWeatherHourly: fetch wx waiting on config URLs"); return; @@ -122,17 +116,17 @@ WeatherProvider.register("weathergov", { /* * Get specific URLs */ - fetchWxGovURLs(config) { - this.fetchData(`${config.apiBase}/points/${config.lat},${config.lon}`) + fetchWxGovURLs (config) { + this.fetchData(`${config.apiBase}/${config.lat},${config.lon}`) .then((data) => { if (!data || !data.properties) { // points URL did not respond with usable data. return; } - this.fetchedLocationName = data.properties.relativeLocation.properties.city + ", " + data.properties.relativeLocation.properties.state; - Log.log("Forecast location is " + this.fetchedLocationName); - this.forecastURL = data.properties.forecast + "?units=si"; - this.forecastHourlyURL = data.properties.forecastHourly + "?units=si"; + this.fetchedLocationName = `${data.properties.relativeLocation.properties.city}, ${data.properties.relativeLocation.properties.state}`; + Log.log(`Forecast location is ${this.fetchedLocationName}`); + this.forecastURL = `${data.properties.forecast}?units=si`; + this.forecastHourlyURL = `${data.properties.forecastHourly}?units=si`; this.forecastGridDataURL = data.properties.forecastGridData; this.observationStationsURL = data.properties.observationStations; // with this URL, we chain another promise for the station obs URL @@ -143,7 +137,7 @@ WeatherProvider.register("weathergov", { // obs station URL did not respond with usable data. return; } - this.stationObsURL = obsData.features[0].id + "/observations/latest"; + this.stationObsURL = `${obsData.features[0].id}/observations/latest`; }) .catch((err) => { Log.error(err); @@ -162,12 +156,13 @@ WeatherProvider.register("weathergov", { } }); }, + /* * 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) { + generateWeatherObjectsFromHourly (forecasts) { const days = []; // variable for date @@ -179,9 +174,15 @@ WeatherProvider.register("weathergov", { } else { weather.windSpeed = forecast.windSpeed.slice(0, forecast.windSpeed.search(" ")); } - weather.windDirection = this.convertWindDirection(forecast.windDirection); + weather.windSpeed = WeatherUtils.convertWindToMs(weather.windSpeed); + weather.windFromDirection = forecast.windDirection; weather.temperature = forecast.temperature; - weather.tempUnits = forecast.temperatureUnit; + //assign probability of precipitation + if (forecast.probabilityOfPrecipitation.value === null) { + weather.precipitationProbability = 0; + } else { + weather.precipitationProbability = forecast.probabilityOfPrecipitation.value; + } // use the forecast isDayTime attribute to help build the weatherType label weather.weatherType = this.convertWeatherType(forecast.shortForecast, forecast.isDaytime); @@ -200,19 +201,17 @@ WeatherProvider.register("weathergov", { * Weather.gov API uses specific units; API does not include choice of units * ... object needs data in units based on config! */ - generateWeatherObjectFromCurrentWeather(currentWeatherData) { + generateWeatherObjectFromCurrentWeather (currentWeatherData) { const currentWeather = new WeatherObject(); currentWeather.date = moment(currentWeatherData.timestamp); currentWeather.temperature = currentWeatherData.temperature.value; currentWeather.windSpeed = WeatherUtils.convertWindToMs(currentWeatherData.windSpeed.value); - currentWeather.windDirection = currentWeatherData.windDirection.value; + currentWeather.windFromDirection = currentWeatherData.windDirection.value; currentWeather.minTemperature = currentWeatherData.minTemperatureLast24Hours.value; currentWeather.maxTemperature = currentWeatherData.maxTemperatureLast24Hours.value; currentWeather.humidity = Math.round(currentWeatherData.relativeHumidity.value); - currentWeather.rain = null; - currentWeather.snow = null; - currentWeather.precipitation = this.convertLength(currentWeatherData.precipitationLastHour.value); + currentWeather.precipitationAmount = currentWeatherData.precipitationLastHour.value; if (currentWeatherData.heatIndex.value !== null) { currentWeather.feelsLikeTemp = currentWeatherData.heatIndex.value; } else if (currentWeatherData.windChill.value !== null) { @@ -232,14 +231,14 @@ WeatherProvider.register("weathergov", { /* * Generate WeatherObjects based on forecast information */ - generateWeatherObjectsFromForecast(forecasts) { + generateWeatherObjectsFromForecast (forecasts) { return this.fetchForecastDaily(forecasts); }, /* * fetch forecast information for daily forecast. */ - fetchForecastDaily(forecasts) { + fetchForecastDaily (forecasts) { // initial variable declaration const days = []; // variables for temperature range and rain @@ -248,7 +247,6 @@ WeatherProvider.register("weathergov", { // variable for date let date = ""; let weather = new WeatherObject(); - weather.precipitation = 0; for (const forecast of forecasts) { if (date !== moment(forecast.startTime).format("YYYY-MM-DD")) { @@ -263,7 +261,12 @@ WeatherProvider.register("weathergov", { minTemp = []; maxTemp = []; - weather.precipitation = 0; + //assign probability of precipitation + if (forecast.probabilityOfPrecipitation.value === null) { + weather.precipitationProbability = 0; + } else { + weather.precipitationProbability = forecast.probabilityOfPrecipitation.value; + } // set new date date = moment(forecast.startTime).format("YYYY-MM-DD"); @@ -295,22 +298,10 @@ WeatherProvider.register("weathergov", { return days.slice(1); }, - /* - * Unit conversions - */ - // conversion to inches - convertLength(meters) { - if (this.config.units === "imperial") { - return meters * 39.3701; - } else { - return meters; - } - }, - /* * Convert the icons to a more usable name. */ - convertWeatherType(weatherType, isDaytime) { + convertWeatherType (weatherType, isDaytime) { //https://w1.weather.gov/xml/current_obs/weather.php // There are way too many types to create, so lets just look for certain strings diff --git a/modules/default/weather/providers/yr.js b/modules/default/weather/providers/yr.js index cc21611be3..35493a1653 100644 --- a/modules/default/weather/providers/yr.js +++ b/modules/default/weather/providers/yr.js @@ -1,14 +1,6 @@ /* 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. - * +/* This class is a provider for Yr.no, a norwegian weather service. * Terms of service: https://developer.yr.no/doc/TermsOfService/ */ WeatherProvider.register("yr", { @@ -18,11 +10,13 @@ WeatherProvider.register("yr", { defaults: { useCorsProxy: true, apiBase: "https://api.met.no/weatherapi", + forecastApiVersion: "2.0", + sunriseApiVersion: "3.0", altitude: 0, currentForecastHours: 1 //1, 6 or 12 }, - start() { + start () { if (typeof Storage === "undefined") { //local storage unavailable Log.error("The Yr weather provider requires local storage."); @@ -31,7 +25,7 @@ WeatherProvider.register("yr", { Log.info(`Weather provider: ${this.providerName} started.`); }, - fetchCurrentWeather() { + fetchCurrentWeather () { this.getCurrentWeather() .then((currentWeather) => { this.setCurrentWeather(currentWeather); @@ -43,11 +37,10 @@ WeatherProvider.register("yr", { }); }, - async getCurrentWeather() { - const getRequests = [this.getWeatherData(), this.getStellarData()]; - const [weatherData, stellarData] = await Promise.all(getRequests); + async getCurrentWeather () { + const [weatherData, stellarData] = await Promise.all([this.getWeatherData(), this.getStellarData()]); if (!stellarData) { - Log.warn("No stelar data available."); + Log.warn("No stellar data available."); } if (!weatherData.properties.timeseries || !weatherData.properties.timeseries[0]) { Log.error("No weather data available."); @@ -65,13 +58,14 @@ WeatherProvider.register("yr", { } const forecastXHours = this.getForecastForXHoursFrom(forecast.data); forecast.weatherType = this.convertWeatherType(forecastXHours.summary.symbol_code, forecast.time); - forecast.precipitation = forecastXHours.details?.precipitation_amount; + forecast.precipitationAmount = forecastXHours.details?.precipitation_amount; + forecast.precipitationProbability = forecastXHours.details?.probability_of_precipitation; forecast.minTemperature = forecastXHours.details?.air_temperature_min; forecast.maxTemperature = forecastXHours.details?.air_temperature_max; return this.getWeatherDataFrom(forecast, stellarData, weatherData.properties.meta.units); }, - getWeatherData() { + 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. @@ -97,7 +91,7 @@ WeatherProvider.register("yr", { }); }, - getWeatherDataFromYrOrCache(resolve, reject) { + getWeatherDataFromYrOrCache (resolve, reject) { localStorage.setItem("yrIsFetchingWeatherData", "true"); let weatherData = this.getWeatherDataFromCache(); @@ -109,13 +103,15 @@ WeatherProvider.register("yr", { this.getWeatherDataFromYr(weatherData?.downloadedAt) .then((weatherData) => { Log.debug("Got weather data from yr."); + let data; if (weatherData) { this.cacheWeatherData(weatherData); + data = weatherData; } else { //Undefined if unchanged - weatherData = this.getWeatherDataFromCache(); + data = this.getWeatherDataFromCache(); } - resolve(weatherData); + resolve(data); }) .catch((err) => { Log.error(err); @@ -127,16 +123,16 @@ WeatherProvider.register("yr", { } }, - weatherDataIsValid(weatherData) { + 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)) + 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() { + getWeatherDataFromCache () { const weatherData = localStorage.getItem("weatherData"); if (weatherData) { return JSON.parse(weatherData); @@ -145,7 +141,7 @@ WeatherProvider.register("yr", { } }, - getWeatherDataFromYr(currentDataFetchedAt) { + getWeatherDataFromYr (currentDataFetchedAt) { const requestHeaders = [{ name: "Accept", value: "application/json" }]; if (currentDataFetchedAt) { requestHeaders.push({ name: "If-Modified-Since", value: currentDataFetchedAt }); @@ -167,7 +163,7 @@ WeatherProvider.register("yr", { }); }, - getForecastUrl() { + getConfigOptions () { if (!this.config.lat) { Log.error("Latitude not provided."); throw new Error("Latitude not provided."); @@ -180,6 +176,11 @@ WeatherProvider.register("yr", { let lat = this.config.lat.toString(); let lon = this.config.lon.toString(); const altitude = this.config.altitude ?? 0; + return { lat, lon, altitude }; + }, + + getForecastUrl () { + let { lat, lon, altitude } = this.getConfigOptions(); 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."); @@ -192,19 +193,14 @@ WeatherProvider.register("yr", { lon = `${lonParts[0]}.${lonParts[1].substring(0, 4)}`; } - return `${this.config.apiBase}/locationforecast/2.0/complete?&altitude=${altitude}&lat=${lat}&lon=${lon}`; + return `${this.config.apiBase}/locationforecast/${this.config.forecastApiVersion}/complete?&altitude=${altitude}&lat=${lat}&lon=${lon}`; }, - cacheWeatherData(weatherData) { + 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() { + 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) => { @@ -230,7 +226,7 @@ WeatherProvider.register("yr", { }); }, - getStellarDataFromYrOrCache(resolve, reject) { + getStellarDataFromYrOrCache (resolve, reject) { localStorage.setItem("yrIsFetchingStellarData", "true"); let stellarData = this.getStellarDataFromCache(); @@ -251,12 +247,12 @@ WeatherProvider.register("yr", { this.cacheStellarData(stellarData); resolve(stellarData); } else { - reject("No stellar data returned from Yr for " + tomorrow); + reject(`No stellar data returned from Yr for ${tomorrow}`); } }) .catch((err) => { Log.error(err); - reject("Unable to get stellar data from Yr for " + tomorrow); + reject(`Unable to get stellar data from Yr for ${tomorrow}`); }) .finally(() => { localStorage.removeItem("yrIsFetchingStellarData"); @@ -265,16 +261,16 @@ WeatherProvider.register("yr", { this.getStellarDataFromYr(today, 2) .then((stellarData) => { if (stellarData) { - stellarData = { + const data = { today: stellarData }; - stellarData.tomorrow = Object.assign({}, stellarData.today); - stellarData.today.date = today; - stellarData.tomorrow.date = tomorrow; - this.cacheStellarData(stellarData); - resolve(stellarData); + data.tomorrow = Object.assign({}, data.today); + data.today.date = today; + data.tomorrow.date = tomorrow; + this.cacheStellarData(data); + resolve(data); } else { - Log.error("Something went wrong when fetching stellar data. Responses: " + stellarData); + Log.error(`Something went wrong when fetching stellar data. Responses: ${stellarData}`); reject(stellarData); } }) @@ -288,7 +284,7 @@ WeatherProvider.register("yr", { } }, - getStellarDataFromCache() { + getStellarDataFromCache () { const stellarData = localStorage.getItem("stellarData"); if (stellarData) { return JSON.parse(stellarData); @@ -297,9 +293,9 @@ WeatherProvider.register("yr", { } }, - getStellarDataFromYr(date, days = 1) { + getStellarDataFromYr (date, days = 1) { const requestHeaders = [{ name: "Accept", value: "application/json" }]; - return this.fetchData(this.getStellarDatatUrl(date, days), "json", requestHeaders) + return this.fetchData(this.getStellarDataUrl(date, days), "json", requestHeaders) .then((data) => { Log.debug("Got stellar data from yr."); return data; @@ -310,19 +306,8 @@ WeatherProvider.register("yr", { }); }, - 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; + getStellarDataUrl (date, days) { + let { lat, lon, altitude } = this.getConfigOptions(); 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."); @@ -349,39 +334,35 @@ WeatherProvider.register("yr", { 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}`; + return `${this.config.apiBase}/sunrise/${this.config.sunriseApiVersion}/sun?lat=${lat}&lon=${lon}&date=${date}&offset=${utcOffsetPrefix}${hours}%3A${minutes}`; }, - cacheStellarData(data) { + 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; + getWeatherDataFrom (forecast, stellarData, units) { + const weather = new WeatherObject(); weather.date = moment(forecast.time); weather.windSpeed = forecast.data.instant.details.wind_speed; - weather.windDirection = (forecast.data.instant.details.wind_from_direction + 180) % 360; + weather.windFromDirection = forecast.data.instant.details.wind_from_direction; weather.temperature = forecast.data.instant.details.air_temperature; weather.minTemperature = forecast.minTemperature; weather.maxTemperature = forecast.maxTemperature; weather.weatherType = forecast.weatherType; weather.humidity = forecast.data.instant.details.relative_humidity; - weather.precipitation = forecast.precipitation; + weather.precipitationAmount = forecast.precipitationAmount; + weather.precipitationProbability = forecast.precipitationProbability; weather.precipitationUnits = units.precipitation_amount; - if (stellarTimesToday) { - weather.sunset = moment(stellarTimesToday.sunset.time); - weather.sunrise = weather.sunset < moment() && stellarTimesTomorrow ? moment(stellarTimesTomorrow.sunrise.time) : moment(stellarTimesToday.sunrise.time); - } + weather.sunrise = stellarData?.today?.properties?.sunrise?.time; + weather.sunset = stellarData?.today?.properties?.sunset?.time; return weather; }, - convertWeatherType(weatherType, weatherTime) { + convertWeatherType (weatherType, weatherTime) { const weatherHour = moment(weatherTime).format("HH"); const weatherTypes = { @@ -473,16 +454,7 @@ WeatherProvider.register("yr", { 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) { + getForecastForXHoursFrom (weather) { if (this.config.currentForecastHours === 1) { if (weather.next_1_hours) { return weather.next_1_hours; @@ -510,7 +482,7 @@ WeatherProvider.register("yr", { } }, - fetchWeatherHourly() { + fetchWeatherHourly () { this.getWeatherForecast("hourly") .then((forecast) => { this.setWeatherHourly(forecast); @@ -522,15 +494,14 @@ WeatherProvider.register("yr", { }); }, - async getWeatherForecast(type) { - const getRequests = [this.getWeatherData(), this.getStellarData()]; - const [weatherData, stellarData] = await Promise.all(getRequests); + async getWeatherForecast (type) { + const [weatherData, stellarData] = await Promise.all([this.getWeatherData(), this.getStellarData()]); if (!weatherData.properties.timeseries || !weatherData.properties.timeseries[0]) { Log.error("No weather data available."); return; } if (!stellarData) { - Log.warn("No stelar data available."); + Log.warn("No stellar data available."); } let forecasts; switch (type) { @@ -549,12 +520,13 @@ WeatherProvider.register("yr", { return series; }, - getHourlyForecastFrom(weatherData) { + 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.precipitationAmount = forecast.data.next_1_hours?.details?.precipitation_amount; + forecast.precipitationProbability = forecast.data.next_1_hours?.details?.probability_of_precipitation; forecast.minTemperature = forecast.data.next_1_hours?.details?.air_temperature_min; forecast.maxTemperature = forecast.data.next_1_hours?.details?.air_temperature_max; forecast.weatherType = this.convertWeatherType(forecast.symbol, forecast.time); @@ -563,7 +535,7 @@ WeatherProvider.register("yr", { return series; }, - getDailyForecastFrom(weatherData) { + getDailyForecastFrom (weatherData) { const series = []; const days = weatherData.properties.timeseries.reduce(function (days, forecast) { @@ -573,7 +545,7 @@ WeatherProvider.register("yr", { return days; }, Object.create(null)); - Object.keys(days).forEach(function (time, index) { + Object.keys(days).forEach(function (time) { let minTemperature = undefined; let maxTemperature = undefined; @@ -599,7 +571,8 @@ WeatherProvider.register("yr", { const forecastXHours = forecast.data.next_12_hours ?? forecast.data.next_6_hours ?? forecast.data.next_1_hours; if (forecastXHours) { forecast.symbol = forecastXHours.summary?.symbol_code; - forecast.precipitation = forecastXHours.details?.precipitation_amount; + forecast.precipitationAmount = forecastXHours.details?.precipitation_amount ?? forecast.data.next_6_hours?.details?.precipitation_amount; // 6 hours is likely to have precipitation amount even if 12 hours does not + forecast.precipitationProbability = forecastXHours.details?.probability_of_precipitation; forecast.minTemperature = minTemperature; forecast.maxTemperature = maxTemperature; @@ -612,7 +585,7 @@ WeatherProvider.register("yr", { return series; }, - fetchWeatherForecast() { + fetchWeatherForecast () { this.getWeatherForecast("daily") .then((forecast) => { this.setWeatherForecast(forecast); diff --git a/modules/default/weather/weather.css b/modules/default/weather/weather.css index 2d7600ad17..816f0a9b74 100644 --- a/modules/default/weather/weather.css +++ b/modules/default/weather/weather.css @@ -6,7 +6,7 @@ transform: translate(0, -3px); } -.weather .humidityIcon { +.weather .humidity-icon { padding-right: 4px; } @@ -29,7 +29,9 @@ padding-right: 0; } -.weather .precipitation { +.weather .precipitation-amount, +.weather .precipitation-prob, +.weather .uv-index { padding-left: 20px; padding-right: 0; } diff --git a/modules/default/weather/weather.js b/modules/default/weather/weather.js index ab989f96ab..224aba0647 100644 --- a/modules/default/weather/weather.js +++ b/modules/default/weather/weather.js @@ -1,34 +1,33 @@ -/* global WeatherProvider, WeatherUtils */ +/* global WeatherProvider, WeatherUtils, formatTime */ -/* MagicMirror² - * Module: Weather - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. - */ Module.register("weather", { // Default module config. defaults: { weatherProvider: "openweathermap", roundTemp: false, type: "current", // current, forecast, daily (equivalent to forecast), hourly (only with OpenWeatherMap /onecall endpoint) + lang: config.language, units: config.units, tempUnits: config.units, windUnits: config.units, + timeFormat: config.timeFormat, updateInterval: 10 * 60 * 1000, // every 10 minutes animationSpeed: 1000, - timeFormat: config.timeFormat, + showFeelsLike: true, + showHumidity: "none", // this is now a string; see current.njk + showIndoorHumidity: false, + showIndoorTemperature: false, + allowOverrideNotification: false, showPeriod: true, showPeriodUpper: false, + showPrecipitationAmount: false, + showPrecipitationProbability: false, + showUVIndex: false, + showSun: true, showWindDirection: true, showWindDirectionAsArrow: false, - lang: config.language, - showHumidity: false, - showSun: true, degreeLabel: false, decimalSymbol: ".", - showIndoorTemperature: false, - showIndoorHumidity: false, maxNumberOfDays: 5, maxEntries: 5, ignoreToday: false, @@ -39,10 +38,9 @@ Module.register("weather", { calendarClass: "calendar", tableClass: "small", onlyTemp: false, - showPrecipitationAmount: false, colored: false, - showFeelsLike: true, - absoluteDates: false + absoluteDates: false, + hourlyForecastIncrements: 1 }, // Module properties. @@ -52,19 +50,19 @@ Module.register("weather", { firstEvent: null, // Define required scripts. - getStyles: function () { + getStyles () { return ["font-awesome.css", "weather-icons.css", "weather.css"]; }, // Return the scripts that are necessary for the weather module. - getScripts: function () { - return ["moment.js", this.file("../utils.js"), "weatherutils.js", "weatherprovider.js", "weatherobject.js", "suncalc.js", this.file("providers/" + this.config.weatherProvider.toLowerCase() + ".js")]; + getScripts () { + return ["moment.js", "weatherutils.js", "weatherobject.js", this.file("providers/overrideWrapper.js"), "weatherprovider.js", "suncalc.js", this.file(`providers/${this.config.weatherProvider.toLowerCase()}.js`)]; }, // Override getHeader method. - getHeader: function () { + getHeader () { if (this.config.appendLocationNameToHeader && this.weatherProvider) { - if (this.data.header) return this.data.header + " " + this.weatherProvider.fetchedLocation(); + if (this.data.header) return `${this.data.header} ${this.weatherProvider.fetchedLocation()}`; else return this.weatherProvider.fetchedLocation(); } @@ -72,7 +70,7 @@ Module.register("weather", { }, // Start the weather module. - start: function () { + start () { moment.locale(this.config.lang); if (this.config.useKmh) { @@ -82,6 +80,10 @@ Module.register("weather", { Log.warn("Your are using the deprecated config values 'useBeaufort'. Please switch to windUnits!"); this.windUnits = "beaufort"; } + if (typeof this.config.showHumidity === "boolean") { + Log.warn("[weather] Deprecation warning: Please consider updating showHumidity to the new style (config string)."); + this.config.showHumidity = this.config.showHumidity ? "wind" : "none"; + } // Initialize the weather provider. this.weatherProvider = WeatherProvider.initialize(this.config.weatherProvider, this); @@ -97,7 +99,7 @@ Module.register("weather", { }, // Override notification handler. - notificationReceived: function (notification, payload, sender) { + notificationReceived (notification, payload, sender) { if (notification === "CALENDAR_EVENTS") { const senderClasses = sender.data.classes.toLowerCase().split(" "); if (senderClasses.indexOf(this.config.calendarClass.toLowerCase()) !== -1) { @@ -116,11 +118,13 @@ Module.register("weather", { } else if (notification === "INDOOR_HUMIDITY") { this.indoorHumidity = this.roundValue(payload); this.updateDom(300); + } else if (notification === "CURRENT_WEATHER_OVERRIDE" && this.config.allowOverrideNotification) { + this.weatherProvider.notificationReceived(payload); } }, // Select the template depending on the display type. - getTemplate: function () { + getTemplate () { switch (this.config.type.toLowerCase()) { case "current": return "current.njk"; @@ -136,14 +140,18 @@ Module.register("weather", { }, // Add all the data to the template. - getTemplateData: function () { - const forecast = this.weatherProvider.weatherForecast(); + getTemplateData () { + const currentData = this.weatherProvider.currentWeather(); + const forecastData = this.weatherProvider.weatherForecast(); + + // Skip some hourly forecast entries if configured + const hourlyData = this.weatherProvider.weatherHourly()?.filter((e, i) => (i + 1) % this.config.hourlyForecastIncrements === this.config.hourlyForecastIncrements - 1); return { config: this.config, - current: this.weatherProvider.currentWeather(), - forecast: forecast, - hourly: this.weatherProvider.weatherHourly(), + current: currentData, + forecast: forecastData, + hourly: hourlyData, indoor: { humidity: this.indoorHumidity, temperature: this.indoorTemperature @@ -152,7 +160,7 @@ Module.register("weather", { }, // What to do when the weather provider has new information available? - updateAvailable: function () { + updateAvailable () { Log.log("New weather information available."); this.updateDom(0); this.scheduleUpdate(); @@ -171,7 +179,7 @@ Module.register("weather", { this.sendNotification("WEATHER_UPDATED", notificationPayload); }, - scheduleUpdate: function (delay = null) { + scheduleUpdate (delay = null) { let nextLoad = this.config.updateInterval; if (delay !== null && delay >= 0) { nextLoad = delay; @@ -195,64 +203,47 @@ Module.register("weather", { }, nextLoad); }, - roundValue: function (temperature) { + roundValue (temperature) { const decimals = this.config.roundTemp ? 0 : 1; const roundValue = parseFloat(temperature).toFixed(decimals); return roundValue === "-0" ? 0 : roundValue; }, - addFilters() { + addFilters () { this.nunjucksEnvironment().addFilter( "formatTime", function (date) { - date = moment(date); - - if (this.config.timeFormat !== 24) { - if (this.config.showPeriod) { - if (this.config.showPeriodUpper) { - return date.format("h:mm A"); - } else { - return date.format("h:mm a"); - } - } else { - return date.format("h:mm"); - } - } - - return date.format("HH:mm"); + return formatTime(this.config, date); }.bind(this) ); this.nunjucksEnvironment().addFilter( "unit", - function (value, type) { + function (value, type, valueUnit) { + let formattedValue; if (type === "temperature") { - value = this.roundValue(WeatherUtils.convertTemp(value, this.config.tempUnits)) + "°"; + formattedValue = `${this.roundValue(WeatherUtils.convertTemp(value, this.config.tempUnits))}°`; if (this.config.degreeLabel) { if (this.config.tempUnits === "metric") { - value += "C"; + formattedValue += "C"; } else if (this.config.tempUnits === "imperial") { - value += "F"; + formattedValue += "F"; } else { - value += "K"; + formattedValue += "K"; } } } else if (type === "precip") { - if (value === null || isNaN(value) || value === 0 || value.toFixed(2) === "0.00") { - value = ""; + if (value === null || isNaN(value)) { + formattedValue = ""; } else { - if (this.config.weatherProvider === "ukmetoffice" || this.config.weatherProvider === "ukmetofficedatahub") { - value += "%"; - } else { - value = `${value.toFixed(2)} ${this.config.units === "imperial" ? "in" : "mm"}`; - } + formattedValue = WeatherUtils.convertPrecipitationUnit(value, valueUnit, this.config.units); } } else if (type === "humidity") { - value += "%"; + formattedValue = `${value}%`; } else if (type === "wind") { - value = WeatherUtils.convertWind(value, this.config.windUnits); + formattedValue = WeatherUtils.convertWind(value, this.config.windUnits); } - return value; + return formattedValue; }.bind(this) ); diff --git a/modules/default/weather/weatherobject.js b/modules/default/weather/weatherobject.js index 0e28b4f20b..5d6801ce13 100644 --- a/modules/default/weather/weatherobject.js +++ b/modules/default/weather/weatherobject.js @@ -1,24 +1,17 @@ /* global SunCalc, WeatherUtils */ -/* MagicMirror² - * Module: Weather - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. - * - * This class is the blueprint for a day which includes weather information. - * - * Currently this is focused on the information which is necessary for the current weather. - * As soon as we start implementing the forecast, mode properties will be added. +/** + * @external Moment */ class WeatherObject { + /** * Constructor for a WeatherObject */ - constructor() { + constructor () { this.date = null; this.windSpeed = null; - this.windDirection = null; + this.windFromDirection = null; this.sunrise = null; this.sunset = null; this.temperature = null; @@ -26,97 +19,83 @@ class WeatherObject { this.maxTemperature = null; this.weatherType = null; this.humidity = null; - this.rain = null; - this.snow = null; - this.precipitation = null; + this.precipitationAmount = null; this.precipitationUnits = null; + this.precipitationProbability = null; this.feelsLikeTemp = null; } - cardinalWindDirection() { - if (this.windDirection > 11.25 && this.windDirection <= 33.75) { + cardinalWindDirection () { + if (this.windFromDirection > 11.25 && this.windFromDirection <= 33.75) { return "NNE"; - } else if (this.windDirection > 33.75 && this.windDirection <= 56.25) { + } else if (this.windFromDirection > 33.75 && this.windFromDirection <= 56.25) { return "NE"; - } else if (this.windDirection > 56.25 && this.windDirection <= 78.75) { + } else if (this.windFromDirection > 56.25 && this.windFromDirection <= 78.75) { return "ENE"; - } else if (this.windDirection > 78.75 && this.windDirection <= 101.25) { + } else if (this.windFromDirection > 78.75 && this.windFromDirection <= 101.25) { return "E"; - } else if (this.windDirection > 101.25 && this.windDirection <= 123.75) { + } else if (this.windFromDirection > 101.25 && this.windFromDirection <= 123.75) { return "ESE"; - } else if (this.windDirection > 123.75 && this.windDirection <= 146.25) { + } else if (this.windFromDirection > 123.75 && this.windFromDirection <= 146.25) { return "SE"; - } else if (this.windDirection > 146.25 && this.windDirection <= 168.75) { + } else if (this.windFromDirection > 146.25 && this.windFromDirection <= 168.75) { return "SSE"; - } else if (this.windDirection > 168.75 && this.windDirection <= 191.25) { + } else if (this.windFromDirection > 168.75 && this.windFromDirection <= 191.25) { return "S"; - } else if (this.windDirection > 191.25 && this.windDirection <= 213.75) { + } else if (this.windFromDirection > 191.25 && this.windFromDirection <= 213.75) { return "SSW"; - } else if (this.windDirection > 213.75 && this.windDirection <= 236.25) { + } else if (this.windFromDirection > 213.75 && this.windFromDirection <= 236.25) { return "SW"; - } else if (this.windDirection > 236.25 && this.windDirection <= 258.75) { + } else if (this.windFromDirection > 236.25 && this.windFromDirection <= 258.75) { return "WSW"; - } else if (this.windDirection > 258.75 && this.windDirection <= 281.25) { + } else if (this.windFromDirection > 258.75 && this.windFromDirection <= 281.25) { return "W"; - } else if (this.windDirection > 281.25 && this.windDirection <= 303.75) { + } else if (this.windFromDirection > 281.25 && this.windFromDirection <= 303.75) { return "WNW"; - } else if (this.windDirection > 303.75 && this.windDirection <= 326.25) { + } else if (this.windFromDirection > 303.75 && this.windFromDirection <= 326.25) { return "NW"; - } else if (this.windDirection > 326.25 && this.windDirection <= 348.75) { + } else if (this.windFromDirection > 326.25 && this.windFromDirection <= 348.75) { return "NNW"; } else { return "N"; } } - nextSunAction() { - return moment().isBetween(this.sunrise, this.sunset) ? "sunset" : "sunrise"; + /** + * Determines if the sun sets or rises next. Uses the current time and not + * the date from the weather-forecast. + * @param {Moment} date an optional date where you want to get the next + * action for. Useful only in tests, defaults to the current time. + * @returns {string} "sunset" or "sunrise" + */ + nextSunAction (date = moment()) { + return date.isBetween(this.sunrise, this.sunset) ? "sunset" : "sunrise"; } - feelsLike() { + feelsLike () { if (this.feelsLikeTemp) { return this.feelsLikeTemp; } - const windInMph = WeatherUtils.convertWind(this.windSpeed, "imperial"); - const tempInF = WeatherUtils.convertTemp(this.temperature, "imperial"); - let feelsLike = tempInF; - - if (windInMph > 3 && tempInF < 50) { - feelsLike = Math.round(35.74 + 0.6215 * tempInF - 35.75 * Math.pow(windInMph, 0.16) + 0.4275 * tempInF * Math.pow(windInMph, 0.16)); - } else if (tempInF > 80 && this.humidity > 40) { - feelsLike = - -42.379 + - 2.04901523 * tempInF + - 10.14333127 * this.humidity - - 0.22475541 * tempInF * this.humidity - - 6.83783 * Math.pow(10, -3) * tempInF * tempInF - - 5.481717 * Math.pow(10, -2) * this.humidity * this.humidity + - 1.22874 * Math.pow(10, -3) * tempInF * tempInF * this.humidity + - 8.5282 * Math.pow(10, -4) * tempInF * this.humidity * this.humidity - - 1.99 * Math.pow(10, -6) * tempInF * tempInF * this.humidity * this.humidity; - } - - return ((feelsLike - 32) * 5) / 9; + return WeatherUtils.calculateFeelsLike(this.temperature, this.windSpeed, this.humidity); } /** * Checks if the weatherObject is at dayTime. - * * @returns {boolean} true if it is at dayTime */ - isDayTime() { - return this.date.isBetween(this.sunrise, this.sunset, undefined, "[]"); + isDayTime () { + const now = !this.date ? moment() : this.date; + return now.isBetween(this.sunrise, this.sunset, undefined, "[]"); } /** * Update the sunrise / sunset time depending on the location. This can be * 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) { + updateSunTime (lat, lon) { const now = !this.date ? new Date() : this.date.toDate(); const times = SunCalc.getTimes(now, lat, lon); this.sunrise = moment(times.sunrise); @@ -128,10 +107,9 @@ class WeatherObject { * * Before being handed to other modules, mutable values must be cloned safely. * Especially 'moment' object is not immutable, so original 'date', 'sunrise', 'sunset' could be corrupted or changed by other modules. - * * @returns {object} plained object clone of original weatherObject */ - simpleClone() { + simpleClone () { const toFlat = ["date", "sunrise", "sunset"]; let clone = { ...this }; for (const prop of toFlat) { diff --git a/modules/default/weather/weatherprovider.js b/modules/default/weather/weatherprovider.js index e7bfe5b7d7..3646441094 100644 --- a/modules/default/weather/weatherprovider.js +++ b/modules/default/weather/weatherprovider.js @@ -1,13 +1,6 @@ -/* global Class, performWebRequest */ - -/* MagicMirror² - * Module: Weather - * - * By Michael Teeuw https://michaelteeuw.nl - * MIT Licensed. - * - * This class is the blueprint for a weather provider. - */ +/* global Class, performWebRequest, OverrideWrapper */ + +// This class is the blueprint for a weather provider. const WeatherProvider = Class.extend({ // Weather Provider Properties providerName: null, @@ -30,97 +23,96 @@ const WeatherProvider = Class.extend({ // All the following methods can be overwritten, although most are good as they are. // Called when a weather provider is initialized. - init: function (config) { + init (config) { this.config = config; Log.info(`Weather provider: ${this.providerName} initialized.`); }, // Called to set the config, this config is the same as the weather module's config. - setConfig: function (config) { + setConfig (config) { this.config = config; Log.info(`Weather provider: ${this.providerName} config set.`, this.config); }, // Called when the weather provider is about to start. - start: function () { + start () { Log.info(`Weather provider: ${this.providerName} started.`); }, // This method should start the API request to fetch the current weather. // This method should definitely be overwritten in the provider. - fetchCurrentWeather: function () { + fetchCurrentWeather () { Log.warn(`Weather provider: ${this.providerName} does not subclass the fetchCurrentWeather method.`); }, // This method should start the API request to fetch the weather forecast. // This method should definitely be overwritten in the provider. - fetchWeatherForecast: function () { + fetchWeatherForecast () { Log.warn(`Weather provider: ${this.providerName} does not subclass the fetchWeatherForecast method.`); }, // This method should start the API request to fetch the weather hourly. // This method should definitely be overwritten in the provider. - fetchWeatherHourly: function () { + fetchWeatherHourly () { Log.warn(`Weather provider: ${this.providerName} does not subclass the fetchWeatherHourly method.`); }, // This returns a WeatherDay object for the current weather. - currentWeather: function () { + currentWeather () { return this.currentWeatherObject; }, // This returns an array of WeatherDay objects for the weather forecast. - weatherForecast: function () { + weatherForecast () { return this.weatherForecastArray; }, // This returns an object containing WeatherDay object(s) depending on the type of call. - weatherHourly: function () { + weatherHourly () { return this.weatherHourlyArray; }, // This returns the name of the fetched location or an empty string. - fetchedLocation: function () { + fetchedLocation () { return this.fetchedLocationName || ""; }, // Set the currentWeather and notify the delegate that new information is available. - setCurrentWeather: function (currentWeatherObject) { + setCurrentWeather (currentWeatherObject) { // We should check here if we are passing a WeatherDay this.currentWeatherObject = currentWeatherObject; }, // Set the weatherForecastArray and notify the delegate that new information is available. - setWeatherForecast: function (weatherForecastArray) { + setWeatherForecast (weatherForecastArray) { // We should check here if we are passing a WeatherDay this.weatherForecastArray = weatherForecastArray; }, // Set the weatherHourlyArray and notify the delegate that new information is available. - setWeatherHourly: function (weatherHourlyArray) { + setWeatherHourly (weatherHourlyArray) { this.weatherHourlyArray = weatherHourlyArray; }, // Set the fetched location name. - setFetchedLocation: function (name) { + setFetchedLocation (name) { this.fetchedLocationName = name; }, // Notify the delegate that new weather is available. - updateAvailable: function () { + updateAvailable () { this.delegate.updateAvailable(this); }, /** * 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) { + async fetchData (url, type = "json", requestHeaders = undefined, expectedResponseHeaders = undefined) { const mockData = this.config.mockData; if (mockData) { const data = mockData.substring(1, mockData.length - 1); @@ -138,7 +130,6 @@ WeatherProvider.providers = []; /** * Static method to register a new weather provider. - * * @param {string} providerIdentifier The name of the weather provider * @param {object} providerDetails The details of the weather provider */ @@ -148,23 +139,26 @@ WeatherProvider.register = function (providerIdentifier, providerDetails) { /** * Static method to initialize a new weather provider. - * * @param {string} providerIdentifier The name of the weather provider * @param {object} delegate The weather module * @returns {object} The new weather provider */ WeatherProvider.initialize = function (providerIdentifier, delegate) { - providerIdentifier = providerIdentifier.toLowerCase(); + const pi = providerIdentifier.toLowerCase(); - const provider = new WeatherProvider.providers[providerIdentifier](); + const provider = new WeatherProvider.providers[pi](); const config = Object.assign({}, provider.defaults, delegate.config); provider.delegate = delegate; provider.setConfig(config); - provider.providerIdentifier = providerIdentifier; + provider.providerIdentifier = pi; if (!provider.providerName) { - provider.providerName = providerIdentifier; + provider.providerName = pi; + } + + if (config.allowOverrideNotification) { + return new OverrideWrapper(provider); } return provider; diff --git a/modules/default/weather/weatherutils.js b/modules/default/weather/weatherutils.js index c0af86afc3..e75baf20f7 100644 --- a/modules/default/weather/weatherutils.js +++ b/modules/default/weather/weatherutils.js @@ -1,18 +1,12 @@ -/* 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; + beaufortWindSpeed (speedInMS) { + const windInKmh = this.convertWind(speedInMS, "kmh"); const speeds = [1, 5, 11, 19, 28, 38, 49, 61, 74, 88, 102, 117, 1000]; for (const [index, speed] of speeds.entries()) { if (speed > windInKmh) { @@ -22,27 +16,49 @@ const WeatherUtils = { return 12; }, + /** + * Convert a value in a given unit to a string with a converted + * value and a postfix matching the output unit system. + * @param {number} value - The value to convert. + * @param {string} valueUnit - The unit the values has. Default is mm. + * @param {string} outputUnit - The unit system (imperial/metric) the return value should have. + * @returns {string} - A string with tha value and a unit postfix. + */ + convertPrecipitationUnit (value, valueUnit, outputUnit) { + if (valueUnit === "%") return `${value.toFixed(0)} ${valueUnit}`; + + let convertedValue = value; + let conversionUnit = valueUnit; + if (outputUnit === "imperial") { + if (valueUnit && valueUnit.toLowerCase() === "cm") convertedValue = convertedValue * 0.3937007874; + else convertedValue = convertedValue * 0.03937007874; + conversionUnit = "in"; + } else { + conversionUnit = valueUnit ? valueUnit : "mm"; + } + + return `${convertedValue.toFixed(2)} ${conversionUnit}`; + }, + /** * 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) { + 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) { + convertWind (windInMS, unit) { switch (unit) { case "beaufort": return this.beaufortWindSpeed(windInMS); @@ -61,7 +77,7 @@ const WeatherUtils = { /* * Convert the wind direction cardinal to value */ - convertWindDirection(windDirection) { + convertWindDirection (windDirection) { const windCardinals = { N: 0, NNE: 22, @@ -84,12 +100,35 @@ const WeatherUtils = { return windCardinals.hasOwnProperty(windDirection) ? windCardinals[windDirection] : null; }, - convertWindToMetric(mph) { + convertWindToMetric (mph) { return mph / 2.2369362920544; }, - convertWindToMs(kmh) { + convertWindToMs (kmh) { return kmh * 0.27777777777778; + }, + + calculateFeelsLike (temperature, windSpeed, humidity) { + const windInMph = this.convertWind(windSpeed, "imperial"); + const tempInF = this.convertTemp(temperature, "imperial"); + let feelsLike = tempInF; + + if (windInMph > 3 && tempInF < 50) { + feelsLike = Math.round(35.74 + 0.6215 * tempInF - 35.75 * Math.pow(windInMph, 0.16) + 0.4275 * tempInF * Math.pow(windInMph, 0.16)); + } else if (tempInF > 80 && humidity > 40) { + feelsLike + = -42.379 + + 2.04901523 * tempInF + + 10.14333127 * humidity + - 0.22475541 * tempInF * humidity + - 6.83783 * Math.pow(10, -3) * tempInF * tempInF + - 5.481717 * Math.pow(10, -2) * humidity * humidity + + 1.22874 * Math.pow(10, -3) * tempInF * tempInF * humidity + + 8.5282 * Math.pow(10, -4) * tempInF * humidity * humidity + - 1.99 * Math.pow(10, -6) * tempInF * tempInF * humidity * humidity; + } + + return ((feelsLike - 32) * 5) / 9; } }; diff --git a/package-lock.json b/package-lock.json index f16d94d761..22c2ad3242 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,113 +1,119 @@ { "name": "magicmirror", - "version": "2.22.0-develop", - "lockfileVersion": 2, + "version": "2.28.0-develop", + "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "magicmirror", - "version": "2.22.0-develop", + "version": "2.28.0-develop", "hasInstallScript": true, "license": "MIT", "dependencies": { - "colors": "^1.4.0", - "console-stamp": "^3.0.6", - "digest-fetch": "^1.3.0", - "eslint": "^8.26.0", - "express": "^4.18.2", - "express-ipfilter": "^1.3.1", + "ansis": "^3.2.0", + "console-stamp": "^3.1.2", + "envsub": "^4.1.0", + "eslint": "^8.57.0", + "express": "^4.19.2", + "express-ipfilter": "^1.3.2", "feedme": "^2.0.2", - "helmet": "^6.0.0", + "helmet": "^7.1.0", + "html-to-text": "^9.0.5", "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.2", - "socket.io": "^4.5.3" + "module-alias": "^2.2.3", + "moment": "^2.30.1", + "node-ical": "^0.18.0", + "pm2": "^5.4.1", + "socket.io": "^4.7.5", + "suncalc": "^1.9.0", + "systeminformation": "^5.22.11" }, "devDependencies": { - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-jest": "^27.1.3", - "eslint-plugin-jsdoc": "^39.3.25", - "eslint-plugin-prettier": "^4.2.1", + "@stylistic/eslint-plugin": "^1.8.1", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-jest": "^28.6.0", + "eslint-plugin-jsdoc": "^48.2.12", + "eslint-plugin-package-json": "^0.15.0", + "eslint-plugin-unicorn": "^54.0.0", "express-basic-auth": "^1.2.1", - "husky": "^8.0.1", - "jest": "^29.2.2", - "jsdom": "^20.0.1", - "lodash": "^4.17.21", - "playwright": "^1.27.1", - "prettier": "^2.7.1", - "pretty-quick": "^3.1.3", - "sinon": "^14.0.1", - "stylelint": "^14.14.0", - "stylelint-config-prettier": "^9.0.3", - "stylelint-config-standard": "^29.0.0", - "stylelint-prettier": "^2.0.0", - "suncalc": "^1.9.0" + "husky": "^9.0.11", + "jest": "^29.7.0", + "jsdom": "^24.1.0", + "lint-staged": "^15.2.7", + "playwright": "^1.44.1", + "prettier": "^3.3.2", + "sinon": "^18.0.0", + "stylelint": "^16.6.1", + "stylelint-config-standard": "^36.0.0", + "stylelint-prettier": "^5.0.0" }, "engines": { - "node": ">=14" + "node": ">=18" }, "optionalDependencies": { - "electron": "^19.1.3" + "electron": "^31.0.1" } }, "node_modules/@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz", + "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.24.7.tgz", + "integrity": "sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/highlight": "^7.18.6" + "@babel/highlight": "^7.24.7", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" } }, "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.24.7", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.24.7.tgz", + "integrity": "sha512-qJzAIcv03PyaWqxRgO4mSU3lihncDT296vnyuE2O8uA4w3UHWI4S3hgeZd1L8W1Bft40w9JxJ2b412iDUFFRhw==", "dev": true, + "license": "MIT", "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==", - "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", - "convert-source-map": "^1.7.0", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.24.7.tgz", + "integrity": "sha512-nykK+LEK86ahTkX/3TgauT0ikKoNCfKHEaZYTUVupJdTLzGNvrblu4u6fa7DhZONAltdf8e662t/abY8idrd/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "@ampproject/remapping": "^2.2.0", + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-compilation-targets": "^7.24.7", + "@babel/helper-module-transforms": "^7.24.7", + "@babel/helpers": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/template": "^7.24.7", + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7", + "convert-source-map": "^2.0.0", "debug": "^4.1.0", "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" + "json5": "^2.2.3", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" @@ -117,200 +123,238 @@ "url": "https://opencollective.com/babel" } }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "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.24.7", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.24.7.tgz", + "integrity": "sha512-oipXieGC3i45Y1A41t4tAqpnEZWgB/lC6Ehh6+rOviR5XWpTtMmLN+fGjz9vOiNRt0p6RtO6DtD0pdU3vpqdSA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.19.3", - "@jridgewell/gen-mapping": "^0.3.2", + "@babel/types": "^7.24.7", + "@jridgewell/gen-mapping": "^0.3.5", + "@jridgewell/trace-mapping": "^0.3.25", "jsesc": "^2.5.1" }, "engines": { "node": ">=6.9.0" } }, - "node_modules/@babel/generator/node_modules/@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", + "node_modules/@babel/generator/node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", "dev": true, - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" + "license": "MIT", + "bin": { + "jsesc": "bin/jsesc" }, "engines": { - "node": ">=6.0.0" + "node": ">=4" } }, "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.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.24.7.tgz", + "integrity": "sha512-ctSdRHBi20qWOfy27RUb4Fhp07KSJ3sXcuSvTrXrc4aG8NSYDo1ici3Vhg9bg69y5bj0Mr1lh0aeEgTvc12rMg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/compat-data": "^7.19.3", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" + "@babel/compat-data": "^7.24.7", + "@babel/helper-validator-option": "^7.24.7", + "browserslist": "^4.22.2", + "lru-cache": "^5.1.1", + "semver": "^6.3.1" }, "engines": { "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" } }, "node_modules/@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.24.7.tgz", + "integrity": "sha512-DoiN84+4Gnd0ncbBOM9AZENV4a5ZiL39HYMyZJGZ/AZEykHYdJw0wW3kdcsh9/Kn+BRXHLkkklZ51ecPKmI1CQ==", "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.24.7" + }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.24.7.tgz", + "integrity": "sha512-FyoJTsj/PEUWu1/TYRiXTIHc8lbw+TDYkZuoE43opPS5TrI7MyONBE1oNvfguEXAD9yhQRrVBnXdXzSLQl9XnA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.24.7.tgz", + "integrity": "sha512-MJJwhkoGy5c4ehfoRyrJ/owKeMl19U54h27YYftT0o2teQ3FJ3nQUf/I3LlJsX4l3qlw7WRXUmiyajvHXoTubQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.24.7.tgz", + "integrity": "sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "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.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.24.7.tgz", + "integrity": "sha512-1fuJEwIrp+97rM4RWdO+qrRsZlAeL1lQJoPqtCYWv0NL115XM93hIH4CSRln2w52SqvmY5hqdtauB6QFCDiZNQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.18.6", - "@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-environment-visitor": "^7.24.7", + "@babel/helper-module-imports": "^7.24.7", + "@babel/helper-simple-access": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7" }, "engines": { "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.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.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.24.7.tgz", + "integrity": "sha512-Rq76wjt7yz9AAc1KnlRKNAi/dMSVWgDRx43FHoJEbcYU6xOWaE2dVPwcdTukJrjxS65GITyfbvEYHvkirZ6uEg==", "dev": true, + "license": "MIT", "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.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.24.7.tgz", + "integrity": "sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/traverse": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.24.7.tgz", + "integrity": "sha512-oy5V7pD+UvfkEATUKvIjvIAH/xCzfsFVw7ygW2SI6NClZzquT+mwdTfgfdbUiceh6iQO0CHtCPsyze/MZ2YbAA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.18.6" + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "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.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.24.7.tgz", + "integrity": "sha512-7MbVt6xrwFQbunH2DNQsAP5sTGxfqQtErvBIvIMi6EQnbgUOuVYanvREcmFrOPhoXBrTtjhhP+lW+o5UfK+tDg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.24.7.tgz", + "integrity": "sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.24.7.tgz", + "integrity": "sha512-yy1/KvjhV/ZCL+SM7hBrvnZJ3ZuT9OuZgIJAGpPEToANvc3iM6iDvBnRjtElWibHU6n8/LPR/EjX9EtIEYO3pw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } }, "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.24.7", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.24.7.tgz", + "integrity": "sha512-NlmJJtvcw72yRJRcnCmGvSi+3jDEg8qFu3z0AFoymmzLx5ERVWyzd9kVXr7Th9/8yIJi2Zc6av4Tqz3wFs8QWg==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "@babel/template": "^7.24.7", + "@babel/types": "^7.24.7" }, "engines": { "node": ">=6.9.0" } }, "node_modules/@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.24.7.tgz", + "integrity": "sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" + "@babel/helper-validator-identifier": "^7.24.7", + "chalk": "^2.4.2", + "js-tokens": "^4.0.0", + "picocolors": "^1.0.0" }, "engines": { "node": ">=6.9.0" @@ -321,6 +365,7 @@ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", "dev": true, + "license": "MIT", "dependencies": { "color-convert": "^1.9.0" }, @@ -333,6 +378,7 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", "dev": true, + "license": "MIT", "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", @@ -347,6 +393,7 @@ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", "dev": true, + "license": "MIT", "dependencies": { "color-name": "1.1.3" } @@ -355,13 +402,15 @@ "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/@babel/highlight/node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.8.0" } @@ -371,6 +420,7 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } @@ -380,6 +430,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^3.0.0" }, @@ -388,10 +439,11 @@ } }, "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.24.7", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.24.7.tgz", + "integrity": "sha512-9uUYRm6OqQrCqQdG1iCBwBPZgN8ciDBro2nIOFaiRz1/BCxaI7CNvQbDHvsArAC7Tw9Hda/B3U+6ui9u4HWXPw==", "dev": true, + "license": "MIT", "bin": { "parser": "bin/babel-parser.js" }, @@ -404,6 +456,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -416,6 +469,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -428,6 +482,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.12.13" }, @@ -440,6 +495,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -452,6 +508,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -460,12 +517,13 @@ } }, "node_modules/@babel/plugin-syntax-jsx": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", - "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.24.7.tgz", + "integrity": "sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -479,6 +537,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -491,6 +550,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -503,6 +563,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.10.4" }, @@ -515,6 +576,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -527,6 +589,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -539,6 +602,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.8.0" }, @@ -551,6 +615,7 @@ "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/helper-plugin-utils": "^7.14.5" }, @@ -562,12 +627,13 @@ } }, "node_modules/@babel/plugin-syntax-typescript": { - "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==", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.24.7.tgz", + "integrity": "sha512-c/+fVeJBB0FeKsFvwytYiUD+LBvhHjGSI0g446PRGdSVGZLRNArBUno2PETbAly3tpiNAQR5XaZ+JslxkotsbA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-plugin-utils": "^7.19.0" + "@babel/helper-plugin-utils": "^7.24.7" }, "engines": { "node": ">=6.9.0" @@ -577,34 +643,36 @@ } }, "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.24.7", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.24.7.tgz", + "integrity": "sha512-jYqfPrU9JTF0PmPy1tLYHW4Mp4KlgxJD9l2nP9fD6yT/ICi554DmrWBAEYpIelzjHf1msDP3PxJIRt/nFNfBig==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" + "@babel/code-frame": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.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==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.3", - "@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", - "debug": "^4.1.0", + "version": "7.24.7", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.24.7.tgz", + "integrity": "sha512-yb65Ed5S/QAcewNPh0nZczy9JdYXkkAbIsEo+P7BE7yO3txAY30Y/oPa3QkQ5It3xVG2kpKMg9MsdxZaO31uKA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/code-frame": "^7.24.7", + "@babel/generator": "^7.24.7", + "@babel/helper-environment-visitor": "^7.24.7", + "@babel/helper-function-name": "^7.24.7", + "@babel/helper-hoist-variables": "^7.24.7", + "@babel/helper-split-export-declaration": "^7.24.7", + "@babel/parser": "^7.24.7", + "@babel/types": "^7.24.7", + "debug": "^4.3.1", "globals": "^11.1.0" }, "engines": { @@ -616,18 +684,20 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", "dev": true, + "license": "MIT", "engines": { "node": ">=4" } }, "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.24.7", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.24.7.tgz", + "integrity": "sha512-XEFXSlxiG5td2EJRe8vOmRbaXVgfcBlszKujvVmWIK/UpywWljQCfzAv3RQCGujWQ1RD4YYWEAqDXfuJiy8f5Q==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/helper-string-parser": "^7.18.10", - "@babel/helper-validator-identifier": "^7.19.1", + "@babel/helper-string-parser": "^7.24.7", + "@babel/helper-validator-identifier": "^7.24.7", "to-fast-properties": "^2.0.0" }, "engines": { @@ -638,70 +708,208 @@ "version": "0.2.3", "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true + "dev": true, + "license": "MIT" }, - "node_modules/@csstools/selector-specificity": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz", - "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==", + "node_modules/@csstools/css-parser-algorithms": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/@csstools/css-parser-algorithms/-/css-parser-algorithms-2.6.3.tgz", + "integrity": "sha512-xI/tL2zxzEbESvnSxwFgwvy5HS00oCXxL4MLs6HUiDcYfwowsoQaABKxUElp1ARITrINzBnsECOc1q0eg2GOrA==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", "engines": { - "node": "^12 || ^14 || >=16" + "node": "^14 || ^16 || >=18" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" + "peerDependencies": { + "@csstools/css-tokenizer": "^2.3.1" + } + }, + "node_modules/@csstools/css-tokenizer": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@csstools/css-tokenizer/-/css-tokenizer-2.3.1.tgz", + "integrity": "sha512-iMNHTyxLbBlWIfGtabT157LH9DUx9X8+Y3oymFEuMj8HNc+rpE3dPFGFgHjpKfjeFDjLjYIAIhXPGvS2lKxL9g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18" + } + }, + "node_modules/@csstools/media-query-list-parser": { + "version": "2.1.11", + "resolved": "https://registry.npmjs.org/@csstools/media-query-list-parser/-/media-query-list-parser-2.1.11.tgz", + "integrity": "sha512-uox5MVhvNHqitPP+SynrB1o8oPxPMt2JLgp5ghJOWf54WGQ5OKu47efne49r1SWqs3wRP8xSWjnO9MBKxhB1dA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT", + "engines": { + "node": "^14 || ^16 || >=18" + }, + "peerDependencies": { + "@csstools/css-parser-algorithms": "^2.6.3", + "@csstools/css-tokenizer": "^2.3.1" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-3.1.1.tgz", + "integrity": "sha512-a7cxGcJ2wIlMFLlh8z2ONm+715QkPHiyJcxwQlKOz/03GPw1COpfhcmC9wm4xlZfp//jWHNNMwzjtqHXVWU9KA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/csstools" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + } + ], + "license": "MIT-0", + "engines": { + "node": "^14 || ^16 || >=18" }, "peerDependencies": { - "postcss": "^8.2", - "postcss-selector-parser": "^6.0.10" + "postcss-selector-parser": "^6.0.13" + } + }, + "node_modules/@dual-bundle/import-meta-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@dual-bundle/import-meta-resolve/-/import-meta-resolve-4.1.0.tgz", + "integrity": "sha512-+nxncfwHM5SgAtrVzgpzJOI1ol0PkumhVo469KCf9lUi21IGcY90G98VuHm9VRrUypmAzawAHO9bs6hqeADaVg==", + "dev": true, + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, "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.3", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.3.tgz", + "integrity": "sha512-Qkzpg2s9GnVV2I2BjRksUi43U5e6+zaQMcjoJy0C+C5oxaKl+fmckGDQFtRpZpZV0NQekuZZ+tGz7EA9TVnQtQ==", + "license": "MIT", "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/@electron/get/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "license": "ISC", + "optional": true, + "bin": { + "semver": "bin/semver.js" } }, "node_modules/@es-joy/jsdoccomment": { - "version": "0.33.4", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.33.4.tgz", - "integrity": "sha512-02XyYuvR/Gn+3BT6idHVNQ4SSQlA1X1FeEfeKm2ypv8ANB6Lt9KRFZ2S7y5xjwR+EPQ/Rzb0XFaD+xKyqe4ALw==", + "version": "0.43.1", + "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.43.1.tgz", + "integrity": "sha512-I238eDtOolvCuvtxrnqtlBaw0BwdQuYqK7eA6XIonicMdOOOb75mqdIzkGDUbS04+1Di007rgm9snFRNeVrOog==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "^8.56.5", + "@types/estree": "^1.0.5", + "@typescript-eslint/types": "^7.2.0", + "comment-parser": "1.4.1", + "esquery": "^1.5.0", + "jsdoc-type-pratt-parser": "~4.0.0" + }, + "engines": { + "node": ">=16" + } + }, + "node_modules/@es-joy/jsdoccomment/node_modules/@typescript-eslint/types": { + "version": "7.13.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-7.13.1.tgz", + "integrity": "sha512-7K7HMcSQIAND6RBL4kDl24sG/xKM13cA85dc7JnmQXw2cBDngg7c19B++JzvJHRG3zG36n9j1i451GBzRuHchw==", "dev": true, + "license": "MIT", + "engines": { + "node": "^18.18.0 || >=20.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@eslint-community/eslint-utils": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", + "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==", + "license": "MIT", "dependencies": { - "comment-parser": "1.3.1", - "esquery": "^1.4.0", - "jsdoc-type-pratt-parser": "~3.1.0" + "eslint-visitor-keys": "^3.3.0" }, "engines": { - "node": "^14 || ^16 || ^17 || ^18 || ^19" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0" + } + }, + "node_modules/@eslint-community/regexpp": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.10.1.tgz", + "integrity": "sha512-Zm2NGpWELsQAD1xsJzGQpYfvICSsFkEpU0jxBjfdC6uNEWXcHnfs9hScFWtXVDVl+rBQJGrl4g1vcKIejpH9dA==", + "license": "MIT", + "engines": { + "node": "^12.0.0 || ^14.0.0 || >=16.0.0" } }, "node_modules/@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", + "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "license": "MIT", "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.15.0", + "espree": "^9.6.0", + "globals": "^13.19.0", "ignore": "^5.2.0", "import-fresh": "^3.2.1", "js-yaml": "^4.1.0", @@ -715,23 +923,79 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", - "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", + "node_modules/@eslint/eslintrc/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "license": "MIT", "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@eslint/eslintrc/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/@eslint/js": { + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.0.tgz", + "integrity": "sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==", + "license": "MIT", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.14", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.14.tgz", + "integrity": "sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==", + "deprecated": "Use @eslint/config-array instead", + "license": "Apache-2.0", + "dependencies": { + "@humanwhocodes/object-schema": "^2.0.2", + "debug": "^4.3.1", "minimatch": "^3.0.5" }, "engines": { "node": ">=10.10.0" } }, + "node_modules/@humanwhocodes/config-array/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/@humanwhocodes/config-array/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, "node_modules/@humanwhocodes/module-importer": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "license": "Apache-2.0", "engines": { "node": ">=12.22" }, @@ -741,15 +1005,18 @@ } }, "node_modules/@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", + "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", + "deprecated": "Use @eslint/object-schema instead", + "license": "BSD-3-Clause" }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, + "license": "ISC", "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", @@ -766,6 +1033,7 @@ "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", "dev": true, + "license": "MIT", "dependencies": { "sprintf-js": "~1.0.2" } @@ -775,6 +1043,7 @@ "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", "dev": true, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -788,6 +1057,7 @@ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, + "license": "MIT", "dependencies": { "argparse": "^1.0.7", "esprima": "^4.0.0" @@ -801,6 +1071,7 @@ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", "dev": true, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -813,6 +1084,7 @@ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -828,6 +1100,7 @@ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", "dev": true, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -840,6 +1113,7 @@ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -848,28 +1122,31 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, "node_modules/@istanbuljs/schema": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/@jest/console": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.2.1.tgz", - "integrity": "sha512-MF8Adcw+WPLZGBiNxn76DOuczG3BhODTcMlDCA4+cFi41OkaY/lyI0XUUhi73F88Y+7IHoGmD80pN5CtxQUdSw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.7.0.tgz", + "integrity": "sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.2.1", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", - "jest-message-util": "^29.2.1", - "jest-util": "^29.2.1", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", "slash": "^3.0.0" }, "engines": { @@ -877,37 +1154,38 @@ } }, "node_modules/@jest/core": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.2.2.tgz", - "integrity": "sha512-susVl8o2KYLcZhhkvSB+b7xX575CX3TmSvxfeDjpRko7KmT89rHkXj6XkDkNpSeFMBzIENw5qIchO9HC9Sem+A==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.7.0.tgz", + "integrity": "sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/console": "^29.2.1", - "@jest/reporters": "^29.2.2", - "@jest/test-result": "^29.2.1", - "@jest/transform": "^29.2.2", - "@jest/types": "^29.2.1", + "@jest/console": "^29.7.0", + "@jest/reporters": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "ci-info": "^3.2.0", "exit": "^0.1.2", "graceful-fs": "^4.2.9", - "jest-changed-files": "^29.2.0", - "jest-config": "^29.2.2", - "jest-haste-map": "^29.2.1", - "jest-message-util": "^29.2.1", - "jest-regex-util": "^29.2.0", - "jest-resolve": "^29.2.2", - "jest-resolve-dependencies": "^29.2.2", - "jest-runner": "^29.2.2", - "jest-runtime": "^29.2.2", - "jest-snapshot": "^29.2.2", - "jest-util": "^29.2.1", - "jest-validate": "^29.2.2", - "jest-watcher": "^29.2.2", + "jest-changed-files": "^29.7.0", + "jest-config": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-resolve-dependencies": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", + "jest-watcher": "^29.7.0", "micromatch": "^4.0.4", - "pretty-format": "^29.2.1", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "strip-ansi": "^6.0.0" }, @@ -923,90 +1201,112 @@ } } }, - "node_modules/@jest/environment": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.2.2.tgz", - "integrity": "sha512-OWn+Vhu0I1yxuGBJEFFekMYc8aGBGrY4rt47SOh/IFaI+D7ZHCk7pKRiSoZ2/Ml7b0Ony3ydmEHRx/tEOC7H1A==", + "node_modules/@jest/core/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "dev": true, - "dependencies": { - "@jest/fake-timers": "^29.2.2", - "@jest/types": "^29.2.1", - "@types/node": "*", - "jest-mock": "^29.2.2" - }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - } - }, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/environment": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.7.0.tgz", + "integrity": "sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", + "@types/node": "*", + "jest-mock": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, "node_modules/@jest/expect": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.2.2.tgz", - "integrity": "sha512-zwblIZnrIVt8z/SiEeJ7Q9wKKuB+/GS4yZe9zw7gMqfGf4C5hBLGrVyxu1SzDbVSqyMSlprKl3WL1r80cBNkgg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==", "dev": true, + "license": "MIT", "dependencies": { - "expect": "^29.2.2", - "jest-snapshot": "^29.2.2" + "expect": "^29.7.0", + "jest-snapshot": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/expect-utils": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.2.2.tgz", - "integrity": "sha512-vwnVmrVhTmGgQzyvcpze08br91OL61t9O0lJMDyb6Y/D8EKQ9V7rGUb/p7PDt0GPzK0zFYqXWFo4EO2legXmkg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.7.0.tgz", + "integrity": "sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==", "dev": true, + "license": "MIT", "dependencies": { - "jest-get-type": "^29.2.0" + "jest-get-type": "^29.6.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/fake-timers": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.2.2.tgz", - "integrity": "sha512-nqaW3y2aSyZDl7zQ7t1XogsxeavNpH6kkdq+EpXncIDvAkjvFD7hmhcIs1nWloengEWUoWqkqSA6MSbf9w6DgA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.7.0.tgz", + "integrity": "sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.2.1", - "@sinonjs/fake-timers": "^9.1.2", + "@jest/types": "^29.6.3", + "@sinonjs/fake-timers": "^10.0.2", "@types/node": "*", - "jest-message-util": "^29.2.1", - "jest-mock": "^29.2.2", - "jest-util": "^29.2.1" + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/globals": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.2.2.tgz", - "integrity": "sha512-/nt+5YMh65kYcfBhj38B3Hm0Trk4IsuMXNDGKE/swp36yydBWfz3OXkLqkSvoAtPW8IJMSJDFCbTM2oj5SNprw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.7.0.tgz", + "integrity": "sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/environment": "^29.2.2", - "@jest/expect": "^29.2.2", - "@jest/types": "^29.2.1", - "jest-mock": "^29.2.2" + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/types": "^29.6.3", + "jest-mock": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/reporters": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.2.2.tgz", - "integrity": "sha512-AzjL2rl2zJC0njIzcooBvjA4sJjvdoq98sDuuNs4aNugtLPSQ+91nysGKRF0uY1to5k0MdGMdOBggUsPqvBcpA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.7.0.tgz", + "integrity": "sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==", "dev": true, + "license": "MIT", "dependencies": { "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.2.1", - "@jest/test-result": "^29.2.1", - "@jest/transform": "^29.2.2", - "@jest/types": "^29.2.1", - "@jridgewell/trace-mapping": "^0.3.15", + "@jest/console": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", "@types/node": "*", "chalk": "^4.0.0", "collect-v8-coverage": "^1.0.0", @@ -1014,13 +1314,13 @@ "glob": "^7.1.3", "graceful-fs": "^4.2.9", "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", + "istanbul-lib-instrument": "^6.0.0", "istanbul-lib-report": "^3.0.0", "istanbul-lib-source-maps": "^4.0.0", "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.2.1", - "jest-util": "^29.2.1", - "jest-worker": "^29.2.1", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", "slash": "^3.0.0", "string-length": "^4.0.1", "strip-ansi": "^6.0.0", @@ -1039,24 +1339,26 @@ } }, "node_modules/@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz", + "integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==", "dev": true, + "license": "MIT", "dependencies": { - "@sinclair/typebox": "^0.24.1" + "@sinclair/typebox": "^0.27.8" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/source-map": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.2.0.tgz", - "integrity": "sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.6.3.tgz", + "integrity": "sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.15", + "@jridgewell/trace-mapping": "^0.3.18", "callsites": "^3.0.0", "graceful-fs": "^4.2.9" }, @@ -1065,13 +1367,14 @@ } }, "node_modules/@jest/test-result": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.2.1.tgz", - "integrity": "sha512-lS4+H+VkhbX6z64tZP7PAUwPqhwj3kbuEHcaLuaBuB+riyaX7oa1txe0tXgrFj5hRWvZKvqO7LZDlNWeJ7VTPA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.7.0.tgz", + "integrity": "sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/console": "^29.2.1", - "@jest/types": "^29.2.1", + "@jest/console": "^29.7.0", + "@jest/types": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "collect-v8-coverage": "^1.0.0" }, @@ -1080,14 +1383,15 @@ } }, "node_modules/@jest/test-sequencer": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.2.2.tgz", - "integrity": "sha512-Cuc1znc1pl4v9REgmmLf0jBd3Y65UXJpioGYtMr/JNpQEIGEzkmHhy6W6DLbSsXeUA13TDzymPv0ZGZ9jH3eIw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.7.0.tgz", + "integrity": "sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/test-result": "^29.2.1", + "@jest/test-result": "^29.7.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.2.1", + "jest-haste-map": "^29.7.0", "slash": "^3.0.0" }, "engines": { @@ -1095,38 +1399,40 @@ } }, "node_modules/@jest/transform": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.2.2.tgz", - "integrity": "sha512-aPe6rrletyuEIt2axxgdtxljmzH8O/nrov4byy6pDw9S8inIrTV+2PnjyP/oFHMSynzGxJ2s6OHowBNMXp/Jzg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.7.0.tgz", + "integrity": "sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", - "@jest/types": "^29.2.1", - "@jridgewell/trace-mapping": "^0.3.15", + "@jest/types": "^29.6.3", + "@jridgewell/trace-mapping": "^0.3.18", "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.2.1", - "jest-regex-util": "^29.2.0", - "jest-util": "^29.2.1", + "jest-haste-map": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", "micromatch": "^4.0.4", "pirates": "^4.0.4", "slash": "^3.0.0", - "write-file-atomic": "^4.0.1" + "write-file-atomic": "^4.0.2" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/@jest/types": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.2.1.tgz", - "integrity": "sha512-O/QNDQODLnINEPAI0cl9U6zUIDXEWXt6IC1o2N2QENuos7hlGUIthlKyV4p6ki3TvXFX071blj8HUhgLGquPjw==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz", + "integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/schemas": "^29.0.0", + "@jest/schemas": "^29.6.3", "@types/istanbul-lib-coverage": "^2.0.0", "@types/istanbul-reports": "^3.0.0", "@types/node": "*", @@ -1138,56 +1444,63 @@ } }, "node_modules/@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", + "integrity": "sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" + "@jridgewell/set-array": "^1.2.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.24" }, "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", + "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.2.1.tgz", + "integrity": "sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.0.0" } }, "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "dev": true + "version": "1.4.15", + "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.15.tgz", + "integrity": "sha512-eF2rxCRulEKXHTRiDrDy6erMYWqNw4LPdQ8UQA4huuxaQsVeRPFl2oM8oDGxMFhJUWZf9McpLtJasDDZb/Bpeg==", + "dev": true, + "license": "MIT" }, "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.25", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.25.tgz", + "integrity": "sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==", "dev": true, + "license": "MIT", "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": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" @@ -1200,6 +1513,7 @@ "version": "2.0.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==", + "license": "MIT", "engines": { "node": ">= 8" } @@ -1208,6 +1522,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", + "license": "MIT", "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" @@ -1216,239 +1531,682 @@ "node": ">= 8" } }, + "node_modules/@pm2/agent": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@pm2/agent/-/agent-2.0.4.tgz", + "integrity": "sha512-n7WYvvTJhHLS2oBb1PjOtgLpMhgImOq8sXkPBw6smeg9LJBWZjiEgPKOpR8mn9UJZsB5P3W4V/MyvNnp31LKeA==", + "license": "AGPL-3.0", + "dependencies": { + "async": "~3.2.0", + "chalk": "~3.0.0", + "dayjs": "~1.8.24", + "debug": "~4.3.1", + "eventemitter2": "~5.0.1", + "fast-json-patch": "^3.0.0-1", + "fclone": "~1.0.11", + "nssocket": "0.6.0", + "pm2-axon": "~4.0.1", + "pm2-axon-rpc": "~0.7.0", + "proxy-agent": "~6.3.0", + "semver": "~7.5.0", + "ws": "~7.5.10" + } + }, + "node_modules/@pm2/agent/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@pm2/agent/node_modules/dayjs": { + "version": "1.8.36", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.8.36.tgz", + "integrity": "sha512-3VmRXEtw7RZKAf+4Tv1Ym9AGeo8r8+CjDi26x+7SYQil1UqtqdaokhzoEJohqlzt0m5kacJSDhJQkG/LWhpRBw==", + "license": "MIT" + }, + "node_modules/@pm2/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==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@pm2/agent/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@pm2/agent/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@pm2/agent/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" + }, + "node_modules/@pm2/io": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/@pm2/io/-/io-6.0.0.tgz", + "integrity": "sha512-sKUEgZoQ5/jRwTyMB1I7u2wXL6dG0j/F/M4ANJ7dJCApfW8nWC0RElMW2siEKvZ79iplIPAaWV27oyBoerEflw==", + "license": "Apache-2", + "dependencies": { + "async": "~2.6.1", + "debug": "~4.3.1", + "eventemitter2": "^6.3.1", + "require-in-the-middle": "^5.0.0", + "semver": "~7.5.4", + "shimmer": "^1.2.0", + "signal-exit": "^3.0.3", + "tslib": "1.9.3" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/@pm2/io/node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/@pm2/io/node_modules/eventemitter2": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", + "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==", + "license": "MIT" + }, + "node_modules/@pm2/io/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==", + "license": "ISC", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@pm2/io/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "license": "ISC", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@pm2/io/node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "license": "ISC" + }, + "node_modules/@pm2/js-api": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@pm2/js-api/-/js-api-0.8.0.tgz", + "integrity": "sha512-nmWzrA/BQZik3VBz+npRcNIu01kdBhWL0mxKmP1ciF/gTcujPTQqt027N9fc1pK9ERM8RipFhymw7RcmCyOEYA==", + "license": "Apache-2", + "dependencies": { + "async": "^2.6.3", + "debug": "~4.3.1", + "eventemitter2": "^6.3.1", + "extrareqp2": "^1.0.0", + "ws": "^7.0.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/@pm2/js-api/node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/@pm2/js-api/node_modules/eventemitter2": { + "version": "6.4.9", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz", + "integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==", + "license": "MIT" + }, + "node_modules/@pm2/js-api/node_modules/ws": { + "version": "7.5.10", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz", + "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==", + "license": "MIT", + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/@pm2/pm2-version-check": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@pm2/pm2-version-check/-/pm2-version-check-1.0.4.tgz", + "integrity": "sha512-SXsM27SGH3yTWKc2fKR4SYNxsmnvuBQ9dd6QHtEWmiZ/VqaOYPAIlS8+vMcn27YLtAEBGvNRSh3TPNvtjZgfqA==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.1" + } + }, + "node_modules/@selderee/plugin-htmlparser2": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@selderee/plugin-htmlparser2/-/plugin-htmlparser2-0.11.0.tgz", + "integrity": "sha512-P33hHGdldxGabLFjPPpaTxVolMrzrcegejx+0GxjrIb9Zv48D8yAIA/QTDR2dFl7Uz7urX8aX6+5bCZslr+gWQ==", + "license": "MIT", + "dependencies": { + "domhandler": "^5.0.3", + "selderee": "^0.11.0" + }, + "funding": { + "url": "https://ko-fi.com/killymxi" + } + }, "node_modules/@sinclair/typebox": { - "version": "0.24.51", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", - "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==", - "dev": true + "version": "0.27.8", + "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz", + "integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==", + "dev": true, + "license": "MIT" }, "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==", + "license": "MIT", "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": "3.0.1", + "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-3.0.1.tgz", + "integrity": "sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "type-detect": "4.0.8" } }, "node_modules/@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-10.3.0.tgz", + "integrity": "sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "@sinonjs/commons": "^1.7.0" + "@sinonjs/commons": "^3.0.0" } }, "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": "8.0.0", + "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-8.0.0.tgz", + "integrity": "sha512-Bp8KUVlLp8ibJZrnvq2foVhP0IVX2CIprMJPK0vqGqgrDa0OHVKeZyBykqskkrdxV6yKBPmGasO8LVjAKR3Gew==", "dev": true, + "license": "BSD-3-Clause", "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, + "license": "BSD-3-Clause", + "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", "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", - "dev": true + "dev": true, + "license": "(Unlicense OR Apache-2.0)" }, "node_modules/@socket.io/component-emitter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", - "integrity": "sha512-+9jVqKhRSpsc591z5vX+X5Yyw+he/HCB4iQ/RYxw35CEPaY1gnsNE43nf9n9AaYjAQrTiI/mOwKUKdUs9vf7Xg==" + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.2.tgz", + "integrity": "sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==", + "license": "MIT" }, - "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==", - "optional": true, + "node_modules/@stylistic/eslint-plugin": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-1.8.1.tgz", + "integrity": "sha512-64My6I7uCcmSQ//427Pfg2vjSf9SDzfsGIWohNFgISMLYdC5BzJqDo647iDDJzSxINh3WTC0Ql46ifiKuOoTyA==", + "dev": true, + "license": "MIT", "dependencies": { - "defer-to-connect": "^1.0.1" + "@stylistic/eslint-plugin-js": "1.8.1", + "@stylistic/eslint-plugin-jsx": "1.8.1", + "@stylistic/eslint-plugin-plus": "1.8.1", + "@stylistic/eslint-plugin-ts": "1.8.1", + "@types/eslint": "^8.56.10" }, "engines": { - "node": ">=6" + "node": "^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" } }, - "node_modules/@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", + "node_modules/@stylistic/eslint-plugin-js": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-1.8.1.tgz", + "integrity": "sha512-c5c2C8Mos5tTQd+NWpqwEu7VT6SSRooAguFPMj1cp2RkTYl1ynKoXo8MWy3k4rkbzoeYHrqC2UlUzsroAN7wtQ==", "dev": true, + "license": "MIT", + "dependencies": { + "@types/eslint": "^8.56.10", + "acorn": "^8.11.3", + "escape-string-regexp": "^4.0.0", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1" + }, "engines": { - "node": ">= 10" + "node": "^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" } }, - "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==", + "node_modules/@stylistic/eslint-plugin-jsx": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-jsx/-/eslint-plugin-jsx-1.8.1.tgz", + "integrity": "sha512-k1Eb6rcjMP+mmjvj+vd9y5KUdWn1OBkkPLHXhsrHt5lCDFZxJEs0aVQzE5lpYrtVZVkpc5esTtss/cPJux0lfA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" + "@stylistic/eslint-plugin-js": "^1.8.1", + "@types/eslint": "^8.56.10", + "estraverse": "^5.3.0", + "picomatch": "^4.0.2" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" } }, - "node_modules/@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", + "node_modules/@stylistic/eslint-plugin-plus": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-plus/-/eslint-plugin-plus-1.8.1.tgz", + "integrity": "sha512-4+40H3lHYTN8OWz+US8CamVkO+2hxNLp9+CAjorI7top/lHqemhpJvKA1LD9Uh+WMY9DYWiWpL2+SZ2wAXY9fQ==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/types": "^7.0.0" + "@types/eslint": "^8.56.10", + "@typescript-eslint/utils": "^6.21.0" + }, + "peerDependencies": { + "eslint": "*" } }, - "node_modules/@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", + "node_modules/@stylistic/eslint-plugin-ts": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-ts/-/eslint-plugin-ts-1.8.1.tgz", + "integrity": "sha512-/q1m+ZuO1JHfiSF16EATFzv7XSJkc5W6DocfvH5o9oB6WWYFMF77fVoBWnKT3wGptPOc2hkRupRKhmeFROdfWA==", "dev": true, + "license": "MIT", "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" + "@stylistic/eslint-plugin-js": "1.8.1", + "@types/eslint": "^8.56.10", + "@typescript-eslint/utils": "^6.21.0" + }, + "engines": { + "node": "^16.0.0 || >=18.0.0" + }, + "peerDependencies": { + "eslint": ">=8.40.0" } }, - "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==", - "dev": true, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "license": "MIT", + "optional": true, "dependencies": { - "@babel/types": "^7.3.0" + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" } }, - "node_modules/@types/cookie": { - "version": "0.4.1", + "node_modules/@tootallnate/quickjs-emscripten": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz", + "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==", + "license": "MIT" + }, + "node_modules/@types/babel__core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz", + "integrity": "sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.20.7", + "@babel/types": "^7.20.7", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "node_modules/@types/babel__generator": { + "version": "7.6.8", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.8.tgz", + "integrity": "sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.4.tgz", + "integrity": "sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.20.6.tgz", + "integrity": "sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@babel/types": "^7.20.7" + } + }, + "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==", + "license": "MIT", + "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==" + "integrity": "sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==", + "license": "MIT" }, "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.17", + "resolved": "https://registry.npmjs.org/@types/cors/-/cors-2.8.17.tgz", + "integrity": "sha512-8CGDvrBj1zgo2qE+oS3pOCyYNqCPryMWY2bGfwA0dcfopWGgxs+78df0Rs3rc9THP4JkOhLsAa+15VdpAqkcUA==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.56.10", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.56.10.tgz", + "integrity": "sha512-Shavhk87gCtY2fhXDctcfS3e6FdxWkCx1iUZ9eEUbh7rTqlZT0/IzOkCOVt0fCjcFuZ9FPYfuezTBImfHCDBGQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.5.tgz", + "integrity": "sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-ZUxbzKl0IfJILTS6t7ip5fQQM/J3TJYubDm3nMbgubNNYS62eXeUpoLUC8/7fJNiFYHTrGPQn7hspDUzIHX3UA==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/minimatch": "*", + "@types/node": "*" + } }, "node_modules/@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", + "version": "4.1.9", + "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.9.tgz", + "integrity": "sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*" } }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.4.tgz", + "integrity": "sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==", + "license": "MIT", + "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", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", - "dev": true + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", + "integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==", + "dev": true, + "license": "MIT" }, "node_modules/@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz", + "integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==", "dev": true, + "license": "MIT", "dependencies": { "@types/istanbul-lib-coverage": "*" } }, "node_modules/@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz", + "integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==", "dev": true, + "license": "MIT", "dependencies": { "@types/istanbul-lib-report": "*" } }, "node_modules/@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true + "version": "7.0.15", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", + "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", + "dev": true, + "license": "MIT" }, - "node_modules/@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", - "dev": true + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true, + "license": "MIT" }, - "node_modules/@types/minimist": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", - "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", - "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==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/minimatch": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", + "integrity": "sha512-K0VQKziLUWkVKiRVrx4a40iPaxTUefQmjtkQofBkYRcoaaL/8rhwDWww9qWbrgicNOgnpIsMxyNIUM4+n6dUIA==", + "dev": true, + "license": "MIT" }, "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": "20.14.6", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.6.tgz", + "integrity": "sha512-JbA0XIJPL1IiNnU7PFxDXyfAwcwVVrOoqyzzyQTyMeVhBzkJVMSkC1LlVsRQ2lpqiY4n6Bb9oCS6lzDKVQxbZw==", + "license": "MIT", + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/@types/normalize-package-data": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", - "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", - "dev": true + "version": "2.4.4", + "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.4.tgz", + "integrity": "sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==", + "dev": true, + "license": "MIT" }, - "node_modules/@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true + "node_modules/@types/responselike": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.3.tgz", + "integrity": "sha512-H/+L+UkTV33uf49PH5pCAUBVPNj2nDBXTN+qS1dOwyyg24l3CcicicCA7ca+HMvJBZcFgl5r8e+RR6elsb4Lyw==", + "license": "MIT", + "optional": true, + "dependencies": { + "@types/node": "*" + } }, - "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==", - "dev": true + "node_modules/@types/semver": { + "version": "7.5.8", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.8.tgz", + "integrity": "sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==", + "dev": true, + "license": "MIT" }, "node_modules/@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.3.tgz", + "integrity": "sha512-9aEbYZ3TbYMznPdcdr3SmIrLXwC/AKZXQeCf9Pgao5CKb8CyHuEX5jzWPTkvregvhRJHcpRO6BFoGW9ycaOkYw==", + "dev": true, + "license": "MIT" }, "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.32", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.32.tgz", + "integrity": "sha512-xQ67Yc/laOG5uMfX/093MRlGGCIBzZMarVa+gfNKJxWAIgykYpVGkBdbqEzGDDfCrVUj6Hiff4mTZ5BA6TmAog==", "dev": true, + "license": "MIT", "dependencies": { "@types/yargs-parser": "*" } }, "node_modules/@types/yargs-parser": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", - "dev": true + "version": "21.0.3", + "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz", + "integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/@types/yauzl": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", + "integrity": "sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==", + "license": "MIT", + "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": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.21.0.tgz", + "integrity": "sha512-OwLUIWZJry80O99zvqXVEioyniJMa+d2GrqpUTqi5/v5D5rOrppJVBPa0yKCblcigC0/aYAzxxqQ1B+DS2RYsg==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.38.1", - "@typescript-eslint/visitor-keys": "5.38.1" + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -1456,12 +2214,13 @@ } }, "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": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.21.0.tgz", + "integrity": "sha512-1kFmZ1rOm5epu9NZEZm1kckCDGj5UJEf7P1kliH4LKu/RkwpsfqqGmY2OOcUs18lSlQBKLDYBOGxRVtrMN5lpg==", "dev": true, + "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -1469,21 +2228,23 @@ } }, "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": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.21.0.tgz", + "integrity": "sha512-6npJTkZcO+y2/kr+z0hc4HwNfrrP4kNYh57ek7yCNlrBjWQ1Y0OS7jiZTkgumrvkX5HkEKXFZkkdFNkaW2wmUQ==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "@typescript-eslint/types": "5.38.1", - "@typescript-eslint/visitor-keys": "5.38.1", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/visitor-keys": "6.21.0", "debug": "^4.3.4", "globby": "^11.1.0", "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" + "minimatch": "9.0.3", + "semver": "^7.5.4", + "ts-api-utils": "^1.0.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", @@ -1495,94 +2256,61 @@ } } }, - "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==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "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": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.21.0.tgz", + "integrity": "sha512-NfWVaC8HP9T8cbKQxHcsJBY5YE1O33+jpMwN45qzWWaPDZgLIbo12toGMWnmhvCpd3sIxkpDw3Wv1B3dYrbDQQ==", "dev": true, + "license": "MIT", "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", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" + "@eslint-community/eslint-utils": "^4.4.0", + "@types/json-schema": "^7.0.12", + "@types/semver": "^7.5.0", + "@typescript-eslint/scope-manager": "6.21.0", + "@typescript-eslint/types": "6.21.0", + "@typescript-eslint/typescript-estree": "6.21.0", + "semver": "^7.5.4" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/@typescript-eslint/utils/node_modules/estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true, - "engines": { - "node": ">=4.0" + "eslint": "^7.0.0 || ^8.0.0" } }, "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": "6.21.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.21.0.tgz", + "integrity": "sha512-JJtkDduxLi9bivAB+cYOVMtbkqdPOhZ+ZI5LC47MIRrDV4Yn2o+ZnW10Nkmr28xRpSpdJ6Sm42Hjf2+REYXm0A==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/types": "5.38.1", - "eslint-visitor-keys": "^3.3.0" + "@typescript-eslint/types": "6.21.0", + "eslint-visitor-keys": "^3.4.1" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^16.0.0 || >=18.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "dev": true + "node_modules/@ungap/structured-clone": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "license": "ISC" }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", + "license": "MIT", "dependencies": { "mime-types": "~2.1.34", "negotiator": "0.6.3" @@ -1592,9 +2320,10 @@ } }, "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.12.0", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.12.0.tgz", + "integrity": "sha512-RTvkC4w+KNXrM39/lWCUaG0IbRkWdCv7W/IOW9oU6SawyxulvkQy5HQPVTKxEjczcUvapcrw3cFx/60VN/NRNw==", + "license": "MIT", "bin": { "acorn": "bin/acorn" }, @@ -1602,49 +2331,32 @@ "node": ">=0.4.0" } }, - "node_modules/acorn-globals": { - "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": "^8.1.0", - "acorn-walk": "^8.0.2" - } - }, "node_modules/acorn-jsx": { "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "license": "MIT", "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, - "node_modules/acorn-walk": { - "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" - } - }, "node_modules/agent-base": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.1.tgz", + "integrity": "sha512-H0TSyFNDMomMNJQBn8wFV5YC/2eJ+VXECwOadZJT554xP6cODZHPX3H9QMQECxvrgiSOP1pHjy1sMWQVYJOUOA==", + "license": "MIT", "dependencies": { - "debug": "4" + "debug": "^4.3.4" }, "engines": { - "node": ">= 6.0.0" + "node": ">= 14" } }, "node_modules/ajv": { "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1656,11 +2368,36 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/amp": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/amp/-/amp-0.3.1.tgz", + "integrity": "sha512-OwIuC4yZaRogHKiuU5WlMR5Xk/jAcpPtawWL05Gj8Lvm2F6mwoJt4O/bHI+DHwG79vWd+8OFYM4/BzYqyRd3qw==", + "license": "MIT" + }, + "node_modules/amp-message": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/amp-message/-/amp-message-0.1.2.tgz", + "integrity": "sha512-JqutcFwoU1+jhv7ArgW38bqrE+LQdcRv4NxNw0mp0JHQyB6tXesWRjtYKlDgHRY2o3JE5UTaBGUK8kSWUdxWUg==", + "license": "MIT", + "dependencies": { + "amp": "0.3.1" + } + }, + "node_modules/ansi-colors": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.3.tgz", + "integrity": "sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/ansi-escapes": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", "dev": true, + "license": "MIT", "dependencies": { "type-fest": "^0.21.3" }, @@ -1676,6 +2413,7 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=10" }, @@ -1687,6 +2425,7 @@ "version": "5.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "license": "MIT", "engines": { "node": ">=8" } @@ -1695,6 +2434,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "license": "MIT", "dependencies": { "color-convert": "^2.0.1" }, @@ -1705,11 +2445,20 @@ "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, + "node_modules/ansis": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansis/-/ansis-3.2.0.tgz", + "integrity": "sha512-Yk3BkHH9U7oPyCN3gL5Tc7CpahG/+UFv/6UG03C311Vy9lzRmA5uoxDTpU9CO3rGHL6KzJz/pdDeXZCZ5Mu/Sg==", + "license": "ISC", + "engines": { + "node": ">=15" + } + }, "node_modules/anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz", + "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==", + "license": "ISC", "dependencies": { "normalize-path": "^3.0.0", "picomatch": "^2.0.4" @@ -1718,77 +2467,245 @@ "node": ">= 8" } }, + "node_modules/anymatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/are-docs-informative": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/are-docs-informative/-/are-docs-informative-0.0.2.tgz", + "integrity": "sha512-ixiS0nLNNG5jNQzgZJNoUpBKdo9yTYZMGJ+QgT2jmjR7G7+QHRCc4v6LQ3NgE7EBJq+o0ams3waJwkrlBom8Ig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/argparse": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" }, - "node_modules/array-differ": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", - "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", - "dev": true, + "node_modules/array-buffer-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.1.tgz", + "integrity": "sha512-ahC5W1xgou+KTXix4sAO8Ki12Q+jf4i0+tmk3sC+zgcynshkHxzpXdImBehiUYKKKDwvfFiJl1tZt6ewscS1Mg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "is-array-buffer": "^3.0.4" + }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" + "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==", + "license": "MIT" + }, + "node_modules/array-includes": { + "version": "3.1.8", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.8.tgz", + "integrity": "sha512-itaWrbYbqpGXkGhZPGUulwnhVf5Hpy1xiCFsGqyIGglbBxmG5vSjxQen3/WGOjPpNEv1RtBLKxbmVXm8HpJStQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } }, - "node_modules/arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", + "node_modules/array.prototype.findlastindex": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.5.tgz", + "integrity": "sha512-zfETvRFA8o7EiNn++N5f/kaCw221hrpGsDmcpndVupkPzEc1Wuf3VgC0qby1BbHs7f5DVYjgtEU2LLh5bqeGfQ==", "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-shim-unscopables": "^1.0.2" + }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", "dev": true, - "engines": { - "node": ">=8" + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.3.tgz", + "integrity": "sha512-bMxMKAjg13EBSVscxTaYA4mRc5t1UAXa2kXiGTNfZ079HIWXEkKmkgFrh/nJqamaLSrXO5H4WFFkPEaLJWbs3A==", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "es-abstract": "^1.22.3", + "es-errors": "^1.2.1", + "get-intrinsic": "^1.2.3", + "is-array-buffer": "^3.0.4", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/ast-types": { + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz", + "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==", + "license": "MIT", + "dependencies": { + "tslib": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ast-types/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "license": "0BSD" + }, + "node_modules/astral-regex": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" } }, + "node_modules/async": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", + "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==", + "license": "MIT" + }, "node_modules/asynckit": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" + "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==", + "license": "MIT" + }, + "node_modules/available-typed-arrays": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.7.tgz", + "integrity": "sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==", + "license": "MIT", + "dependencies": { + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/axios": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.1.3.tgz", - "integrity": "sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA==", + "version": "1.6.7", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.7.tgz", + "integrity": "sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==", + "license": "MIT", "dependencies": { - "follow-redirects": "^1.15.0", + "follow-redirects": "^1.15.4", "form-data": "^4.0.0", "proxy-from-env": "^1.1.0" } }, "node_modules/babel-jest": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.2.2.tgz", - "integrity": "sha512-kkq2QSDIuvpgfoac3WZ1OOcHsQQDU5xYk2Ql7tLdJ8BVAYbefEXal+NfS45Y5LVZA7cxC8KYcQMObpCt1J025w==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.7.0.tgz", + "integrity": "sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/transform": "^29.2.2", + "@jest/transform": "^29.7.0", "@types/babel__core": "^7.1.14", "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.2.0", + "babel-preset-jest": "^29.6.3", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "slash": "^3.0.0" @@ -1805,6 +2722,7 @@ "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "@babel/helper-plugin-utils": "^7.0.0", "@istanbuljs/load-nyc-config": "^1.0.0", @@ -1816,11 +2734,39 @@ "node": ">=8" } }, + "node_modules/babel-plugin-istanbul/node_modules/istanbul-lib-instrument": { + "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, + "license": "BSD-3-Clause", + "dependencies": { + "@babel/core": "^7.12.3", + "@babel/parser": "^7.14.7", + "@istanbuljs/schema": "^0.1.2", + "istanbul-lib-coverage": "^3.2.0", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-istanbul/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/babel-plugin-jest-hoist": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.2.0.tgz", - "integrity": "sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.6.3.tgz", + "integrity": "sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==", "dev": true, + "license": "MIT", "dependencies": { "@babel/template": "^7.3.3", "@babel/types": "^7.3.3", @@ -1836,6 +2782,7 @@ "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/plugin-syntax-async-generators": "^7.8.4", "@babel/plugin-syntax-bigint": "^7.8.3", @@ -1855,12 +2802,13 @@ } }, "node_modules/babel-preset-jest": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.2.0.tgz", - "integrity": "sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.6.3.tgz", + "integrity": "sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==", "dev": true, + "license": "MIT", "dependencies": { - "babel-plugin-jest-hoist": "^29.2.0", + "babel-plugin-jest-hoist": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0" }, "engines": { @@ -1873,17 +2821,14 @@ "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "node_modules/base-64": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz", - "integrity": "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA==" + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "license": "MIT" }, "node_modules/base64id": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==", + "license": "MIT", "engines": { "node": "^4.5.0 || >= 5.9" } @@ -1893,6 +2838,7 @@ "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", "dev": true, + "license": "MIT", "dependencies": { "safe-buffer": "5.1.2" }, @@ -1904,15 +2850,62 @@ "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 + "dev": true, + "license": "MIT" + }, + "node_modules/basic-ftp": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz", + "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/binary-extensions": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz", + "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/blessed": { + "version": "0.1.81", + "resolved": "https://registry.npmjs.org/blessed/-/blessed-0.1.81.tgz", + "integrity": "sha512-LoF5gae+hlmfORcG1M5+5XZi4LBmvlXTzwJWzUlPryN/SJdSflZvROM2TwkT0GMpq7oqT48NRd4GS7BiVBc5OQ==", + "license": "MIT", + "bin": { + "blessed": "bin/tput.js" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "license": "MIT" + }, + "node_modules/bodec": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/bodec/-/bodec-0.1.0.tgz", + "integrity": "sha512-Ylo+MAo5BDUq1KA3f3R/MFhh+g8cnHmo8bz3YPGhI1znrMaf77ol1sfvYJzsw3nTE+Y2GryfDxBaR+AqpAkEHQ==", + "license": "MIT" }, "node_modules/body-parser": { - "version": "1.20.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", - "integrity": "sha512-jWi7abTbYwajOytWCQc37VulmWiRae5RyTpaCyDcS5/lMdtwSz5lOpDE67srw/HYe35f1z3fDQw+3txg7gNtWw==", + "version": "1.20.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.2.tgz", + "integrity": "sha512-ml9pReCu3M61kGlqoTm2umSXTlRTuGTx0bfYj+uIUKKYycG5NtSbeetV3faSU6R7ajOPw0g/J1PvK4qNy7s5bA==", + "license": "MIT", "dependencies": { "bytes": "3.1.2", - "content-type": "~1.0.4", + "content-type": "~1.0.5", "debug": "2.6.9", "depd": "2.0.0", "destroy": "1.2.0", @@ -1920,7 +2913,7 @@ "iconv-lite": "0.4.24", "on-finished": "2.4.1", "qs": "6.11.0", - "raw-body": "2.5.1", + "raw-body": "2.5.2", "type-is": "~1.6.18", "unpipe": "1.0.0" }, @@ -1933,6 +2926,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -1941,6 +2935,7 @@ "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3" }, @@ -1951,39 +2946,42 @@ "node_modules/body-parser/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/boolean": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", + "license": "MIT", "optional": true }, "node_modules/brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "license": "MIT", "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" + "balanced-match": "^1.0.0" } }, "node_modules/braces": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", - "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", - "dev": true, + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz", + "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==", + "license": "MIT", "dependencies": { - "fill-range": "^7.0.1" + "fill-range": "^7.1.1" }, "engines": { "node": ">=8" } }, "node_modules/browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "version": "4.23.1", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.1.tgz", + "integrity": "sha512-TUfofFo/KsK/bWZ9TWQ5O26tsWW4Uhmt8IYklbnUa70udB6P2wA7w7o4PY4muaEPBQaAX+CEnmmIA41NVHtPVw==", "dev": true, "funding": [ { @@ -1993,13 +2991,18 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" + "caniuse-lite": "^1.0.30001629", + "electron-to-chromium": "^1.4.796", + "node-releases": "^2.0.14", + "update-browserslist-db": "^1.0.16" }, "bin": { "browserslist": "cli.js" @@ -2013,6 +3016,7 @@ "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", "dev": true, + "license": "Apache-2.0", "dependencies": { "node-int64": "^0.4.0" } @@ -2021,6 +3025,7 @@ "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "license": "MIT", "optional": true, "engines": { "node": "*" @@ -2030,65 +3035,73 @@ "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 + "license": "MIT" + }, + "node_modules/builtin-modules": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", + "integrity": "sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, "node_modules/bytes": { "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "license": "MIT", "engines": { "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==", + "license": "MIT", + "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.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "license": "MIT", "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" + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" }, "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, + "node_modules/call-bind": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", + "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", + "license": "MIT", "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "set-function-length": "^1.2.1" }, - "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/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -2098,6 +3111,7 @@ "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "license": "MIT", "engines": { "node": ">=6" } @@ -2107,31 +3121,15 @@ "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, - "node_modules/camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", - "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "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.30001636", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001636.tgz", + "integrity": "sha512-bMg2vmr8XBsbL6Lr0UHXy/21m84FTxDLWn2FSqMd5PrlbMxwJlQnC2YWYxVgp66PZE+BBNF2jYQUBKCo1FDeZg==", "dev": true, "funding": [ { @@ -2141,13 +3139,19 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } - ] + ], + "license": "CC-BY-4.0" }, "node_modules/chalk": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "license": "MIT", "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -2164,58 +3168,237 @@ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" } }, - "node_modules/charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", + "node_modules/charm": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/charm/-/charm-0.1.2.tgz", + "integrity": "sha512-syedaZ9cPe7r3hoQA9twWYKu5AIyCswN5+szkmPBe9ccdLrj4bYaCnLVPTLd2kgVRc7+zoX4tyPgRnFKCj5YjQ==", + "license": "MIT/X11" + }, + "node_modules/chokidar": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", + "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==", + "license": "MIT", + "dependencies": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "glob-parent": "~5.1.2", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.6.0" + }, "engines": { - "node": "*" + "node": ">= 8.10.0" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + }, + "optionalDependencies": { + "fsevents": "~2.3.2" + } + }, + "node_modules/chokidar/node_modules/glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "license": "ISC", + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" } }, "node_modules/ci-info": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.5.0.tgz", - "integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==", - "dev": true + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.0.0.tgz", + "integrity": "sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } }, "node_modules/cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "dev": true + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.3.1.tgz", + "integrity": "sha512-a3KdPAANPbNE4ZUv9h6LckSl9zLsYOP4MBmhIPkRaeyybt+r4UghLvq+xw/YwUcC1gqylCkL4rdVs3Lwupjm4Q==", + "dev": true, + "license": "MIT" }, "node_modules/clarinet": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/clarinet/-/clarinet-0.12.5.tgz", - "integrity": "sha512-4833ySquSUW91fnPaYI94LX3OdnyfwD8/NrMi6a4Kt6EmOsphLWmEzx9bZPqO9+DtQzSv2s3WSYNLsrXt59FKg==", + "version": "0.12.6", + "resolved": "https://registry.npmjs.org/clarinet/-/clarinet-0.12.6.tgz", + "integrity": "sha512-0FR+TrvLbYHLjhzs9oeIbd3yfZmd4u2DzYQEjUTm2dNfh4Y/9RIRWPjsm3aBtrVEpjKI7+lWa4ouqEXoml84mQ==", + "license": "BSD-2-Clause", "engines": { "chrome": ">=16.0.912", "firefox": ">=0.8.0", "node": ">=0.3.6" } }, - "node_modules/cliui": { - "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==", + "node_modules/clean-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clean-regexp/-/clean-regexp-1.0.0.tgz", + "integrity": "sha512-GfisEZEJvzKrmGWkvfhgzcz/BllN1USeqD2V6tg14OAOgaCD2Z/PUEuxnAZ/nPvmaHRG7a8y77p1T/IRQ4D1Hw==", "dev": true, + "license": "MIT", "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" + "escape-string-regexp": "^1.0.5" }, "engines": { - "node": ">=12" + "node": ">=4" } }, - "node_modules/clone-response": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "node_modules/clean-regexp/node_modules/escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/cli-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", + "dev": true, + "license": "MIT", + "dependencies": { + "restore-cursor": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cli-tableau": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/cli-tableau/-/cli-tableau-2.0.1.tgz", + "integrity": "sha512-he+WTicka9cl0Fg/y+YyxcN6/bfQ/1O3QmgxRXDhABKqLzvoOSM4fMzp39uMyLBulAFuywD2N7UaoQE7WaADxQ==", + "dependencies": { + "chalk": "3.0.0" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/cli-tableau/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cli-truncate": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-4.0.0.tgz", + "integrity": "sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==", + "dev": true, + "license": "MIT", + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^7.0.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/cliui": { + "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, + "license": "ISC", + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/cliui/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/cliui/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/cliui/node_modules/wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "license": "MIT", "optional": true, "dependencies": { "mimic-response": "^1.0.0" @@ -2229,21 +3412,24 @@ "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", "dev": true, + "license": "MIT", "engines": { "iojs": ">= 1.0.0", "node": ">= 0.12.0" } }, "node_modules/collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.2.tgz", + "integrity": "sha512-lHl4d5/ONEbLlJvaJNtsF/Lz+WvB07u2ycqTYbdrq7UypDXailES4valYb2eWiJFxZlVmpGekfqoxQhzyFdT4Q==", + "dev": true, + "license": "MIT" }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "license": "MIT", "dependencies": { "color-name": "~1.1.4" }, @@ -2254,26 +3440,28 @@ "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "license": "MIT" }, "node_modules/colord": { "version": "2.9.3", "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", - "dev": true + "dev": true, + "license": "MIT" }, - "node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "engines": { - "node": ">=0.1.90" - } + "node_modules/colorette": { + "version": "2.0.20", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz", + "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==", + "dev": true, + "license": "MIT" }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", + "license": "MIT", "dependencies": { "delayed-stream": "~1.0.0" }, @@ -2281,11 +3469,21 @@ "node": ">= 0.8" } }, + "node_modules/commander": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz", + "integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==", + "license": "MIT", + "engines": { + "node": ">= 6" + } + }, "node_modules/comment-parser": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz", - "integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==", + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.4.1.tgz", + "integrity": "sha512-buhp5kePrmda3vhc5B9t7pUQXAb2Tnd0qgpkIhPhkHXxJpiPJ11H0ZEU0oBpJ2QztSbzG/ZxMj/CHsYJqRHmyg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 12.0.0" } @@ -2293,49 +3491,27 @@ "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" - } + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "license": "MIT" }, "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.2", + "resolved": "https://registry.npmjs.org/console-stamp/-/console-stamp-3.1.2.tgz", + "integrity": "sha512-ab66x3NxOTxPuq71dI6gXEiw2X6ql4Le5gZz0bm7FW3FSCB00eztra/oQUuCoCGlsyKOxtULnHwphzMrRtzMBg==", + "license": "MIT", "dependencies": { "chalk": "^4.1.2", "dateformat": "^4.6.3" }, "engines": { - "node": ">=10" + "node": ">=12" } }, "node_modules/content-disposition": { "version": "0.5.4", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", + "license": "MIT", "dependencies": { "safe-buffer": "5.2.1" }, @@ -2344,32 +3520,26 @@ } }, "node_modules/content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", + "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, "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==", + "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, - "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==", - "dev": true + "license": "MIT" }, "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.6.0.tgz", + "integrity": "sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -2377,18 +3547,28 @@ "node_modules/cookie-signature": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" + "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", + "license": "MIT" }, - "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/core-js-compat": { + "version": "3.37.1", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.37.1.tgz", + "integrity": "sha512-9TNiImhKvQqSUkOvk/mMRZzOANTiEVC7WaBNhHcKM7x+/5E1l5NvsysR19zuDQScE8k+kfQXWRN3AtS/eOSHpg==", + "dev": true, + "license": "MIT", + "dependencies": { + "browserslist": "^4.23.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } }, "node_modules/cors": { "version": "2.8.5", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "license": "MIT", "dependencies": { "object-assign": "^4", "vary": "^1" @@ -2398,25 +3578,65 @@ } }, "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": "9.0.0", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.0.tgz", + "integrity": "sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==", "dev": true, + "license": "MIT", "dependencies": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" + "env-paths": "^2.2.1", + "import-fresh": "^3.3.0", + "js-yaml": "^4.1.0", + "parse-json": "^5.2.0" }, "engines": { - "node": ">=10" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/d-fischer" + }, + "peerDependencies": { + "typescript": ">=4.9.5" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, + "node_modules/create-jest": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/create-jest/-/create-jest-29.7.0.tgz", + "integrity": "sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "prompts": "^2.0.1" + }, + "bin": { + "create-jest": "bin/create-jest.js" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/croner": { + "version": "4.1.97", + "resolved": "https://registry.npmjs.org/croner/-/croner-4.1.97.tgz", + "integrity": "sha512-/f6gpQuxDaqXu+1kwQYSckUglPaOrHdbIlBAu0YuW8/Cdb45XwXYNUBXg3r/9Mo6n540Kn/smKcZWko5x99KrQ==", + "license": "MIT" + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "license": "MIT", "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", @@ -2426,21 +3646,28 @@ "node": ">= 8" } }, - "node_modules/crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", + "node_modules/css-functions-list": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.2.2.tgz", + "integrity": "sha512-c+N0v6wbKVxTu5gOBBFkr9BEdBWaqqjQeiJ8QvSRIJOf+UxlJh930m8e6/WNeODIK0mYLFkoONrnj16i2EcvfQ==", + "dev": true, + "license": "MIT", "engines": { - "node": "*" + "node": ">=12 || >=16" } }, - "node_modules/css-functions-list": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.1.0.tgz", - "integrity": "sha512-/9lCvYZaUbBGvYUgYGFJ4dcYiyqdhSjG7IPVluoV8A1ILjkF7ilmhp1OGUz8n+nmBcu0RNrQAzgD8B6FJbrt2w==", + "node_modules/css-tree": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-2.3.1.tgz", + "integrity": "sha512-6Fv1DV/TYw//QF5IzQdqsNDjx/wc8TrMBZsqjL9eW01tWb7R7k/mq+/VXfJCl7SoD5emsJop9cOByJZfs8hYIw==", "dev": true, + "license": "MIT", + "dependencies": { + "mdn-data": "2.0.30", + "source-map-js": "^1.0.1" + }, "engines": { - "node": ">=12.22" + "node": "^10 || ^12.20.0 || ^14.13.0 || >=15.0.0" } }, "node_modules/cssesc": { @@ -2448,6 +3675,7 @@ "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", "dev": true, + "license": "MIT", "bin": { "cssesc": "bin/cssesc" }, @@ -2455,149 +3683,238 @@ "node": ">=4" } }, - "node_modules/cssom": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", - "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", - "dev": true - }, "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.0.1.tgz", + "integrity": "sha512-8ZYiJ3A/3OkDd093CBT/0UKDWry7ak4BdPTFP2+QEP7cmhouyq/Up709ASSj2cK02BbZiMgk7kYjZNS4QP5qrQ==", "dev": true, + "license": "MIT", "dependencies": { - "cssom": "~0.3.6" + "rrweb-cssom": "^0.6.0" }, "engines": { - "node": ">=8" + "node": ">=18" } }, - "node_modules/cssstyle/node_modules/cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true + "node_modules/cssstyle/node_modules/rrweb-cssom": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.6.0.tgz", + "integrity": "sha512-APM0Gt1KoXBz0iIkkdB/kfvGOwC4UuJFeG/c+yV7wSc7q96cG/kJ0HiYCnzivD9SB53cLV1MlHFNfOuPaadYSw==", + "dev": true, + "license": "MIT" + }, + "node_modules/culvert": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/culvert/-/culvert-0.1.2.tgz", + "integrity": "sha512-yi1x3EAWKjQTreYWeSd98431AV+IEE0qoDyOoaHJ7KJ21gv6HtBXHVLX74opVSGqcR8/AbjJBHAHpcOy2bj5Gg==", + "license": "MIT" + }, + "node_modules/data-uri-to-buffer": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz", + "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==", + "license": "MIT", + "engines": { + "node": ">= 14" + } }, "node_modules/data-urls": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", - "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-5.0.0.tgz", + "integrity": "sha512-ZYP5VBHshaDAiVZxjbRVcFJpc+4xGgT0bK3vzy1HLN8jTO975HEbuYzZJcHoQEY5K1a0z8YayJkyVETa08eNTg==", "dev": true, + "license": "MIT", "dependencies": { - "abab": "^2.0.6", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^11.0.0" + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0" }, "engines": { - "node": ">=12" - } - }, - "node_modules/dateformat": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", - "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", - "engines": { - "node": "*" + "node": ">=18" } }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "node_modules/data-view-buffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-buffer/-/data-view-buffer-1.0.1.tgz", + "integrity": "sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==", + "license": "MIT", "dependencies": { - "ms": "2.1.2" + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" }, "engines": { - "node": ">=6.0" + "node": ">= 0.4" }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "dev": true, + "node_modules/data-view-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/data-view-byte-length/-/data-view-byte-length-1.0.1.tgz", + "integrity": "sha512-4J7wRJD3ABAzr8wP+OcIcqq2dlUKp4DVflx++hs5h5ZKydWMI6/D/fAot+yh6g2tHh8fLFTvNOaVN357NvSrOQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "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==", - "dev": true, + "node_modules/data-view-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/data-view-byte-offset/-/data-view-byte-offset-1.0.0.tgz", + "integrity": "sha512-t/Ygsytq+R995EJ5PZlD4Cu56sWa8InXySaViRzw9apusqsOO2bQP+SbYzAhR0pFKoB+43lYy8rWban9JSuXnA==", + "license": "MIT", "dependencies": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-data-view": "^1.0.1" }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/decamelize-keys/node_modules/map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", - "dev": true, + "node_modules/dateformat": { + "version": "4.6.3", + "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", + "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==", + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": "*" + } + }, + "node_modules/dayjs": { + "version": "1.11.11", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.11.tgz", + "integrity": "sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==", + "license": "MIT" + }, + "node_modules/debug": { + "version": "4.3.5", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.5.tgz", + "integrity": "sha512-pt0bNEmneDIvdL1Xsd9oDQ/wrQRkXDT4AUWlNZNPKvW5x/jyO9VFXkJUP07vQ2upmw5PlaITaPKc31jK13V+jg==", + "license": "MIT", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "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==", - "dev": true + "version": "10.4.3", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz", + "integrity": "sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA==", + "dev": true, + "license": "MIT" }, "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==", + "license": "MIT", "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==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.5.3.tgz", + "integrity": "sha512-NHQtfOOW68WD8lgypbLA5oT+Bt0xXJhiYvoR6SmmNXZfpzOGXwdKWmcwG8N7PwVVWV3eF/68nmD9BaJSsTBhyQ==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "babel-plugin-macros": "^3.1.0" + }, + "peerDependenciesMeta": { + "babel-plugin-macros": { + "optional": true + } + } }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" + "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", + "license": "MIT" }, "node_modules/deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true, + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", + "integrity": "sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==", + "license": "MIT", "engines": { "node": ">=0.10.0" } }, "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 + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "license": "MIT", + "optional": true, + "engines": { + "node": ">=10" + } }, - "node_modules/define-properties": { + "node_modules/define-data-property": { "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", - "optional": true, + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", + "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", + "license": "MIT", + "dependencies": { + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "gopd": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "license": "MIT", "dependencies": { + "define-data-property": "^1.0.1", "has-property-descriptors": "^1.0.0", "object-keys": "^1.1.1" }, @@ -2608,10 +3925,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/degenerator": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz", + "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==", + "license": "MIT", + "dependencies": { + "ast-types": "^0.13.4", + "escodegen": "^2.1.0", + "esprima": "^4.0.1" + }, + "engines": { + "node": ">= 14" + } + }, "node_modules/delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==", + "license": "MIT", "engines": { "node": ">=0.4.0" } @@ -2620,6 +3952,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -2628,16 +3961,28 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "license": "MIT", "engines": { "node": ">= 0.8", "npm": "1.2.8000 || >= 1.4.16" } }, + "node_modules/detect-indent": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-6.1.0.tgz", + "integrity": "sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/detect-newline": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -2646,40 +3991,34 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "license": "MIT", "optional": true }, "node_modules/diff": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", - "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", - "dev": true, + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.3.1" } }, "node_modules/diff-sequences": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.2.0.tgz", - "integrity": "sha512-413SY5JpYeSBZxmenGEmCVQ8mCgtFJF0w9PROdaS6z987XC2Pd2GOKqOITLtMftmyFZqgtCOb/QA7/Z3ZXfzIw==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.6.3.tgz", + "integrity": "sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==", "dev": true, + "license": "MIT", "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==", - "dependencies": { - "base-64": "^0.1.0", - "md5": "^2.3.0" - } - }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==", "dev": true, + "license": "MIT", "dependencies": { "path-type": "^4.0.0" }, @@ -2691,6 +4030,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "license": "Apache-2.0", "dependencies": { "esutils": "^2.0.2" }, @@ -2698,58 +4038,99 @@ "node": ">=6.0.0" } }, - "node_modules/domexception": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", - "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", - "dev": true, + "node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "license": "MIT", "dependencies": { - "webidl-conversions": "^7.0.0" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "BSD-2-Clause" + }, + "node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "license": "BSD-2-Clause", + "dependencies": { + "domelementtype": "^2.3.0" }, "engines": { - "node": ">=12" + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" } }, - "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/domutils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.1.0.tgz", + "integrity": "sha512-H78uMmQtI2AhgDJjWeQmHwJJ2bLPD3GMmO7Zja/ZZh84wkm+4ut+IUnUdRa8uCGX88DiVx1j6FRe1XfxEgjEZA==", + "license": "BSD-2-Clause", + "dependencies": { + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } }, "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==" + "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", + "license": "MIT" }, "node_modules/electron": { - "version": "19.1.3", - "resolved": "https://registry.npmjs.org/electron/-/electron-19.1.3.tgz", - "integrity": "sha512-P2kfFc8UqVvPHE1w9qTZSPNpfOqd+CK34K3wBqJwokzYdVBLsVkbIoLxyByjJ/cU35WaeCL5bsI8kXALfPvebw==", + "version": "31.0.1", + "resolved": "https://registry.npmjs.org/electron/-/electron-31.0.1.tgz", + "integrity": "sha512-2eBcp4iqLkTsml6mMq+iqrS5u3kJ/2mpOLP7Mj7lo0uNK3OyfNqRS9z1ArsHjBF2/HV250Te/O9nKrwQRTX/+g==", "hasInstallScript": true, + "license": "MIT", "optional": true, "dependencies": { - "@electron/get": "^1.14.1", - "@types/node": "^16.11.26", - "extract-zip": "^1.0.3" + "@electron/get": "^2.0.0", + "@types/node": "^20.9.0", + "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==", - "dev": true + "version": "1.4.806", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.806.tgz", + "integrity": "sha512-nkoEX2QIB8kwCOtvtgwhXWy2IHVcOLQZu9Qo36uaGB835mdX/h8uLRlosL6QIhLVUnAiicXRW00PwaPZC74Nrg==", + "dev": true, + "license": "ISC" }, "node_modules/emittery": { "version": "0.13.1", "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12" }, @@ -2758,15 +4139,17 @@ } }, "node_modules/emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true + "version": "10.3.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.3.0.tgz", + "integrity": "sha512-QpLs9D9v9kArv4lfDEgg1X/gN5XLnf/A6l9cs8SPZLRZR3ZkY9+kwIQTxm+fsSej5UMYGE8fdoaZVIBlqG0XTw==", + "dev": true, + "license": "MIT" }, "node_modules/encodeurl": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==", + "license": "MIT", "engines": { "node": ">= 0.8" } @@ -2775,15 +4158,17 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "devOptional": true, + "license": "MIT", + "optional": true, "dependencies": { "once": "^1.4.0" } }, "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.5.5", + "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-6.5.5.tgz", + "integrity": "sha512-C5Pn8Wk+1vKBoHghJODM63yk8MvrO9EWZUfkAt5HAqIgPE4/8FF0PEGHXtEd40l223+cE5ABWuPzm38PHFXfMA==", + "license": "MIT", "dependencies": { "@types/cookie": "^0.4.1", "@types/cors": "^2.8.12", @@ -2793,17 +4178,18 @@ "cookie": "~0.4.1", "cors": "~2.8.5", "debug": "~4.3.1", - "engine.io-parser": "~5.0.3", - "ws": "~8.2.3" + "engine.io-parser": "~5.2.1", + "ws": "~8.17.1" }, "engines": { - "node": ">=10.0.0" + "node": ">=10.2.0" } }, "node_modules/engine.io-parser": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz", - "integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==", + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.2.2.tgz", + "integrity": "sha512-RcyUFKA93/CXH20l4SoVvzZfrSDMOTUS3bWVpTt2FuFP+XYrL8i8oonHP7WInRyVHXh0n/ORtoeiE1os+8qkSw==", + "license": "MIT", "engines": { "node": ">=10.0.0" } @@ -2812,35 +4198,28 @@ "version": "0.4.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, - "node_modules/engine.io/node_modules/ws": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" + "node_modules/enquirer": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/enquirer/-/enquirer-2.3.6.tgz", + "integrity": "sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==", + "license": "MIT", + "dependencies": { + "ansi-colors": "^4.1.1" }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } + "engines": { + "node": ">=8.6" } }, "node_modules/entities": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", - "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", - "dev": true, + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", "engines": { "node": ">=0.12" }, @@ -2852,167 +4231,288 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "optional": true, + "devOptional": true, + "license": "MIT", "engines": { "node": ">=6" } }, + "node_modules/envsub": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/envsub/-/envsub-4.1.0.tgz", + "integrity": "sha512-B44hta3xNFu6+zDhOha1TIrZkQHGDO3G5K8D2sJIkm/s3XyQjxWBGp1B+b/Y74Go1PqMP+cp8moPR4JullnD9Q==", + "license": "ISC", + "dependencies": { + "bluebird": "^3.7.2", + "chalk": "^3.0.0", + "commander": "^4.0.1", + "diff": "^4.0.1", + "handlebars": "^4.5.3", + "lodash": "^4.17.15", + "replace-last": "^1.2.6", + "string.prototype.matchall": "^4.0.8" + }, + "bin": { + "envsub": "bin/envsub.js", + "envsubh": "bin/envsubh.js" + } + }, + "node_modules/envsub/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/error-ex": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", "dev": true, + "license": "MIT", "dependencies": { "is-arrayish": "^0.2.1" } }, - "node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "optional": true - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "node_modules/escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "node_modules/es-abstract": { + "version": "1.23.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.23.3.tgz", + "integrity": "sha512-e+HfNH61Bj1X9/jLc5v1owaLYuHdeHHSQlkhCBiTK8rBvKaULl/beGMxwrMXjpYrv4pz22BlY570vVePA2ho4A==", + "license": "MIT", + "dependencies": { + "array-buffer-byte-length": "^1.0.1", + "arraybuffer.prototype.slice": "^1.0.3", + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "data-view-buffer": "^1.0.1", + "data-view-byte-length": "^1.0.1", + "data-view-byte-offset": "^1.0.0", + "es-define-property": "^1.0.0", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "es-set-tostringtag": "^2.0.3", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.4", + "get-symbol-description": "^1.0.2", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2", + "has-proto": "^1.0.3", + "has-symbols": "^1.0.3", + "hasown": "^2.0.2", + "internal-slot": "^1.0.7", + "is-array-buffer": "^3.0.4", + "is-callable": "^1.2.7", + "is-data-view": "^1.0.1", + "is-negative-zero": "^2.0.3", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.3", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.13", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.5", + "regexp.prototype.flags": "^1.5.2", + "safe-array-concat": "^1.1.2", + "safe-regex-test": "^1.0.3", + "string.prototype.trim": "^1.2.9", + "string.prototype.trimend": "^1.0.8", + "string.prototype.trimstart": "^1.0.8", + "typed-array-buffer": "^1.0.2", + "typed-array-byte-length": "^1.0.1", + "typed-array-byte-offset": "^1.0.2", + "typed-array-length": "^1.0.6", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.15" + }, "engines": { - "node": ">=10" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", - "dev": true, + "node_modules/es-define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", + "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", + "license": "MIT", "dependencies": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1" - }, - "bin": { - "escodegen": "bin/escodegen.js", - "esgenerate": "bin/esgenerate.js" + "get-intrinsic": "^1.2.4" }, "engines": { - "node": ">=6.0" + "node": ">= 0.4" + } + }, + "node_modules/es-errors": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", + "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-object-atoms": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.0.0.tgz", + "integrity": "sha512-MZ4iQ6JwHOBQjahnjwaC1ZtIBH+2ohjamzAO3oaHcXYup7qxjF2fixyH+Q71voWHeOkI2q/TnJao/KfXYIZWbw==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0" }, - "optionalDependencies": { - "source-map": "~0.6.1" + "engines": { + "node": ">= 0.4" } }, - "node_modules/escodegen/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, + "node_modules/es-set-tostringtag": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.3.tgz", + "integrity": "sha512-3T8uNMC3OQTHkFUsFq8r/BwAXLHvU/9O9mE0fBc/MY5iq/8H7ncvO947LmYA6ldWw9Uh8Yhf25zu6n7nML5QWQ==", + "license": "MIT", "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" + "get-intrinsic": "^1.2.4", + "has-tostringtag": "^1.0.2", + "hasown": "^2.0.1" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 0.4" } }, - "node_modules/escodegen/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", "dev": true, + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "license": "MIT", "dependencies": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" }, "engines": { - "node": ">= 0.8.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/escodegen/node_modules/prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "license": "MIT", + "optional": true + }, + "node_modules/escalade": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz", + "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==", "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.8.0" + "node": ">=6" } }, - "node_modules/escodegen/node_modules/type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, + "node_modules/escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", + "license": "MIT" + }, + "node_modules/escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/escodegen": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz", + "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==", + "license": "BSD-2-Clause", "dependencies": { - "prelude-ls": "~1.1.2" + "esprima": "^4.0.1", + "estraverse": "^5.2.0", + "esutils": "^2.0.2" + }, + "bin": { + "escodegen": "bin/escodegen.js", + "esgenerate": "bin/esgenerate.js" }, "engines": { - "node": ">= 0.8.0" + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" } }, "node_modules/eslint": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.26.0.tgz", - "integrity": "sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg==", + "version": "8.57.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz", + "integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==", + "license": "MIT", "dependencies": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.11.6", + "@eslint-community/eslint-utils": "^4.2.0", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.4", + "@eslint/js": "8.57.0", + "@humanwhocodes/config-array": "^0.11.14", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "@ungap/structured-clone": "^1.2.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", + "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^6.0.1", "find-up": "^5.0.0", "glob-parent": "^6.0.2", - "globals": "^13.15.0", - "grapheme-splitter": "^1.0.4", + "globals": "^13.19.0", + "graphemer": "^1.4.0", "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", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "bin": { @@ -3025,188 +4525,440 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-config-prettier": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", - "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", "dev": true, - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" + "license": "MIT", + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" } }, - "node_modules/eslint-plugin-jest": { - "version": "27.1.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.1.3.tgz", - "integrity": "sha512-7DrIfYRQPa7JQd1Le8G/BJsfYHVUKQdJQ/6vULSp/4NjKZmSMJ/605G2hhScEra++SiH68zPEjLnrO74nHrMLg==", + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.1.tgz", + "integrity": "sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==", "dev": true, + "license": "MIT", "dependencies": { - "@typescript-eslint/utils": "^5.10.0" + "debug": "^3.2.7" }, "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" - }, - "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^5.0.0", - "eslint": "^7.0.0 || ^8.0.0" + "node": ">=4" }, "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { - "optional": true - }, - "jest": { + "eslint": { "optional": true } } }, - "node_modules/eslint-plugin-jsdoc": { - "version": "39.3.25", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.3.25.tgz", - "integrity": "sha512-7JiFOOaipz7Z7lNQ9sMJ6cdvclmVUwNYtFWGS3a0k0uEFcdZPPD64WOfENuyNHpl86C0AKIEPgOpZby5kd+pew==", + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", "dev": true, + "license": "MIT", "dependencies": { - "@es-joy/jsdoccomment": "~0.33.4", - "comment-parser": "1.3.1", - "debug": "^4.3.4", - "escape-string-regexp": "^4.0.0", - "esquery": "^1.4.0", - "semver": "^7.3.8", - "spdx-expression-parse": "^3.0.1" + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "dev": true, + "license": "MIT", + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" }, "engines": { - "node": "^14 || ^16 || ^17 || ^18 || ^19" + "node": ">=4" }, "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" } }, - "node_modules/eslint-plugin-jsdoc/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", "dev": true, + "license": "MIT", "dependencies": { - "lru-cache": "^6.0.0" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "license": "Apache-2.0", + "dependencies": { + "esutils": "^2.0.2" }, - "bin": { - "semver": "bin/semver.js" + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=10" + "node": "*" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver.js" } }, - "node_modules/eslint-plugin-prettier": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", - "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", + "node_modules/eslint-plugin-jest": { + "version": "28.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-28.6.0.tgz", + "integrity": "sha512-YG28E1/MIKwnz+e2H7VwYPzHUYU4aMa19w0yGcwXnnmJH6EfgHahTJ2un3IyraUxNfnz/KUhJAFXNNwWPo12tg==", "dev": true, + "license": "MIT", "dependencies": { - "prettier-linter-helpers": "^1.0.0" + "@typescript-eslint/utils": "^6.0.0 || ^7.0.0" }, "engines": { - "node": ">=12.0.0" + "node": "^16.10.0 || ^18.12.0 || >=20.0.0" }, "peerDependencies": { - "eslint": ">=7.28.0", - "prettier": ">=2.0.0" + "@typescript-eslint/eslint-plugin": "^6.0.0 || ^7.0.0", + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0", + "jest": "*" }, "peerDependenciesMeta": { - "eslint-config-prettier": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { "optional": true } } }, - "node_modules/eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", + "node_modules/eslint-plugin-jsdoc": { + "version": "48.2.12", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-48.2.12.tgz", + "integrity": "sha512-sO9sKkJx5ovWoRk9hV0YiNzXQ4Z6j27CqE/po2E3wddZVuy9wvKPSTiIhpxMTrP/qURvKayJIDB2+o9kyCW1Fw==", + "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" + "@es-joy/jsdoccomment": "~0.43.1", + "are-docs-informative": "^0.0.2", + "comment-parser": "1.4.1", + "debug": "^4.3.4", + "escape-string-regexp": "^4.0.0", + "esquery": "^1.5.0", + "semver": "^7.6.2", + "spdx-expression-parse": "^4.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": ">=18" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0 || ^9.0.0" } }, - "node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "node_modules/eslint-plugin-package-json": { + "version": "0.15.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-package-json/-/eslint-plugin-package-json-0.15.0.tgz", + "integrity": "sha512-XPPehRGjoN2YPnwH/Vo9GTBTTSoJ9uveqKr7tCDskgKwXjtAfMIw4NyGvmTq4GLlnl+cw0VeKTC75863f2DBFw==", + "dev": true, + "license": "MIT", + "dependencies": { + "detect-indent": "6.1.0", + "detect-newline": "3.1.0", + "package-json-validator": "^0.6.3", + "semver": "^7.5.4", + "sort-object-keys": "^1.1.3", + "sort-package-json": "^1.57.0", + "validate-npm-package-name": "^5.0.0" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "eslint": ">=8.0.0", + "jsonc-eslint-parser": "^2.0.0" + } + }, + "node_modules/eslint-plugin-unicorn": { + "version": "54.0.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-unicorn/-/eslint-plugin-unicorn-54.0.0.tgz", + "integrity": "sha512-XxYLRiYtAWiAjPv6z4JREby1TAE2byBC7wlh0V4vWDCpccOSU1KovWV//jqPXF6bq3WKxqX9rdjoRQ1EhdmNdQ==", + "dev": true, + "license": "MIT", "dependencies": { - "eslint-visitor-keys": "^2.0.0" + "@babel/helper-validator-identifier": "^7.24.5", + "@eslint-community/eslint-utils": "^4.4.0", + "@eslint/eslintrc": "^3.0.2", + "ci-info": "^4.0.0", + "clean-regexp": "^1.0.0", + "core-js-compat": "^3.37.0", + "esquery": "^1.5.0", + "indent-string": "^4.0.0", + "is-builtin-module": "^3.2.1", + "jsesc": "^3.0.2", + "pluralize": "^8.0.0", + "read-pkg-up": "^7.0.1", + "regexp-tree": "^0.1.27", + "regjsparser": "^0.10.0", + "semver": "^7.6.1", + "strip-indent": "^3.0.0" }, "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + "node": ">=18.18" }, "funding": { - "url": "https://github.com/sponsors/mysticatea" + "url": "https://github.com/sindresorhus/eslint-plugin-unicorn?sponsor=1" }, "peerDependencies": { - "eslint": ">=5" + "eslint": ">=8.56.0" } }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "node_modules/eslint-plugin-unicorn/node_modules/@eslint/eslintrc": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.1.0.tgz", + "integrity": "sha512-4Bfj15dVJdoy3RfZmmo86RK1Fwzn6SstsvK9JS+BaVKqC6QQQQyXekNaC+g+LKNgkQ+2VhGAzm6hO40AhMR3zQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^10.0.1", + "globals": "^14.0.0", + "ignore": "^5.2.0", + "import-fresh": "^3.2.1", + "js-yaml": "^4.1.0", + "minimatch": "^3.1.2", + "strip-json-comments": "^3.1.1" + }, "engines": { - "node": ">=10" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "node_modules/eslint-plugin-unicorn/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-unicorn/node_modules/eslint-visitor-keys": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.0.0.tgz", + "integrity": "sha512-OtIRv/2GyiF6o/d8K7MYKKbXrOUBIK6SfkIRM4Z0dY3w+LiQ0vy3F57m0Z71bjbyeiWFiHJ8brqnmE6H6/jEuw==", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, - "node_modules/espree": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", - "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", + "node_modules/eslint-plugin-unicorn/node_modules/espree": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/espree/-/espree-10.1.0.tgz", + "integrity": "sha512-M1M6CpiE6ffoigIOWYO9UDP8TMUw9kqb21tf+08IgDYjCsOvCuDt4jQcZmoYxx+w7zlKw9/N0KXfto+I8/FrXA==", + "dev": true, + "license": "BSD-2-Clause", "dependencies": { - "acorn": "^8.8.0", + "acorn": "^8.12.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^4.0.0" }, "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^18.18.0 || ^20.9.0 || >=21.1.0" }, "funding": { "url": "https://opencollective.com/eslint" } }, - "node_modules/esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "node_modules/eslint-plugin-unicorn/node_modules/globals": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz", + "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==", "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "node_modules/eslint-plugin-unicorn/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", "dependencies": { - "estraverse": "^5.1.0" + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=0.10" + "node": "*" } }, - "node_modules/esrecurse": { + "node_modules/eslint-scope": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", + "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "license": "BSD-2-Clause", + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "license": "Apache-2.0", + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/espree": { + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "license": "BSD-2-Clause", + "dependencies": { + "acorn": "^8.9.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.4.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "license": "BSD-2-Clause", + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz", + "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==", + "license": "BSD-3-Clause", + "dependencies": { + "estraverse": "^5.1.0" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/esrecurse": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", + "license": "BSD-2-Clause", "dependencies": { "estraverse": "^5.2.0" }, @@ -3218,6 +4970,7 @@ "version": "5.3.0", "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "license": "BSD-2-Clause", "engines": { "node": ">=4.0" } @@ -3226,6 +4979,7 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "license": "BSD-2-Clause", "engines": { "node": ">=0.10.0" } @@ -3234,15 +4988,30 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", + "license": "MIT", "engines": { "node": ">= 0.6" } }, + "node_modules/eventemitter2": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-5.0.1.tgz", + "integrity": "sha512-5EM1GHXycJBS6mauYAbVKT1cVs7POKWb2NXD4Vyt8dDqeZa7LaDK1/sjtL+Zb0lzTpSNil4596Dyu97hz37QLg==", + "license": "MIT" + }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "dev": true, + "license": "MIT" + }, "node_modules/execa": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", "dev": true, + "license": "MIT", "dependencies": { "cross-spawn": "^7.0.3", "get-stream": "^6.0.0", @@ -3266,6 +5035,7 @@ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -3283,32 +5053,34 @@ } }, "node_modules/expect": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.2.2.tgz", - "integrity": "sha512-hE09QerxZ5wXiOhqkXy5d2G9ar+EqOyifnCXCpMNu+vZ6DG9TJ6CO2c2kPDSLqERTTWrO7OZj8EkYHQqSd78Yw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/expect/-/expect-29.7.0.tgz", + "integrity": "sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/expect-utils": "^29.2.2", - "jest-get-type": "^29.2.0", - "jest-matcher-utils": "^29.2.2", - "jest-message-util": "^29.2.1", - "jest-util": "^29.2.1" + "@jest/expect-utils": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/express": { - "version": "4.18.2", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.2.tgz", - "integrity": "sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ==", + "version": "4.19.2", + "resolved": "https://registry.npmjs.org/express/-/express-4.19.2.tgz", + "integrity": "sha512-5T6nhjsT+EOMzuck8JjBHARTHfMht0POzlA60WV2pMD3gyXw2LZnZ+ueGdNxG+0calOJcWKbpFcuzLZ91YWq9Q==", + "license": "MIT", "dependencies": { "accepts": "~1.3.8", "array-flatten": "1.1.1", - "body-parser": "1.20.1", + "body-parser": "1.20.2", "content-disposition": "0.5.4", "content-type": "~1.0.4", - "cookie": "0.5.0", + "cookie": "0.6.0", "cookie-signature": "1.0.6", "debug": "2.6.9", "depd": "2.0.0", @@ -3344,16 +5116,18 @@ "resolved": "https://registry.npmjs.org/express-basic-auth/-/express-basic-auth-1.2.1.tgz", "integrity": "sha512-L6YQ1wQ/mNjVLAmK3AG1RK6VkokA1BIY6wmiH304Xtt/cLTps40EusZsU1Uop+v9lTDPxdtzbFmdXfFO3KEnwA==", "dev": true, + "license": "MIT", "dependencies": { "basic-auth": "^2.0.1" } }, "node_modules/express-ipfilter": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/express-ipfilter/-/express-ipfilter-1.3.1.tgz", - "integrity": "sha512-9WZC8wGkI6I6ygZNzuZ2MbFJiGoDXs1dM+E8LKtSP13pdgqrnkonWlgvvbxG3YZpa7Haz7Ndum9/J6qkj52OqA==", + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/express-ipfilter/-/express-ipfilter-1.3.2.tgz", + "integrity": "sha512-yMzCWGuVMnR8CFlsIC2spHWoQYp9vtyZXUgS/JdV5GOJgrz6zmKOEZsA4eF1XrxkOIVzaVk6yzTBk65pBhliNw==", + "license": "MIT", "dependencies": { - "ip": "^1.1.8", + "ip": "^2.0.1", "lodash": "^4.17.11", "proxy-addr": "^2.0.7", "range_check": "^2.0.4" @@ -3366,6 +5140,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -3373,54 +5148,58 @@ "node_modules/express/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "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==", + "license": "BSD-2-Clause", "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, + "node_modules/extrareqp2": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/extrareqp2/-/extrareqp2-1.0.0.tgz", + "integrity": "sha512-Gum0g1QYb6wpPJCVypWP3bbIuaibcFiJcpuPM10YSXp/tzqi84x9PJageob+eN4xVRIOto4wjSGNLyMD54D2xA==", + "license": "MIT", "dependencies": { - "ms": "2.0.0" + "follow-redirects": "^1.14.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", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "license": "MIT" }, "node_modules/fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.3.0.tgz", + "integrity": "sha512-VxPP4NqbUjj6MaAOafWeUn2cXWLcCtljklUtZf0Ind4XQ+QPtmA0b18zZy0jIQx+ExRVCR/ZQpBmik5lXshNsw==", + "dev": true, + "license": "Apache-2.0" }, "node_modules/fast-glob": { - "version": "3.2.12", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz", - "integrity": "sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==", + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz", + "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==", "dev": true, + "license": "MIT", "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", @@ -3437,6 +5216,7 @@ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", "dev": true, + "license": "ISC", "dependencies": { "is-glob": "^4.0.1" }, @@ -3444,29 +5224,39 @@ "node": ">= 6" } }, + "node_modules/fast-json-patch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/fast-json-patch/-/fast-json-patch-3.1.1.tgz", + "integrity": "sha512-vf6IHUX2SBcA+5/+4883dsIjpBTqmfBjmYiWK1savxQmFk4JfBMLa7ynTYOs1Rolp/T1betJxHiGD3g1Mn8lUQ==", + "license": "MIT" + }, "node_modules/fast-json-stable-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" + "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==", + "license": "MIT" }, "node_modules/fastest-levenshtein": { "version": "1.0.16", "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", "dev": true, + "license": "MIT", "engines": { "node": ">= 4.9.1" } }, "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.17.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz", + "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==", + "license": "ISC", "dependencies": { "reusify": "^1.0.4" } @@ -3476,14 +5266,22 @@ "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", "dev": true, + "license": "Apache-2.0", "dependencies": { "bser": "2.1.1" } }, + "node_modules/fclone": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/fclone/-/fclone-1.0.11.tgz", + "integrity": "sha512-GDqVQezKzRABdeqflsgMr7ktzgF9CyS+p2oe0jJqUY6izSSbhPIQJDpoU4PtGcD7VPM9xh/dVrTu6z1nwgmEGw==", + "license": "MIT" + }, "node_modules/fd-slicer": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", + "license": "MIT", "optional": true, "dependencies": { "pend": "~1.2.0" @@ -3493,6 +5291,7 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/feedme/-/feedme-2.0.2.tgz", "integrity": "sha512-0RNn0uLaSey8EThxgABR0T1Q47kSRatYnAXy1cfUc8/eypqXiAu38XGthuwwzb7mESCD9465k6Nym8D9AtB8HA==", + "license": "MIT", "dependencies": { "clarinet": "^0.12.4", "sax": "^1.2.4" @@ -3505,6 +5304,7 @@ "version": "6.0.1", "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "license": "MIT", "dependencies": { "flat-cache": "^3.0.4" }, @@ -3513,10 +5313,10 @@ } }, "node_modules/fill-range": { - "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, + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", + "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==", + "license": "MIT", "dependencies": { "to-regex-range": "^5.0.1" }, @@ -3528,6 +5328,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "license": "MIT", "dependencies": { "debug": "2.6.9", "encodeurl": "~1.0.2", @@ -3545,6 +5346,7 @@ "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", "dependencies": { "ms": "2.0.0" } @@ -3552,12 +5354,14 @@ "node_modules/finalhandler/node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" }, "node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "license": "MIT", "dependencies": { "locate-path": "^6.0.0", "path-exists": "^4.0.0" @@ -3570,11 +5374,13 @@ } }, "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.2.0.tgz", + "integrity": "sha512-CYcENa+FtcUKLmhhqyctpclsq7QF38pKjZHsGNiSQF5r4FtoKDWabFDl3hzaEQMvT1LHEysw5twgLvpYYb4vbw==", + "license": "MIT", "dependencies": { - "flatted": "^3.1.0", + "flatted": "^3.2.9", + "keyv": "^4.5.3", "rimraf": "^3.0.2" }, "engines": { @@ -3582,20 +5388,22 @@ } }, "node_modules/flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", + "integrity": "sha512-X8cqMLLie7KsNUDSdzeN8FYK9rEt4Dt67OsG/DNGnYTSDBG4uFAJFBnUeiV+zCVAvwFy56IjM9sH51jVaEhNxw==", + "license": "ISC" }, "node_modules/follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==", + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", "funding": [ { "type": "individual", "url": "https://github.com/sponsors/RubenVerborgh" } ], + "license": "MIT", "engines": { "node": ">=4.0" }, @@ -3605,10 +5413,20 @@ } } }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "license": "MIT", + "dependencies": { + "is-callable": "^1.1.3" + } + }, "node_modules/form-data": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "license": "MIT", "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", @@ -3622,6 +5440,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -3630,6 +5449,7 @@ "version": "0.5.2", "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==", + "license": "MIT", "engines": { "node": ">= 0.6" } @@ -3638,6 +5458,7 @@ "version": "8.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", + "license": "MIT", "optional": true, "dependencies": { "graceful-fs": "^4.2.0", @@ -3651,14 +5472,15 @@ "node_modules/fs.realpath": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "license": "ISC" }, "node_modules/fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", "hasInstallScript": true, + "license": "MIT", "optional": true, "os": [ "darwin" @@ -3668,15 +5490,47 @@ } }, "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", "dev": true, + "license": "MIT", "engines": { "node": ">=6.9.0" } @@ -3686,18 +5540,38 @@ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", "dev": true, + "license": "ISC", "engines": { "node": "6.* || 8.* || >= 10.*" } }, + "node_modules/get-east-asian-width": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.2.0.tgz", + "integrity": "sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", + "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", + "license": "MIT", "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3708,26 +5582,122 @@ "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=8.0.0" } }, "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==", + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "license": "MIT", "optional": true, "dependencies": { "pump": "^3.0.0" }, "engines": { - "node": ">=6" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.2.tgz", + "integrity": "sha512-g0QYk1dZBxGwk+Ngc+ltRH2IBp2f7zBkBMBJZCDerh6EhlhSR6+9irMCuT/09zD6qkarHUSn529sK/yL4S27mg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.5", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-uri": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.3.tgz", + "integrity": "sha512-BzUrJBS9EcUb4cFol8r4W3v1cPsSyajLSthNkz5BxbpDcHN5tIrM10E2eNvfnvBn3DaT3DUgx0OpsBKkaOpanw==", + "license": "MIT", + "dependencies": { + "basic-ftp": "^5.0.2", + "data-uri-to-buffer": "^6.0.2", + "debug": "^4.3.4", + "fs-extra": "^11.2.0" + }, + "engines": { + "node": ">= 14" + } + }, + "node_modules/get-uri/node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "license": "MIT", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, + "node_modules/get-uri/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "license": "MIT", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/get-uri/node_modules/universalify": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", + "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==", + "license": "MIT", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/git-hooks-list": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/git-hooks-list/-/git-hooks-list-1.0.3.tgz", + "integrity": "sha512-Y7wLWcrLUXwk2noSka166byGCvhMtDRpgHdzCno1UQv/n/Hegp++a2xBWJL1lJarnKD3SWaljD+0z1ztqxuKyQ==", + "dev": true, + "license": "MIT", + "funding": { + "url": "https://github.com/fisker/git-hooks-list?sponsor=1" } }, + "node_modules/git-node-fs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/git-node-fs/-/git-node-fs-1.0.0.tgz", + "integrity": "sha512-bLQypt14llVXBg0S0u8q8HmU7g9p3ysH+NvVlae5vILuUvs759665HvmR5+wb04KjHyjFcDRxdYb4kyNnluMUQ==", + "license": "MIT" + }, + "node_modules/git-sha1": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/git-sha1/-/git-sha1-0.1.2.tgz", + "integrity": "sha512-2e/nZezdVlyCopOCYHeW0onkbZg7xP1Ad6pndPy1rCygeRykefUS6r7oA5cJRGEFvseiaz5a/qUHFVX1dd6Isg==", + "license": "MIT" + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "license": "ISC", "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", @@ -3747,6 +5717,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "license": "ISC", "dependencies": { "is-glob": "^4.0.3" }, @@ -3754,36 +5725,44 @@ "node": ">=10.13.0" } }, - "node_modules/global-agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", - "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", - "optional": true, + "node_modules/glob/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "license": "MIT", "dependencies": { - "boolean": "^3.0.1", - "es6-error": "^4.1.1", - "matcher": "^3.0.0", - "roarr": "^2.15.3", - "semver": "^7.3.2", - "serialize-error": "^7.0.1" + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/glob/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" }, "engines": { - "node": ">=10.0" + "node": "*" } }, - "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==", + "node_modules/global-agent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", + "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", + "license": "BSD-3-Clause", "optional": true, "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" + "boolean": "^3.0.1", + "es6-error": "^4.1.1", + "matcher": "^3.0.0", + "roarr": "^2.15.3", + "semver": "^7.3.2", + "serialize-error": "^7.0.1" }, "engines": { - "node": ">=10" + "node": ">=10.0" } }, "node_modules/global-modules": { @@ -3791,6 +5770,7 @@ "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", "dev": true, + "license": "MIT", "dependencies": { "global-prefix": "^3.0.0" }, @@ -3803,6 +5783,7 @@ "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", "dev": true, + "license": "MIT", "dependencies": { "ini": "^1.3.5", "kind-of": "^6.0.2", @@ -3817,6 +5798,7 @@ "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", "dev": true, + "license": "ISC", "dependencies": { "isexe": "^2.0.0" }, @@ -3824,25 +5806,11 @@ "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.24.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", + "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "license": "MIT", "dependencies": { "type-fest": "^0.20.2" }, @@ -3854,12 +5822,13 @@ } }, "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "optional": true, + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.4.tgz", + "integrity": "sha512-DpLKbNU4WylpxJykQujfCcwYWiV/Jhm50Goo0wrVILAv5jOr9d+H+UR3PhSCD2rCCEIg0uc+G+muBTwD54JhDQ==", + "license": "MIT", "dependencies": { - "define-properties": "^1.1.3" + "define-properties": "^1.2.1", + "gopd": "^1.0.1" }, "engines": { "node": ">= 0.4" @@ -3873,6 +5842,7 @@ "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", "dev": true, + "license": "MIT", "dependencies": { "array-union": "^2.1.0", "dir-glob": "^3.0.1", @@ -3892,76 +5862,117 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "license": "MIT", + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "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==", + "license": "MIT", "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": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "devOptional": true - }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==" - }, - "node_modules/hard-rejection": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", - "dev": true, - "engines": { - "node": ">=6" - } + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "license": "ISC" }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "node_modules/graphemer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", + "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", + "license": "MIT" + }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "license": "MIT", "dependencies": { - "function-bind": "^1.1.1" + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" }, "engines": { - "node": ">= 0.4.0" + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "license": "MIT", "engines": { "node": ">=8" } }, "node_modules/has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "optional": true, + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", + "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", + "license": "MIT", "dependencies": { - "get-intrinsic": "^1.1.1" + "es-define-property": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", + "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", + "license": "MIT", + "engines": { + "node": ">= 0.4" }, "funding": { "url": "https://github.com/sponsors/ljharb" @@ -3971,6 +5982,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "license": "MIT", "engines": { "node": ">= 0.4" }, @@ -3978,49 +5990,75 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/helmet": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/helmet/-/helmet-6.0.0.tgz", - "integrity": "sha512-FO9RpR1wNJepH/GbLPQVtkE2eESglXL641p7SdyoT4LngHFJcZheHMoyUcjCZF4qpuMMO1u5q6RK0l9Ux8JBcg==", + "node_modules/has-tostringtag": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz", + "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.3" + }, "engines": { - "node": ">=14.0.0" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", - "dev": true, + "node_modules/hasown": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", + "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", + "license": "MIT", "dependencies": { - "lru-cache": "^6.0.0" + "function-bind": "^1.1.2" }, "engines": { - "node": ">=10" + "node": ">= 0.4" + } + }, + "node_modules/helmet": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/helmet/-/helmet-7.1.0.tgz", + "integrity": "sha512-g+HZqgfbpXdCkme/Cd/mZkV0aV3BZZZSugecH03kl38m/Kmdx8jKjBikpDj2cr+Iynv4KpYEviojNdTJActJAg==", + "license": "MIT", + "engines": { + "node": ">=16.0.0" } }, + "node_modules/hosted-git-info": { + "version": "2.8.9", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", + "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", + "dev": true, + "license": "ISC" + }, "node_modules/html-encoding-sniffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", - "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-4.0.0.tgz", + "integrity": "sha512-Y22oTqIU4uuPgEemfz7NDJz6OeKf12Lsu+QC+s3BVpda64lTiMYCyGwg5ki4vFxkMwQdeZDl2adZoqUgdFuTgQ==", "dev": true, + "license": "MIT", "dependencies": { - "whatwg-encoding": "^2.0.0" + "whatwg-encoding": "^3.1.1" }, "engines": { - "node": ">=12" + "node": ">=18" } }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/html-tags": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.2.0.tgz", - "integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.3.1.tgz", + "integrity": "sha512-ztqyC3kLto0e9WbNp0aeP+M3kTt+nbaIveGmUxAtZa+8iFgKLUOD4YKM5j+f3QD89bra7UeumolZHKuOXnTmeQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -4028,16 +6066,53 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/html-to-text": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/html-to-text/-/html-to-text-9.0.5.tgz", + "integrity": "sha512-qY60FjREgVZL03vJU6IfMV4GDjGBIoOyvuFdpBDIX9yTlDw0TjxVBQp+P8NvpdIXNJvfWBTNul7fsAQJq2FNpg==", + "license": "MIT", + "dependencies": { + "@selderee/plugin-htmlparser2": "^0.11.0", + "deepmerge": "^4.3.1", + "dom-serializer": "^2.0.0", + "htmlparser2": "^8.0.2", + "selderee": "^0.11.0" + }, + "engines": { + "node": ">=14" + } + }, + "node_modules/htmlparser2": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.2.tgz", + "integrity": "sha512-GYdjWKDkbRLkZ5geuHs5NY1puJ+PXwP7+fHPRz06Eirsb9ugf6d8kkXav6ADhcODhFFPMIXyxkxSuMf3D6NCFA==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "license": "MIT", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1", + "entities": "^4.4.0" + } + }, "node_modules/http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz", + "integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==", + "license": "BSD-2-Clause", "optional": true }, "node_modules/http-errors": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", + "license": "MIT", "dependencies": { "depd": "2.0.0", "inherits": "2.0.4", @@ -4050,30 +6125,43 @@ } }, "node_modules/http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.2.tgz", + "integrity": "sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==", + "license": "MIT", "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" + "agent-base": "^7.1.0", + "debug": "^4.3.4" }, "engines": { - "node": ">= 6" + "node": ">= 14" + } + }, + "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==", + "license": "MIT", + "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", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", + "integrity": "sha512-wlwpilI7YdjSkWaQ/7omYBMTliDcmCN8OLihO6I9B86g06lMyAoqgoDpV0XqoaPOKj+0DIdAvnsWfyAAhmimcg==", + "license": "MIT", "dependencies": { - "agent-base": "6", + "agent-base": "^7.0.2", "debug": "4" }, "engines": { - "node": ">= 6" + "node": ">= 14" } }, "node_modules/human-signals": { @@ -4081,20 +6169,22 @@ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", "dev": true, + "license": "Apache-2.0", "engines": { "node": ">=10.17.0" } }, "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": "9.0.11", + "resolved": "https://registry.npmjs.org/husky/-/husky-9.0.11.tgz", + "integrity": "sha512-AB6lFlbwwyIqMdHYhwPe+kjOC3Oc5P3nThEoW/AaO2BX3vJDjWPFxYLxokUZOo6RNX20He3AaT8sESs9NJcmEw==", "dev": true, + "license": "MIT", "bin": { - "husky": "lib/bin.js" + "husky": "bin.mjs" }, "engines": { - "node": ">=14" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/typicode" @@ -4104,6 +6194,7 @@ "version": "0.6.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" }, @@ -4112,9 +6203,10 @@ } }, "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.3.1", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz", + "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==", + "license": "MIT", "engines": { "node": ">= 4" } @@ -4123,6 +6215,7 @@ "version": "3.3.0", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "license": "MIT", "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" @@ -4134,20 +6227,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/import-lazy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", - "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/import-local": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", "dev": true, + "license": "MIT", "dependencies": { "pkg-dir": "^4.2.0", "resolve-cwd": "^3.0.0" @@ -4166,6 +6251,7 @@ "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==", + "license": "MIT", "engines": { "node": ">=0.8.19" } @@ -4175,6 +6261,7 @@ "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" } @@ -4183,6 +6270,8 @@ "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.", + "license": "ISC", "dependencies": { "once": "^1.3.0", "wrappy": "1" @@ -4191,23 +6280,59 @@ "node_modules/inherits": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "license": "ISC" }, "node_modules/ini": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "devOptional": true + "license": "ISC" + }, + "node_modules/internal-slot": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.7.tgz", + "integrity": "sha512-NGnrKwXzSms2qUUih/ILZ5JBqNTSa1+ZmP6flaIp6KmSElgE9qdndzS3cqjrDovwFdmwsGsLdeFgB6suw+1e9g==", + "license": "MIT", + "dependencies": { + "es-errors": "^1.3.0", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } }, "node_modules/ip": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", - "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==" + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", + "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==", + "license": "MIT" + }, + "node_modules/ip-address": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz", + "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==", + "license": "MIT", + "dependencies": { + "jsbn": "1.1.0", + "sprintf-js": "^1.1.3" + }, + "engines": { + "node": ">= 12" + } + }, + "node_modules/ip-address/node_modules/sprintf-js": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", + "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==", + "license": "BSD-3-Clause" }, "node_modules/ip6": { "version": "0.2.10", "resolved": "https://registry.npmjs.org/ip6/-/ip6-0.2.10.tgz", "integrity": "sha512-1LdpyKjhvepd6EbAU6rW4g14vuYtx5TnJX9TfZZBhsM6DsyPQLNzW12rtbUqXBMwqFrLVV/Gcxv0GNFvJp2cYA==", + "license": "MIT", "bin": { "ip6": "ip6-cli.js" } @@ -4216,55 +6341,172 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "license": "MIT", "engines": { "node": ">= 0.10" } }, + "node_modules/is-array-buffer": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.4.tgz", + "integrity": "sha512-wcjaerHw0ydZwfhiKbXJWLDY8A7yV7KhjQOpb83hGgGfId/aQa4TOvwyzn2PuswW2gPCYEL/nEAiSVpdOj1lXw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-arrayish": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "node_modules/is-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==", "dev": true, + "license": "MIT" + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "license": "MIT", "dependencies": { - "has": "^1.0.3" + "has-bigints": "^1.0.1" }, "funding": { "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "node_modules/is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "license": "MIT", + "dependencies": { + "binary-extensions": "^2.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, - "node_modules/is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", + "node_modules/is-builtin-module": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/is-builtin-module/-/is-builtin-module-3.2.1.tgz", + "integrity": "sha512-BSLE3HnV2syZ0FK0iMA/yUGplUeMmNz4AW5fnTunbCIqZi4vG3WjJT9FHMy5D69xmAYBHXQhJdALdpwVxV501A==", + "dev": true, + "license": "MIT", + "dependencies": { + "builtin-modules": "^3.3.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "license": "MIT", + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-view": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-data-view/-/is-data-view-1.0.1.tgz", + "integrity": "sha512-AHkaJrsUVW6wq6JS8y3JnM/GJF/9cf+k20+iDzlSaJrinEo5+7vRiteOSwBhHRiAyQATN1AmY4hwzxJKPmYf+w==", + "license": "MIT", + "dependencies": { + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-fullwidth-code-point": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-4.0.0.tgz", + "integrity": "sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-generator-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -4273,6 +6515,7 @@ "version": "4.0.3", "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "license": "MIT", "dependencies": { "is-extglob": "^2.1.1" }, @@ -4280,30 +6523,59 @@ "node": ">=0.10.0" } }, + "node_modules/is-negative-zero": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.3.tgz", + "integrity": "sha512-5KoIu2Ngpyek75jXodFvnafB6DJgr3u8uuK0LEZJjrU19DrMD3EVERaR8sjz8CCGgpZvxPl9SuE1GMVPFHx1mw==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true, + "license": "MIT", "engines": { "node": ">=0.12.0" } }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "license": "MIT", "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", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=8" } }, "node_modules/is-plain-object": { @@ -4311,6 +6583,7 @@ "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -4319,13 +6592,46 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.3.tgz", + "integrity": "sha512-nA2hv5XIhLR3uVzDDfCIknerhx8XUKnstuOERPNNIinXG7v9u+ohXF67vxm4TPTEPU6lm61ZkwP3c9PCB97rhg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, "node_modules/is-stream": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", "dev": true, + "license": "MIT", "engines": { "node": ">=8" }, @@ -4333,54 +6639,115 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "license": "MIT", + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "license": "MIT", + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.13.tgz", + "integrity": "sha512-uZ25/bUAlUY5fR4OKT4rZQEBrzQWYV9ZJYGGsUmEJ6thodVJ1HX64ePQ6Z0qPWP+m+Uq6e9UugrE38jeYsDSMw==", + "license": "MIT", + "dependencies": { + "which-typed-array": "^1.1.14" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "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": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==", + "license": "ISC" }, "node_modules/istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz", + "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==", "dev": true, + "license": "BSD-3-Clause", "engines": { "node": ">=8" } }, "node_modules/istanbul-lib-instrument": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.2.1.tgz", - "integrity": "sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-6.0.2.tgz", + "integrity": "sha512-1WUsZ9R1lA0HtBSohTkm39WTPlNKSJ5iFk7UwqXkBLoHQT+hfqPsfsTDVuZdKGaBwn7din9bS7SsnoAr943hvw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "@babel/core": "^7.12.3", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", + "@babel/core": "^7.23.9", + "@babel/parser": "^7.23.9", + "@istanbuljs/schema": "^0.1.3", "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" + "semver": "^7.5.4" }, "engines": { - "node": ">=8" + "node": ">=10" } }, "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==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz", + "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", + "make-dir": "^4.0.0", "supports-color": "^7.1.0" }, "engines": { - "node": ">=8" + "node": ">=10" } }, "node_modules/istanbul-lib-source-maps": { @@ -4388,6 +6755,7 @@ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "debug": "^4.1.1", "istanbul-lib-coverage": "^3.0.0", @@ -4398,10 +6766,11 @@ } }, "node_modules/istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", + "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { "html-escaper": "^2.0.0", "istanbul-lib-report": "^3.0.0" @@ -4411,15 +6780,16 @@ } }, "node_modules/jest": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.2.2.tgz", - "integrity": "sha512-r+0zCN9kUqoON6IjDdjbrsWobXM/09Nd45kIPRD8kloaRh1z5ZCMdVsgLXGxmlL7UpAJsvCYOQNO+NjvG/gqiQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest/-/jest-29.7.0.tgz", + "integrity": "sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/core": "^29.2.2", - "@jest/types": "^29.2.1", + "@jest/core": "^29.7.0", + "@jest/types": "^29.6.3", "import-local": "^3.0.2", - "jest-cli": "^29.2.2" + "jest-cli": "^29.7.0" }, "bin": { "jest": "bin/jest.js" @@ -4437,12 +6807,14 @@ } }, "node_modules/jest-changed-files": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.2.0.tgz", - "integrity": "sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.7.0.tgz", + "integrity": "sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==", "dev": true, + "license": "MIT", "dependencies": { "execa": "^5.0.0", + "jest-util": "^29.7.0", "p-limit": "^3.1.0" }, "engines": { @@ -4450,28 +6822,30 @@ } }, "node_modules/jest-circus": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.2.2.tgz", - "integrity": "sha512-upSdWxx+Mh4DV7oueuZndJ1NVdgtTsqM4YgywHEx05UMH5nxxA2Qu9T9T9XVuR021XxqSoaKvSmmpAbjwwwxMw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", + "integrity": "sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/environment": "^29.2.2", - "@jest/expect": "^29.2.2", - "@jest/test-result": "^29.2.1", - "@jest/types": "^29.2.1", + "@jest/environment": "^29.7.0", + "@jest/expect": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "co": "^4.6.0", - "dedent": "^0.7.0", + "dedent": "^1.0.0", "is-generator-fn": "^2.0.0", - "jest-each": "^29.2.1", - "jest-matcher-utils": "^29.2.2", - "jest-message-util": "^29.2.1", - "jest-runtime": "^29.2.2", - "jest-snapshot": "^29.2.2", - "jest-util": "^29.2.1", + "jest-each": "^29.7.0", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", "p-limit": "^3.1.0", - "pretty-format": "^29.2.1", + "pretty-format": "^29.7.0", + "pure-rand": "^6.0.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -4480,22 +6854,22 @@ } }, "node_modules/jest-cli": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.2.2.tgz", - "integrity": "sha512-R45ygnnb2CQOfd8rTPFR+/fls0d+1zXS6JPYTBBrnLPrhr58SSuPTiA5Tplv8/PXpz4zXR/AYNxmwIj6J6nrvg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.7.0.tgz", + "integrity": "sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/core": "^29.2.2", - "@jest/test-result": "^29.2.1", - "@jest/types": "^29.2.1", + "@jest/core": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "chalk": "^4.0.0", + "create-jest": "^29.7.0", "exit": "^0.1.2", - "graceful-fs": "^4.2.9", "import-local": "^3.0.2", - "jest-config": "^29.2.2", - "jest-util": "^29.2.1", - "jest-validate": "^29.2.2", - "prompts": "^2.0.1", + "jest-config": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", "yargs": "^17.3.1" }, "bin": { @@ -4514,31 +6888,32 @@ } }, "node_modules/jest-config": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.2.2.tgz", - "integrity": "sha512-Q0JX54a5g1lP63keRfKR8EuC7n7wwny2HoTRDb8cx78IwQOiaYUVZAdjViY3WcTxpR02rPUpvNVmZ1fkIlZPcw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.7.0.tgz", + "integrity": "sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.2.2", - "@jest/types": "^29.2.1", - "babel-jest": "^29.2.2", + "@jest/test-sequencer": "^29.7.0", + "@jest/types": "^29.6.3", + "babel-jest": "^29.7.0", "chalk": "^4.0.0", "ci-info": "^3.2.0", "deepmerge": "^4.2.2", "glob": "^7.1.3", "graceful-fs": "^4.2.9", - "jest-circus": "^29.2.2", - "jest-environment-node": "^29.2.2", - "jest-get-type": "^29.2.0", - "jest-regex-util": "^29.2.0", - "jest-resolve": "^29.2.2", - "jest-runner": "^29.2.2", - "jest-util": "^29.2.1", - "jest-validate": "^29.2.2", + "jest-circus": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-runner": "^29.7.0", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", "micromatch": "^4.0.4", "parse-json": "^5.2.0", - "pretty-format": "^29.2.1", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "strip-json-comments": "^3.1.1" }, @@ -4558,26 +6933,44 @@ } } }, + "node_modules/jest-config/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", + "engines": { + "node": ">=8" + } + }, "node_modules/jest-diff": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.2.1.tgz", - "integrity": "sha512-gfh/SMNlQmP3MOUgdzxPOd4XETDJifADpT937fN1iUGz+9DgOu2eUPHH25JDkLVcLwwqxv3GzVyK4VBUr9fjfA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.7.0.tgz", + "integrity": "sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", - "diff-sequences": "^29.2.0", - "jest-get-type": "^29.2.0", - "pretty-format": "^29.2.1" + "diff-sequences": "^29.6.3", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-docblock": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.2.0.tgz", - "integrity": "sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.7.0.tgz", + "integrity": "sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==", "dev": true, + "license": "MIT", "dependencies": { "detect-newline": "^3.0.0" }, @@ -4586,62 +6979,66 @@ } }, "node_modules/jest-each": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.2.1.tgz", - "integrity": "sha512-sGP86H/CpWHMyK3qGIGFCgP6mt+o5tu9qG4+tobl0LNdgny0aitLXs9/EBacLy3Bwqy+v4uXClqJgASJWcruYw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.7.0.tgz", + "integrity": "sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.2.1", + "@jest/types": "^29.6.3", "chalk": "^4.0.0", - "jest-get-type": "^29.2.0", - "jest-util": "^29.2.1", - "pretty-format": "^29.2.1" + "jest-get-type": "^29.6.3", + "jest-util": "^29.7.0", + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-environment-node": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.2.2.tgz", - "integrity": "sha512-B7qDxQjkIakQf+YyrqV5dICNs7tlCO55WJ4OMSXsqz1lpI/0PmeuXdx2F7eU8rnPbRkUR/fItSSUh0jvE2y/tw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.7.0.tgz", + "integrity": "sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/environment": "^29.2.2", - "@jest/fake-timers": "^29.2.2", - "@jest/types": "^29.2.1", + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-mock": "^29.2.2", - "jest-util": "^29.2.1" + "jest-mock": "^29.7.0", + "jest-util": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-get-type": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz", - "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz", + "integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-haste-map": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.2.1.tgz", - "integrity": "sha512-wF460rAFmYc6ARcCFNw4MbGYQjYkvjovb9GBT+W10Um8q5nHq98jD6fHZMDMO3tA56S8XnmNkM8GcA8diSZfnA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.7.0.tgz", + "integrity": "sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.2.1", + "@jest/types": "^29.6.3", "@types/graceful-fs": "^4.1.3", "@types/node": "*", "anymatch": "^3.0.3", "fb-watchman": "^2.0.0", "graceful-fs": "^4.2.9", - "jest-regex-util": "^29.2.0", - "jest-util": "^29.2.1", - "jest-worker": "^29.2.1", + "jest-regex-util": "^29.6.3", + "jest-util": "^29.7.0", + "jest-worker": "^29.7.0", "micromatch": "^4.0.4", "walker": "^1.0.8" }, @@ -4653,46 +7050,49 @@ } }, "node_modules/jest-leak-detector": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.2.1.tgz", - "integrity": "sha512-1YvSqYoiurxKOJtySc+CGVmw/e1v4yNY27BjWTVzp0aTduQeA7pdieLiW05wTYG/twlKOp2xS/pWuikQEmklug==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.7.0.tgz", + "integrity": "sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==", "dev": true, + "license": "MIT", "dependencies": { - "jest-get-type": "^29.2.0", - "pretty-format": "^29.2.1" + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-matcher-utils": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.2.2.tgz", - "integrity": "sha512-4DkJ1sDPT+UX2MR7Y3od6KtvRi9Im1ZGLGgdLFLm4lPexbTaCgJW5NN3IOXlQHF7NSHY/VHhflQ+WoKtD/vyCw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.7.0.tgz", + "integrity": "sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", - "jest-diff": "^29.2.1", - "jest-get-type": "^29.2.0", - "pretty-format": "^29.2.1" + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "pretty-format": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-message-util": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.2.1.tgz", - "integrity": "sha512-Dx5nEjw9V8C1/Yj10S/8ivA8F439VS8vTq1L7hEgwHFn9ovSKNpYW/kwNh7UglaEgXO42XxzKJB+2x0nSglFVw==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.7.0.tgz", + "integrity": "sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==", "dev": true, + "license": "MIT", "dependencies": { "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.2.1", + "@jest/types": "^29.6.3", "@types/stack-utils": "^2.0.0", "chalk": "^4.0.0", "graceful-fs": "^4.2.9", "micromatch": "^4.0.4", - "pretty-format": "^29.2.1", + "pretty-format": "^29.7.0", "slash": "^3.0.0", "stack-utils": "^2.0.3" }, @@ -4701,24 +7101,26 @@ } }, "node_modules/jest-mock": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.2.2.tgz", - "integrity": "sha512-1leySQxNAnivvbcx0sCB37itu8f4OX2S/+gxLAV4Z62shT4r4dTG9tACDywUAEZoLSr36aYUTsVp3WKwWt4PMQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.7.0.tgz", + "integrity": "sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.2.1", + "@jest/types": "^29.6.3", "@types/node": "*", - "jest-util": "^29.2.1" + "jest-util": "^29.7.0" }, "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, + "license": "MIT", "engines": { "node": ">=6" }, @@ -4732,28 +7134,30 @@ } }, "node_modules/jest-regex-util": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.2.0.tgz", - "integrity": "sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA==", + "version": "29.6.3", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.6.3.tgz", + "integrity": "sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==", "dev": true, + "license": "MIT", "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-resolve": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.2.2.tgz", - "integrity": "sha512-3gaLpiC3kr14rJR3w7vWh0CBX2QAhfpfiQTwrFPvVrcHe5VUBtIXaR004aWE/X9B2CFrITOQAp5gxLONGrk6GA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.7.0.tgz", + "integrity": "sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==", "dev": true, + "license": "MIT", "dependencies": { "chalk": "^4.0.0", "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.2.1", + "jest-haste-map": "^29.7.0", "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.2.1", - "jest-validate": "^29.2.2", + "jest-util": "^29.7.0", + "jest-validate": "^29.7.0", "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", + "resolve.exports": "^2.0.0", "slash": "^3.0.0" }, "engines": { @@ -4761,43 +7165,45 @@ } }, "node_modules/jest-resolve-dependencies": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.2.2.tgz", - "integrity": "sha512-wWOmgbkbIC2NmFsq8Lb+3EkHuW5oZfctffTGvwsA4JcJ1IRk8b2tg+hz44f0lngvRTeHvp3Kyix9ACgudHH9aQ==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.7.0.tgz", + "integrity": "sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==", "dev": true, + "license": "MIT", "dependencies": { - "jest-regex-util": "^29.2.0", - "jest-snapshot": "^29.2.2" + "jest-regex-util": "^29.6.3", + "jest-snapshot": "^29.7.0" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, "node_modules/jest-runner": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.2.2.tgz", - "integrity": "sha512-1CpUxXDrbsfy9Hr9/1zCUUhT813kGGK//58HeIw/t8fa/DmkecEwZSWlb1N/xDKXg3uCFHQp1GCvlSClfImMxg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.7.0.tgz", + "integrity": "sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/console": "^29.2.1", - "@jest/environment": "^29.2.2", - "@jest/test-result": "^29.2.1", - "@jest/transform": "^29.2.2", - "@jest/types": "^29.2.1", + "@jest/console": "^29.7.0", + "@jest/environment": "^29.7.0", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "emittery": "^0.13.1", "graceful-fs": "^4.2.9", - "jest-docblock": "^29.2.0", - "jest-environment-node": "^29.2.2", - "jest-haste-map": "^29.2.1", - "jest-leak-detector": "^29.2.1", - "jest-message-util": "^29.2.1", - "jest-resolve": "^29.2.2", - "jest-runtime": "^29.2.2", - "jest-util": "^29.2.1", - "jest-watcher": "^29.2.2", - "jest-worker": "^29.2.1", + "jest-docblock": "^29.7.0", + "jest-environment-node": "^29.7.0", + "jest-haste-map": "^29.7.0", + "jest-leak-detector": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-resolve": "^29.7.0", + "jest-runtime": "^29.7.0", + "jest-util": "^29.7.0", + "jest-watcher": "^29.7.0", + "jest-worker": "^29.7.0", "p-limit": "^3.1.0", "source-map-support": "0.5.13" }, @@ -4806,31 +7212,32 @@ } }, "node_modules/jest-runtime": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.2.2.tgz", - "integrity": "sha512-TpR1V6zRdLynckKDIQaY41od4o0xWL+KOPUCZvJK2bu5P1UXhjobt5nJ2ICNeIxgyj9NGkO0aWgDqYPVhDNKjA==", - "dev": true, - "dependencies": { - "@jest/environment": "^29.2.2", - "@jest/fake-timers": "^29.2.2", - "@jest/globals": "^29.2.2", - "@jest/source-map": "^29.2.0", - "@jest/test-result": "^29.2.1", - "@jest/transform": "^29.2.2", - "@jest/types": "^29.2.1", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.7.0.tgz", + "integrity": "sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/environment": "^29.7.0", + "@jest/fake-timers": "^29.7.0", + "@jest/globals": "^29.7.0", + "@jest/source-map": "^29.6.3", + "@jest/test-result": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "@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.2.1", - "jest-message-util": "^29.2.1", - "jest-mock": "^29.2.2", - "jest-regex-util": "^29.2.0", - "jest-resolve": "^29.2.2", - "jest-snapshot": "^29.2.2", - "jest-util": "^29.2.1", + "jest-haste-map": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-mock": "^29.7.0", + "jest-regex-util": "^29.6.3", + "jest-resolve": "^29.7.0", + "jest-snapshot": "^29.7.0", + "jest-util": "^29.7.0", "slash": "^3.0.0", "strip-bom": "^4.0.0" }, @@ -4839,62 +7246,45 @@ } }, "node_modules/jest-snapshot": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.2.2.tgz", - "integrity": "sha512-GfKJrpZ5SMqhli3NJ+mOspDqtZfJBryGA8RIBxF+G+WbDoC7HCqKaeAss4Z/Sab6bAW11ffasx8/vGsj83jyjA==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.7.0.tgz", + "integrity": "sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==", "dev": true, + "license": "MIT", "dependencies": { "@babel/core": "^7.11.6", "@babel/generator": "^7.7.2", "@babel/plugin-syntax-jsx": "^7.7.2", "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.2.2", - "@jest/transform": "^29.2.2", - "@jest/types": "^29.2.1", - "@types/babel__traverse": "^7.0.6", - "@types/prettier": "^2.1.5", + "@jest/expect-utils": "^29.7.0", + "@jest/transform": "^29.7.0", + "@jest/types": "^29.6.3", "babel-preset-current-node-syntax": "^1.0.0", "chalk": "^4.0.0", - "expect": "^29.2.2", + "expect": "^29.7.0", "graceful-fs": "^4.2.9", - "jest-diff": "^29.2.1", - "jest-get-type": "^29.2.0", - "jest-haste-map": "^29.2.1", - "jest-matcher-utils": "^29.2.2", - "jest-message-util": "^29.2.1", - "jest-util": "^29.2.1", + "jest-diff": "^29.7.0", + "jest-get-type": "^29.6.3", + "jest-matcher-utils": "^29.7.0", + "jest-message-util": "^29.7.0", + "jest-util": "^29.7.0", "natural-compare": "^1.4.0", - "pretty-format": "^29.2.1", - "semver": "^7.3.5" + "pretty-format": "^29.7.0", + "semver": "^7.5.3" }, "engines": { "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-snapshot/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/jest-util": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.2.1.tgz", - "integrity": "sha512-P5VWDj25r7kj7kl4pN2rG/RN2c1TLfYYYZYULnS/35nFDjBai+hBeo3MDrYZS7p6IoY3YHZnt2vq4L6mKnLk0g==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.7.0.tgz", + "integrity": "sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/types": "^29.2.1", + "@jest/types": "^29.6.3", "@types/node": "*", "chalk": "^4.0.0", "ci-info": "^3.2.0", @@ -4905,28 +7295,59 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/jest-validate": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.2.2.tgz", - "integrity": "sha512-eJXATaKaSnOuxNfs8CLHgdABFgUrd0TtWS8QckiJ4L/QVDF4KVbZFBBOwCBZHOS0Rc5fOxqngXeGXE3nGQkpQA==", + "node_modules/jest-util/node_modules/ci-info": { + "version": "3.9.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.9.0.tgz", + "integrity": "sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==", "dev": true, - "dependencies": { - "@jest/types": "^29.2.1", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.2.0", - "leven": "^3.1.0", - "pretty-format": "^29.2.1" - }, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "license": "MIT", "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "node": ">=8" } }, - "node_modules/jest-validate/node_modules/camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", + "node_modules/jest-util/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/jest-validate": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz", + "integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "@jest/types": "^29.6.3", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^29.6.3", + "leven": "^3.1.0", + "pretty-format": "^29.7.0" + }, + "engines": { + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + } + }, + "node_modules/jest-validate/node_modules/camelcase": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, @@ -4935,18 +7356,19 @@ } }, "node_modules/jest-watcher": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.2.2.tgz", - "integrity": "sha512-j2otfqh7mOvMgN2WlJ0n7gIx9XCMWntheYGlBK7+5g3b1Su13/UAK7pdKGyd4kDlrLwtH2QPvRv5oNIxWvsJ1w==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.7.0.tgz", + "integrity": "sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==", "dev": true, + "license": "MIT", "dependencies": { - "@jest/test-result": "^29.2.1", - "@jest/types": "^29.2.1", + "@jest/test-result": "^29.7.0", + "@jest/types": "^29.6.3", "@types/node": "*", "ansi-escapes": "^4.2.1", "chalk": "^4.0.0", "emittery": "^0.13.1", - "jest-util": "^29.2.1", + "jest-util": "^29.7.0", "string-length": "^4.0.1" }, "engines": { @@ -4954,13 +7376,14 @@ } }, "node_modules/jest-worker": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.2.1.tgz", - "integrity": "sha512-ROHTZ+oj7sBrgtv46zZ84uWky71AoYi0vEV9CdEtc1FQunsoAGe5HbQmW76nI5QWdvECVPrSi1MCVUmizSavMg==", + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.7.0.tgz", + "integrity": "sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==", "dev": true, + "license": "MIT", "dependencies": { "@types/node": "*", - "jest-util": "^29.2.1", + "jest-util": "^29.7.0", "merge-stream": "^2.0.0", "supports-color": "^8.0.0" }, @@ -4973,6 +7396,7 @@ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", "dev": true, + "license": "MIT", "dependencies": { "has-flag": "^4.0.0" }, @@ -4983,21 +7407,30 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "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==" + "node_modules/js-git": { + "version": "0.7.8", + "resolved": "https://registry.npmjs.org/js-git/-/js-git-0.7.8.tgz", + "integrity": "sha512-+E5ZH/HeRnoc/LW0AmAyhU+mNcWBzAKE+30+IDMLSLbbK+Tdt02AdkOKq9u15rlJsDEGFqtgckc8ZM59LhhiUA==", + "license": "MIT", + "dependencies": { + "bodec": "^0.1.0", + "culvert": "^0.1.2", + "git-sha1": "^0.1.2", + "pako": "^0.2.5" + } }, "node_modules/js-tokens": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/js-yaml": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "license": "MIT", "dependencies": { "argparse": "^2.0.1" }, @@ -5005,53 +7438,56 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/jsbn": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz", + "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==", + "license": "MIT" + }, "node_modules/jsdoc-type-pratt-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-3.1.0.tgz", - "integrity": "sha512-MgtD0ZiCDk9B+eI73BextfRrVQl0oyzRG8B2BjORts6jbunj4ScKPcyXGTbB6eXL4y9TzxCm6hyeLq/2ASzNdw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-4.0.0.tgz", + "integrity": "sha512-YtOli5Cmzy3q4dP26GraSOeAhqecewG04hoO8DY56CH4KJ9Fvv5qKWUCCo3HZob7esJQHCv6/+bnTy72xZZaVQ==", "dev": true, + "license": "MIT", "engines": { "node": ">=12.0.0" } }, "node_modules/jsdom": { - "version": "20.0.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.1.tgz", - "integrity": "sha512-pksjj7Rqoa+wdpkKcLzQRHhJCEE42qQhl/xLMUKHgoSejaKOdaXEAnqs6uDNwMl/fciHTzKeR8Wm8cw7N+g98A==", - "dev": true, - "dependencies": { - "abab": "^2.0.6", - "acorn": "^8.8.0", - "acorn-globals": "^7.0.0", - "cssom": "^0.5.0", - "cssstyle": "^2.3.0", - "data-urls": "^3.0.2", - "decimal.js": "^10.4.1", - "domexception": "^4.0.0", - "escodegen": "^2.0.0", + "version": "24.1.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-24.1.0.tgz", + "integrity": "sha512-6gpM7pRXCwIOKxX47cgOyvyQDN/Eh0f1MeKySBV2xGdKtqJBLj8P25eY3EVCWo2mglDDzozR2r2MW4T+JiNUZA==", + "dev": true, + "license": "MIT", + "dependencies": { + "cssstyle": "^4.0.1", + "data-urls": "^5.0.0", + "decimal.js": "^10.4.3", "form-data": "^4.0.0", - "html-encoding-sniffer": "^3.0.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.1", + "html-encoding-sniffer": "^4.0.0", + "http-proxy-agent": "^7.0.2", + "https-proxy-agent": "^7.0.4", "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.2", - "parse5": "^7.1.1", + "nwsapi": "^2.2.10", + "parse5": "^7.1.2", + "rrweb-cssom": "^0.7.0", "saxes": "^6.0.0", "symbol-tree": "^3.2.4", - "tough-cookie": "^4.1.2", - "w3c-xmlserializer": "^3.0.0", + "tough-cookie": "^4.1.4", + "w3c-xmlserializer": "^5.0.0", "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^2.0.0", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^11.0.0", - "ws": "^8.9.0", - "xml-name-validator": "^4.0.0" + "whatwg-encoding": "^3.1.1", + "whatwg-mimetype": "^4.0.0", + "whatwg-url": "^14.0.0", + "ws": "^8.17.0", + "xml-name-validator": "^5.0.0" }, "engines": { - "node": ">=14" + "node": ">=18" }, "peerDependencies": { - "canvas": "^2.5.0" + "canvas": "^2.11.2" }, "peerDependenciesMeta": { "canvas": { @@ -5060,50 +7496,56 @@ } }, "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.0.2.tgz", + "integrity": "sha512-xKqzzWXDttJuOcawBt4KnKHHIf5oQ/Cxax+0PWFG+DFDgHNAdi+TXECADI+RYiFUMmx8792xsMbbgXj4CwnP4g==", "dev": true, + "license": "MIT", "bin": { "jsesc": "bin/jsesc" }, "engines": { - "node": ">=4" + "node": ">=6" } }, "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==", - "optional": true + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "license": "MIT" }, "node_modules/json-parse-even-better-errors": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" + "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", + "license": "MIT" }, "node_modules/json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", + "license": "ISC", "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.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", "dev": true, + "license": "MIT", "bin": { "json5": "lib/cli.js" }, @@ -5111,28 +7553,50 @@ "node": ">=6" } }, + "node_modules/jsonc-eslint-parser": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/jsonc-eslint-parser/-/jsonc-eslint-parser-2.4.0.tgz", + "integrity": "sha512-WYDyuc/uFcGp6YtM2H0uKmUwieOuzeE/5YocFJLnLfclZ4inf3mRn8ZVy1s7Hxji7Jxm6Ss8gqpexD/GlKoGgg==", + "dev": true, + "license": "MIT", + "peer": true, + "dependencies": { + "acorn": "^8.5.0", + "eslint-visitor-keys": "^3.0.0", + "espree": "^9.0.0", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ota-meshi" + } + }, "node_modules/jsonfile": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", + "license": "MIT", "optional": true, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "node_modules/just-extend": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", - "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", - "dev": true + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-6.2.0.tgz", + "integrity": "sha512-cYofQu2Xpom82S6qD778jBDpwvvy39s1l/hrYij2u9AMdQcGRpaBu6kY4mVhuno5kJVi1DAz4aiphA2WI1/OAw==", + "dev": true, + "license": "MIT" }, "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==", - "optional": true, + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", + "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==", + "license": "MIT", "dependencies": { - "json-buffer": "3.0.0" + "json-buffer": "3.0.1" } }, "node_modules/kind-of": { @@ -5140,6 +7604,7 @@ "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", "dev": true, + "license": "MIT", "engines": { "node": ">=0.10.0" } @@ -5149,21 +7614,42 @@ "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } }, "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==", - "dev": true + "version": "0.31.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.31.0.tgz", + "integrity": "sha512-sBPIUGTNF0czz0mwGGUoKKJC8Q7On1GPbCSFPfyEsfHb2DyBG0Y4QtV+EVWpINSaiGKZblDNuF5AezxSgOhesQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/lazy": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/lazy/-/lazy-1.0.11.tgz", + "integrity": "sha512-Y+CjUfLmIpoUCCRl0ub4smrYtGGr5AOa2AKOaWelGHOGz33X/Y/KizefGqbkwfz44+cnq/+9habclf8vOmu2LA==", + "license": "MIT", + "engines": { + "node": ">=0.2.0" + } + }, + "node_modules/leac": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/leac/-/leac-0.6.0.tgz", + "integrity": "sha512-y+SqErxb8h7nE/fiEX07jsbuhrpO9lL8eca7/Y1nuWV2moNlXhyd59iDGcRf6moVyDMbmTNzL40SUyrFU/yDpg==", + "license": "MIT", + "funding": { + "url": "https://ko-fi.com/killymxi" + } }, "node_modules/leven": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", "dev": true, + "license": "MIT", "engines": { "node": ">=6" } @@ -5172,6 +7658,7 @@ "version": "0.4.1", "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "license": "MIT", "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" @@ -5180,1156 +7667,1221 @@ "node": ">= 0.8.0" } }, + "node_modules/lilconfig": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.2.tgz", + "integrity": "sha512-eop+wDAvpItUys0FWkHIKeC9ybYrTGbU41U5K7+bttZZeohvnY7M9dZ5kB21GNWiFT2q1OoPTvncPCgSOVO5ow==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/antonk52" + } + }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true + "dev": true, + "license": "MIT" }, - "node_modules/locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "node_modules/lint-staged": { + "version": "15.2.7", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-15.2.7.tgz", + "integrity": "sha512-+FdVbbCZ+yoh7E/RosSdqKJyUM2OEjTciH0TFNkawKgvFp1zbGlEC39RADg+xKBG1R4mhoH2j85myBQZ5wR+lw==", + "dev": true, + "license": "MIT", "dependencies": { - "p-locate": "^5.0.0" + "chalk": "~5.3.0", + "commander": "~12.1.0", + "debug": "~4.3.4", + "execa": "~8.0.1", + "lilconfig": "~3.1.1", + "listr2": "~8.2.1", + "micromatch": "~4.0.7", + "pidtree": "~0.6.0", + "string-argv": "~0.3.2", + "yaml": "~2.4.2" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" }, "engines": { - "node": ">=10" + "node": ">=18.12.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://opencollective.com/lint-staged" } }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "node_modules/lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "dev": true - }, - "node_modules/lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" - }, - "node_modules/lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "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==", - "optional": true, + "node_modules/lint-staged/node_modules/chalk": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=0.10.0" - } - }, - "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, - "dependencies": { - "yallist": "^4.0.0" + "node": "^12.17.0 || ^14.13 || >=16.0.0" }, - "engines": { - "node": ">=10" + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, - "node_modules/luxon": { - "version": "1.28.0", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz", - "integrity": "sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ==", + "node_modules/lint-staged/node_modules/commander": { + "version": "12.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz", + "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==", + "dev": true, + "license": "MIT", "engines": { - "node": "*" + "node": ">=18" } }, - "node_modules/make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "node_modules/lint-staged/node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, + "license": "MIT", "dependencies": { - "semver": "^6.0.0" + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=16.17" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "dependencies": { - "tmpl": "1.0.5" + "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", + "node_modules/lint-staged/node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=16" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/matcher": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", - "optional": true, - "dependencies": { - "escape-string-regexp": "^4.0.0" - }, + "node_modules/lint-staged/node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "dev": true, + "license": "Apache-2.0", "engines": { - "node": ">=10" + "node": ">=16.17.0" } }, - "node_modules/mathml-tag-names": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", - "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", + "node_modules/lint-staged/node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, + "license": "MIT", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/md5": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", - "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", - "dependencies": { - "charenc": "0.0.2", - "crypt": "0.0.2", - "is-buffer": "~1.1.6" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "node_modules/lint-staged/node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/meow": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", - "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "node_modules/lint-staged/node_modules/npm-run-path": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, + "license": "MIT", "dependencies": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize": "^1.2.0", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^3.0.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.18.0", - "yargs-parser": "^20.2.3" + "path-key": "^4.0.0" }, "engines": { - "node": ">=10" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/meow/node_modules/type-fest": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", - "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", + "node_modules/lint-staged/node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^4.0.0" + }, "engines": { - "node": ">=10" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "node_modules/lint-staged/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", "dev": true, + "license": "MIT", "engines": { - "node": ">= 8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "node_modules/lint-staged/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "license": "ISC", "engines": { - "node": ">= 0.6" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "node_modules/lint-staged/node_modules/strip-final-newline": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, + "license": "MIT", "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "bin": { - "mime": "cli.js" + "node": ">=12" }, - "engines": { - "node": ">=4" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "node_modules/listr2": { + "version": "8.2.1", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-8.2.1.tgz", + "integrity": "sha512-irTfvpib/rNiD637xeevjO2l3Z5loZmuaRi0L0YE5LfijwVY96oyVn0DFD3o/teAok7nfobMG1THvvcHh/BP6g==", + "dev": true, + "license": "MIT", + "dependencies": { + "cli-truncate": "^4.0.0", + "colorette": "^2.0.20", + "eventemitter3": "^5.0.1", + "log-update": "^6.0.0", + "rfdc": "^1.3.1", + "wrap-ansi": "^9.0.0" + }, "engines": { - "node": ">= 0.6" + "node": ">=18.0.0" } }, - "node_modules/mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "node_modules/locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "license": "MIT", "dependencies": { - "mime-db": "1.52.0" + "p-locate": "^5.0.0" }, "engines": { - "node": ">= 0.6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "node_modules/lodash": { + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", + "license": "MIT" + }, + "node_modules/lodash.get": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", + "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", "dev": true, - "engines": { - "node": ">=6" - } + "license": "MIT" }, - "node_modules/mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "optional": true, - "engines": { - "node": ">=4" - } + "node_modules/lodash.merge": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", + "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", + "license": "MIT" }, - "node_modules/min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "node_modules/lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", "dev": true, - "engines": { - "node": ">=4" - } + "license": "MIT" }, - "node_modules/minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "node_modules/log-update": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.0.0.tgz", + "integrity": "sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==", + "dev": true, + "license": "MIT", "dependencies": { - "brace-expansion": "^1.1.7" + "ansi-escapes": "^6.2.0", + "cli-cursor": "^4.0.0", + "slice-ansi": "^7.0.0", + "strip-ansi": "^7.1.0", + "wrap-ansi": "^9.0.0" }, "engines": { - "node": "*" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "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", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", + "node_modules/log-update/node_modules/ansi-escapes": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-6.2.1.tgz", + "integrity": "sha512-4nJ3yixlEthEJ9Rk4vPcdBRkZvQZlYyu8j4/Mqz5sgIkddmEnH2Yj2ZrnP9S3tQOvSNRUIgVNF/1yPpRAGNRig==", "dev": true, - "dependencies": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - }, + "license": "MIT", "engines": { - "node": ">= 6" + "node": ">=14.16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/minimist-options/node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "node_modules/log-update/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, + "license": "MIT", "engines": { - "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" + "node": ">=12" }, - "bin": { - "mkdirp": "bin/cmd.js" + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "node_modules/module-alias": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.2.tgz", - "integrity": "sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q==" - }, - "node_modules/moment": { - "version": "2.29.4", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", - "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "node_modules/log-update/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", "engines": { - "node": "*" - } - }, - "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==", - "dependencies": { - "moment": ">= 2.9.0" + "node": ">=12" }, - "engines": { - "node": "*" + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "node_modules/log-update/node_modules/is-fullwidth-code-point": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.0.0.tgz", + "integrity": "sha512-OVa3u9kkBbw7b8Xw5F9P+D/T9X+Z4+JruYVNapTjPYZYUznQ5YfWeFkOj606XYYW8yugTfC8Pj0hYqvi4ryAhA==", "dev": true, + "license": "MIT", + "dependencies": { + "get-east-asian-width": "^1.0.0" + }, "engines": { - "node": ">=4" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "node_modules/multimatch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz", - "integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==", + "node_modules/log-update/node_modules/slice-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.0.tgz", + "integrity": "sha512-bSiSngZ/jWeX93BqeIAbImyTbEihizcwNjFoRUIY/T1wWQsfsm2Vw1agPKylXvQTU7iASGdHhyqRlqQzfz+Htg==", "dev": true, + "license": "MIT", "dependencies": { - "@types/minimatch": "^3.0.3", - "array-differ": "^3.0.0", - "array-union": "^2.1.0", - "arrify": "^2.0.1", - "minimatch": "^3.0.4" + "ansi-styles": "^6.2.1", + "is-fullwidth-code-point": "^5.0.0" }, "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "node_modules/log-update/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, - "bin": { - "nanoid": "bin/nanoid.cjs" + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" }, "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" - }, - "node_modules/negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "license": "MIT", + "optional": true, "engines": { - "node": ">= 0.6" + "node": ">=8" } }, - "node_modules/nise": { + "node_modules/lru-cache": { "version": "5.1.1", - "resolved": "https://registry.npmjs.org/nise/-/nise-5.1.1.tgz", - "integrity": "sha512-yr5kW2THW1AkxVmCnKEh4nbYkJdB3I7LUkiUgOvEkOp414mc2UMaHMA7pjq1nYowhdoJZGwEKGaQVbxfpWj10A==", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "dev": true, + "license": "ISC", "dependencies": { - "@sinonjs/commons": "^1.8.3", - "@sinonjs/fake-timers": ">=5", - "@sinonjs/text-encoding": "^0.7.1", - "just-extend": "^4.0.2", - "path-to-regexp": "^1.7.0" + "yallist": "^3.0.2" } }, - "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/path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", + "node_modules/make-dir": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz", + "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==", "dev": true, + "license": "MIT", "dependencies": { - "isarray": "0.0.1" - } - }, - "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "dependencies": { - "whatwg-url": "^5.0.0" + "semver": "^7.5.3" }, "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" + "node": ">=10" }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/node-fetch/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "node_modules/node-fetch/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/node-fetch/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/node-ical": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/node-ical/-/node-ical-0.15.2.tgz", - "integrity": "sha512-p5KD4thji/9/rDLr4+Ig8QZzRhc1otRV1e85nFIgxJBJnLkF3hG15fxB30DlLQ9QtnzpR7AlgERTwhJuszC0cg==", + "node_modules/makeerror": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", + "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "axios": "^1.1.2", - "moment-timezone": "^0.5.31", - "rrule": "2.6.4", - "uuid": "^9.0.0" + "tmpl": "1.0.5" } }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true - }, - "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==", - "dev": true - }, - "node_modules/normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", - "dev": true, + "node_modules/matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "license": "MIT", + "optional": true, "dependencies": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" + "escape-string-regexp": "^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==", + "node_modules/mathml-tag-names": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", + "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "node_modules/mdn-data": { + "version": "2.0.30", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.30.tgz", + "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", "dev": true, - "engines": { - "node": ">=0.10.0" - } + "license": "CC0-1.0" }, - "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==", - "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_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "license": "MIT", "engines": { - "node": ">=4" + "node": ">= 0.6" } }, - "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "node_modules/meow": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-13.2.0.tgz", + "integrity": "sha512-pxQJQzB6djGPXh08dacEloMFopsOqGVRKFPYvPOt9XDZ1HasbgDZA74CJGreSU4G3Ak7EFJGoiH2auq+yXISgA==", "dev": true, - "dependencies": { - "path-key": "^3.0.0" - }, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=18" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/nwsapi": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", - "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==", - "dev": true + "node_modules/merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==", + "license": "MIT" }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "engines": { - "node": ">=0.10.0" - } + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true, + "license": "MIT" }, - "node_modules/object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 8" } }, - "node_modules/object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "optional": true, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "license": "MIT", "engines": { - "node": ">= 0.4" + "node": ">= 0.6" } }, - "node_modules/on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "node_modules/micromatch": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.7.tgz", + "integrity": "sha512-LPP/3KorzCwBxfeUuZmaR6bG2kdeHSbe0P2tY3FLRU4vYrjYz5hI4QZwV0njUx3jeuKe67YukQ1LSPZBKDqO/Q==", + "dev": true, + "license": "MIT", "dependencies": { - "ee-first": "1.1.1" + "braces": "^3.0.3", + "picomatch": "^2.3.1" }, "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dependencies": { - "wrappy": "1" + "node": ">=8.6" } }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "node_modules/micromatch/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", "dev": true, - "dependencies": { - "mimic-fn": "^2.1.0" - }, + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=8.6" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dependencies": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" + "node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "license": "MIT", + "bin": { + "mime": "cli.js" }, "engines": { - "node": ">= 0.8.0" + "node": ">=4" } }, - "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==", - "optional": true, + "node_modules/mime-db": { + "version": "1.52.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", + "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==", + "license": "MIT", "engines": { - "node": ">=6" + "node": ">= 0.6" } }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "node_modules/mime-types": { + "version": "2.1.35", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", + "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", + "license": "MIT", "dependencies": { - "yocto-queue": "^0.1.0" + "mime-db": "1.52.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">= 0.6" } }, - "node_modules/p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "dependencies": { - "p-limit": "^3.0.2" - }, + "node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=6" } }, - "node_modules/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, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "license": "MIT", + "optional": true, "engines": { - "node": ">=6" + "node": ">=4" } }, - "node_modules/parent-module": { + "node_modules/min-indent": { "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "dependencies": { - "callsites": "^3.0.0" - }, + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=4" } }, - "node_modules/parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", + "node_modules/minimatch": { + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, + "license": "ISC", "dependencies": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" + "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, - "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==", - "dev": true, - "dependencies": { - "entities": "^4.4.0" - }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "license": "MIT", "funding": { - "url": "https://github.com/inikulin/parse5?sponsor=1" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "license": "MIT", + "bin": { + "mkdirp": "bin/cmd.js" + }, "engines": { - "node": ">= 0.8" + "node": ">=10" } }, - "node_modules/path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "node_modules/module-alias": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/module-alias/-/module-alias-2.2.3.tgz", + "integrity": "sha512-23g5BFj4zdQL/b6tor7Ji+QY4pEfNH784BMslY9Qb0UnJWRAt+lQGLYmRaM0KDBwIG23ffEBELhZDP2rhi9f/Q==", + "license": "MIT" + }, + "node_modules/module-details-from-path": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/module-details-from-path/-/module-details-from-path-1.0.3.tgz", + "integrity": "sha512-ySViT69/76t8VhE1xXHK6Ch4NcDd26gx0MzKXLO+F7NOtnqH68d9zF94nT8ZWSxXh8ELOERsnJO/sWt1xZYw5A==", + "license": "MIT" + }, + "node_modules/moment": { + "version": "2.30.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", + "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", + "license": "MIT", "engines": { - "node": ">=8" + "node": "*" } }, - "node_modules/path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "node_modules/moment-timezone": { + "version": "0.5.45", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.45.tgz", + "integrity": "sha512-HIWmqA86KcmCAhnMAN0wuDOARV/525R2+lOLotuGFzn4HO+FH+/645z2wx0Dt3iDv6/p61SIvKnDstISainhLQ==", + "license": "MIT", + "dependencies": { + "moment": "^2.29.4" + }, + "engines": { + "node": "*" + } + }, + "node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "license": "MIT" + }, + "node_modules/mute-stream": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", + "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==", + "license": "ISC" + }, + "node_modules/nanoid": { + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==", + "license": "MIT" + }, + "node_modules/needle": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/needle/-/needle-2.4.0.tgz", + "integrity": "sha512-4Hnwzr3mi5L97hMYeNl8wRW/Onhy4nUKR/lVemJ8gJedxxUyBLm9kkrDColJvoSfwi0jCNhD+xCdOtiGDQiRZg==", + "license": "MIT", + "dependencies": { + "debug": "^3.2.6", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + }, + "bin": { + "needle": "bin/needle" + }, + "engines": { + "node": ">= 4.4.x" + } + }, + "node_modules/needle/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "license": "MIT", + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/needle/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, "engines": { "node": ">=0.10.0" } }, - "node_modules/path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "node_modules/negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 0.6" } }, - "node_modules/path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "license": "MIT" }, - "node_modules/path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" + "node_modules/netmask": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz", + "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } }, - "node_modules/path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "node_modules/nise": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nise/-/nise-6.0.0.tgz", + "integrity": "sha512-K8ePqo9BFvN31HXwEtTNGzgrPpmvgciDsFz8aztFjt4LqKO/JeFD8tBOeuDiCMXrIl/m1YvfH8auSpxfaD09wg==", "dev": true, - "engines": { - "node": ">=8" + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/text-encoding": "^0.7.2", + "just-extend": "^6.2.0", + "path-to-regexp": "^6.2.1" } }, - "node_modules/pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "optional": true + "node_modules/nise/node_modules/@sinonjs/fake-timers": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", + "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", + "dev": true, + "license": "BSD-3-Clause", + "dependencies": { + "@sinonjs/commons": "^3.0.0" + } }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true + "node_modules/nise/node_modules/path-to-regexp": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.2.2.tgz", + "integrity": "sha512-GQX3SSMokngb36+whdpRXE+3f9V8UzyAorlYvOGx87ufGHehNTn5lCxrKtLyZ4Yl/wEKnNnr98ZzOwwDZV5ogw==", + "dev": true, + "license": "MIT" }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "node_modules/node-ical": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/node-ical/-/node-ical-0.18.0.tgz", + "integrity": "sha512-FrOUPztjw9OUgSB9o/ffhl86BiVClQTut97C2NqCwKIgOAcKPEw5UQMuSuNJO/Y4hqTyJdKZh2TCqNHQnE9YFg==", + "license": "Apache-2.0", + "dependencies": { + "axios": "1.6.7", + "moment-timezone": "^0.5.44", + "rrule": "2.8.1", + "uuid": "^9.0.0" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "license": "MIT" + }, + "node_modules/node-releases": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz", + "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==", + "dev": true, + "license": "MIT" + }, + "node_modules/normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "license": "BSD-2-Clause", + "dependencies": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" } }, - "node_modules/pify": { + "node_modules/normalize-package-data/node_modules/semver": { + "version": "5.7.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", + "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", + "dev": true, + "license": "ISC", + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/normalize-path": { "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "optional": true, + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "license": "MIT", "engines": { - "node": ">=4" + "node": ">=0.10.0" } }, - "node_modules/pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", - "dev": true, + "node_modules/normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "license": "MIT", + "optional": true, "engines": { - "node": ">= 6" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", "dev": true, + "license": "MIT", "dependencies": { - "find-up": "^4.0.0" + "path-key": "^3.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/pkg-dir/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, + "node_modules/nssocket": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/nssocket/-/nssocket-0.6.0.tgz", + "integrity": "sha512-a9GSOIql5IqgWJR3F/JXG4KpJTA3Z53Cj0MeMvGpglytB1nxE4PdFNC0jINe27CS7cGivoynwc054EzCcT3M3w==", + "license": "MIT", "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "eventemitter2": "~0.4.14", + "lazy": "~1.0.11" }, "engines": { - "node": ">=8" + "node": ">= 0.10.x" } }, - "node_modules/pkg-dir/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==", + "node_modules/nssocket/node_modules/eventemitter2": { + "version": "0.4.14", + "resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-0.4.14.tgz", + "integrity": "sha512-K7J4xq5xAD5jHsGM5ReWXRTFa3JRGofHiMcVgQ8PRwgWxzjHpMWCIzsmyf60+mh8KLsqYPcjUMa0AC4hd6lPyQ==", + "license": "MIT" + }, + "node_modules/nwsapi": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.10.tgz", + "integrity": "sha512-QK0sRs7MKv0tKe1+5uZIQk/C8XGza4DAnztJG8iD+TpJIORARrCxczA738awHrZoHeTjSSoHqao2teO0dC/gFQ==", "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, + "license": "MIT" + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/pkg-dir/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, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "license": "MIT", "dependencies": { - "p-try": "^2.0.0" + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" }, "engines": { - "node": ">=6" + "node": ">= 0.4" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/pkg-dir/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==", + "node_modules/object.fromentries": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.8.tgz", + "integrity": "sha512-k6E21FzySsSK5a21KRADBd/NGneRegFO5pLHfdQLpRDETUNJueLXs3WCzyQ3tFRDYgbq3KHGXfTbi2bs8WQ6rQ==", "dev": true, + "license": "MIT", "dependencies": { - "p-limit": "^2.2.0" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-object-atoms": "^1.0.0" }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/playwright": { - "version": "1.27.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.27.1.tgz", - "integrity": "sha512-xXYZ7m36yTtC+oFgqH0eTgullGztKSRMb4yuwLPl8IYSmgBM88QiB+3IWb1mRIC9/NNwcgbG0RwtFlg+EAFQHQ==", + "node_modules/object.groupby": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.3.tgz", + "integrity": "sha512-+Lhy3TQTuzXI5hevh8sBGqbmurHbbIjAi0Z4S63nthVLmLxfbj4T54a4CfZrXIrt9iP4mVAPYMo/v99taj3wjQ==", "dev": true, - "hasInstallScript": true, + "license": "MIT", "dependencies": { - "playwright-core": "1.27.1" - }, - "bin": { - "playwright": "cli.js" + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2" }, "engines": { - "node": ">=14" + "node": ">= 0.4" } }, - "node_modules/playwright-core": { - "version": "1.27.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.27.1.tgz", - "integrity": "sha512-9EmeXDncC2Pmp/z+teoVYlvmPWUC6ejSSYZUln7YaP89Z6lpAaiaAnqroUt/BoLo8tn7WYShcfaCh+xofZa44Q==", + "node_modules/object.values": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.2.0.tgz", + "integrity": "sha512-yBYjY9QX2hnRmZHAjG/f13MzmBzxzYgQhFrke06TTyKY5zSTEqkOeukBzIdVA3j3ulu8Qa3MbVFShV7T2RmGtQ==", "dev": true, - "bin": { - "playwright": "cli.js" + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" }, "engines": { - "node": ">=14" - } - }, - "node_modules/postcss": { - "version": "8.4.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", - "integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - } - ], + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/on-finished": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", + "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", + "license": "MIT", "dependencies": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" + "ee-first": "1.1.1" }, "engines": { - "node": "^10 || ^12 || >=14" + "node": ">= 0.8" } }, - "node_modules/postcss-media-query-parser": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", - "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", - "dev": true - }, - "node_modules/postcss-resolve-nested-selector": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", - "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==", - "dev": true + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "license": "ISC", + "dependencies": { + "wrappy": "1" + } }, - "node_modules/postcss-safe-parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", - "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", "dev": true, + "license": "MIT", + "dependencies": { + "mimic-fn": "^2.1.0" + }, "engines": { - "node": ">=12.0" + "node": ">=6" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.3.3" + "url": "https://github.com/sponsors/sindresorhus" } }, - "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==", + "node_modules/optimist": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/optimist/-/optimist-0.6.1.tgz", + "integrity": "sha512-snN4O4TkigujZphWLN0E//nQmm7790RYaE53DdL7ZYwee2D8DDo9/EyYiKUfN3rneWUjhJnueija3G9I2i0h3g==", "dev": true, + "license": "MIT/X11", "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" + "minimist": "~0.0.1", + "wordwrap": "~0.0.2" } }, - "node_modules/postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true + "node_modules/optimist/node_modules/minimist": { + "version": "0.0.10", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.10.tgz", + "integrity": "sha512-iotkTvxc+TwOm5Ieim8VnSNvCDjCK9S8G3scJ50ZthspSxa7jx50jkhYduuAtAjvfDUwSgOwf8+If99AlOEhyw==", + "dev": true, + "license": "MIT" }, - "node_modules/prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "node_modules/optimist/node_modules/wordwrap": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-0.0.3.tgz", + "integrity": "sha512-1tMA907+V4QmxV7dbRvb4/8MaRALK6q9Abid3ndMYnbyo8piisCmeONVqVSXqQA3KaP4SLt5b7ud6E2sqP8TFw==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/optionator": { + "version": "0.9.4", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", + "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==", + "license": "MIT", + "dependencies": { + "deep-is": "^0.1.3", + "fast-levenshtein": "^2.0.6", + "levn": "^0.4.1", + "prelude-ls": "^1.2.1", + "type-check": "^0.4.0", + "word-wrap": "^1.2.5" + }, "engines": { "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==", + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "license": "MIT", "optional": true, "engines": { - "node": ">=4" + "node": ">=8" } }, - "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==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "license": "MIT", + "dependencies": { + "yocto-queue": "^0.1.0" }, "engines": { - "node": ">=10.13.0" + "node": ">=10" }, "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, + "node_modules/p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "license": "MIT", "dependencies": { - "fast-diff": "^1.1.2" + "p-limit": "^3.0.2" }, "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/pretty-format": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.2.1.tgz", - "integrity": "sha512-Y41Sa4aLCtKAXvwuIpTvcFBkyeYp2gdFWzXGA+ZNES3VwURIB165XO/z7CjETwzCCS53MjW/rLMyyqEnTtaOfA==", - "dev": true, - "dependencies": { - "@jest/schemas": "^29.0.0", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" + "node": ">=10" }, - "engines": { - "node": "^14.15.0 || ^16.10.0 || >=18.0.0" + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/pretty-format/node_modules/ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "node_modules/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, + "license": "MIT", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=6" } }, - "node_modules/pretty-quick": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.3.tgz", - "integrity": "sha512-kOCi2FJabvuh1as9enxYmrnBC6tVMoVOenMaBqRfsvBHB0cbpYHjdQEpSglpASDFEXVwplpcGR4CLEaisYAFcA==", - "dev": true, + "node_modules/pac-proxy-agent": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.0.1.tgz", + "integrity": "sha512-ASV8yU4LLKBAjqIPMbrgtaKIvxQri/yh2OpI+S6hVa9JRkUI3Y3NPFbfngDtY7oFtSMD3w31Xns89mDa3Feo5A==", + "license": "MIT", "dependencies": { - "chalk": "^3.0.0", - "execa": "^4.0.0", - "find-up": "^4.1.0", - "ignore": "^5.1.4", - "mri": "^1.1.5", - "multimatch": "^4.0.0" - }, - "bin": { - "pretty-quick": "bin/pretty-quick.js" + "@tootallnate/quickjs-emscripten": "^0.23.0", + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "get-uri": "^6.0.1", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "pac-resolver": "^7.0.0", + "socks-proxy-agent": "^8.0.2" }, "engines": { - "node": ">=10.13" - }, - "peerDependencies": { - "prettier": ">=2.0.0" + "node": ">= 14" } }, - "node_modules/pretty-quick/node_modules/chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, + "node_modules/pac-resolver": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz", + "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==", + "license": "MIT", "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "degenerator": "^5.0.0", + "netmask": "^2.0.2" }, "engines": { - "node": ">=8" + "node": ">= 14" } }, - "node_modules/pretty-quick/node_modules/execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", + "node_modules/package-json-validator": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/package-json-validator/-/package-json-validator-0.6.4.tgz", + "integrity": "sha512-sp5bWr5eUoVgNV50vsJyil0XCluM+qMvtba8X4ug5Z/0YtYZsePka+tZgqiZnAyFyf5pwXaSDwYncFdSEzX7PA==", "dev": true, "dependencies": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.0" - }, - "engines": { - "node": ">=10" + "optimist": "~0.6.0" }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" + "bin": { + "pjv": "bin/pjv" } }, - "node_modules/pretty-quick/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, + "node_modules/pako": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/pako/-/pako-0.2.9.tgz", + "integrity": "sha512-NUcwaKxUxWrZLpDG+z/xZaCgQITkA/Dv4V/T6bw7VON6l1Xz/VnrBqrYjZQ12TamKHzITTfOEIYUj48y2KXImA==", + "license": "MIT" + }, + "node_modules/parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "license": "MIT", "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" + "callsites": "^3.0.0" }, "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/pretty-quick/node_modules/get-stream": { + "node_modules/parse-json": { "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", + "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", "dev": true, + "license": "MIT", "dependencies": { - "pump": "^3.0.0" + "@babel/code-frame": "^7.0.0", + "error-ex": "^1.3.1", + "json-parse-even-better-errors": "^2.3.0", + "lines-and-columns": "^1.1.6" }, "engines": { "node": ">=8" @@ -6338,265 +8890,180 @@ "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", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "dev": true, - "engines": { - "node": ">=8.12.0" - } - }, - "node_modules/pretty-quick/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==", + "node_modules/parse5": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz", + "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==", "dev": true, + "license": "MIT", "dependencies": { - "p-locate": "^4.1.0" + "entities": "^4.4.0" }, - "engines": { - "node": ">=8" + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" } }, - "node_modules/pretty-quick/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, + "node_modules/parseley": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/parseley/-/parseley-0.12.1.tgz", + "integrity": "sha512-e6qHKe3a9HWr0oMRVDTRhKce+bRO8VGQR3NyVwcjwrbhMmFCX9KszEV35+rn4AdilFAq9VPxP/Fe1wC9Qjd2lw==", + "license": "MIT", "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" + "leac": "^0.6.0", + "peberminta": "^0.9.0" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://ko-fi.com/killymxi" } }, - "node_modules/pretty-quick/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" - }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 0.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/path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "license": "MIT", + "engines": { + "node": ">=8" + } }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "optional": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "dependencies": { - "kleur": "^3.0.3", - "sisteransi": "^1.0.5" - }, + "node_modules/path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "license": "MIT", "engines": { - "node": ">= 6" + "node": ">=0.10.0" } }, - "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", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "license": "MIT", "engines": { - "node": ">= 0.10" + "node": ">=8" } }, - "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", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "license": "MIT" }, - "node_modules/pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "devOptional": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } + "node_modules/path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==", + "license": "MIT" }, - "node_modules/punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "node_modules/path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", + "dev": true, + "license": "MIT", "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/qs": { - "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" - }, - "engines": { - "node": ">=0.6" - }, + "node_modules/peberminta": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/peberminta/-/peberminta-0.9.0.tgz", + "integrity": "sha512-XIxfHpEuSJbITd1H3EeQwpcZbTLHc+VVr8ANI9t5sit565tsI4/xK3KWTUFE2e6QiangUkh3B0jihzmGnNrRsQ==", + "license": "MIT", "funding": { - "url": "https://github.com/sponsors/ljharb" + "url": "https://ko-fi.com/killymxi" } }, - "node_modules/querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true + "node_modules/pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "license": "MIT", + "optional": true }, - "node_modules/queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "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/picocolors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.1.tgz", + "integrity": "sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==", + "dev": true, + "license": "ISC" }, - "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==", + "node_modules/picomatch": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", + "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" - } - }, - "node_modules/range_check": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/range_check/-/range_check-2.0.4.tgz", - "integrity": "sha512-aed0ocXXj+SIiNNN9b+mZWA3Ow2GXHtftOGk2xQwshK5GbEZAvUcPWNQBLTx/lPcdFRIUFlFCRtHTQNIFMqynQ==", - "dependencies": { - "ip6": "^0.2.0", - "ipaddr.js": "^1.9.1" + "node": ">=12" }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", - "engines": { - "node": ">= 0.6" + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" + "node_modules/pidtree": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.6.0.tgz", + "integrity": "sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==", + "dev": true, + "license": "MIT", + "bin": { + "pidtree": "bin/pidtree.js" }, "engines": { - "node": ">= 0.8" + "node": ">=0.10" } }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/pidusage": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-3.0.2.tgz", + "integrity": "sha512-g0VU+y08pKw5M8EZ2rIGiEBaB8wrQMjYGFfW2QVIfyT8V+fq8YFLkvlz4bz5ljvFDJYNFCWT3PWqcRr2FKO81w==", + "license": "MIT", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "safe-buffer": "^5.2.1" }, "engines": { - "node": ">=0.10.0" + "node": ">=10" } }, - "node_modules/react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "node_modules/read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", + "node_modules/pirates": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.6.tgz", + "integrity": "sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg==", "dev": true, - "dependencies": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">= 6" } }, - "node_modules/read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", + "node_modules/pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", "dev": true, + "license": "MIT", "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" + "find-up": "^4.0.0" }, "engines": { "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-pkg-up/node_modules/find-up": { + "node_modules/pkg-dir/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, + "license": "MIT", "dependencies": { "locate-path": "^5.0.0", "path-exists": "^4.0.0" @@ -6605,11 +9072,12 @@ "node": ">=8" } }, - "node_modules/read-pkg-up/node_modules/locate-path": { + "node_modules/pkg-dir/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, + "license": "MIT", "dependencies": { "p-locate": "^4.1.0" }, @@ -6617,11 +9085,12 @@ "node": ">=8" } }, - "node_modules/read-pkg-up/node_modules/p-limit": { + "node_modules/pkg-dir/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, + "license": "MIT", "dependencies": { "p-try": "^2.0.0" }, @@ -6632,11 +9101,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/read-pkg-up/node_modules/p-locate": { + "node_modules/pkg-dir/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, + "license": "MIT", "dependencies": { "p-limit": "^2.2.0" }, @@ -6644,1105 +9114,1247 @@ "node": ">=8" } }, - "node_modules/read-pkg-up/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/read-pkg/node_modules/hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "node_modules/read-pkg/node_modules/normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "node_modules/playwright": { + "version": "1.44.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.44.1.tgz", + "integrity": "sha512-qr/0UJ5CFAtloI3avF95Y0L1xQo6r3LQArLIg/z/PoGJ6xa+EwzrwO5lpNr/09STxdHuUoP2mvuELJS+hLdtgg==", "dev": true, + "license": "Apache-2.0", "dependencies": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "node_modules/read-pkg/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, + "playwright-core": "1.44.1" + }, "bin": { - "semver": "bin/semver" + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "fsevents": "2.3.2" } }, - "node_modules/read-pkg/node_modules/type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", + "node_modules/playwright-core": { + "version": "1.44.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.44.1.tgz", + "integrity": "sha512-wh0JWtYTrhv1+OSsLPgFzGzt67Y7BE/ZS3jEqgGBlp2ppp1ZDj8c+9IARNW4dwf1poq5MgHreEM2KV/GuR4cFA==", "dev": true, + "license": "Apache-2.0", + "bin": { + "playwright-core": "cli.js" + }, "engines": { - "node": ">=8" + "node": ">=16" } }, - "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", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dev": true, - "dependencies": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", + "node_modules/playwright/node_modules/fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], "engines": { - "node": ">=0.10.0" + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "node_modules/pluralize": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/pluralize/-/pluralize-8.0.0.tgz", + "integrity": "sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==", "dev": true, + "license": "MIT", "engines": { - "node": ">=0.10.0" + "node": ">=4" } }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true - }, - "node_modules/resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "dependencies": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" + "node_modules/pm2": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/pm2/-/pm2-5.4.1.tgz", + "integrity": "sha512-y9ndADjy78XfzdbVHISn4WiUTrcvmsO7ieCtM/oC80rwPgBDg+bHkkz1e4eaLOW5a7sJsnDfQjJe4AqxNnIw5Q==", + "license": "AGPL-3.0", + "dependencies": { + "@pm2/agent": "~2.0.0", + "@pm2/io": "~6.0.0", + "@pm2/js-api": "~0.8.0", + "@pm2/pm2-version-check": "latest", + "async": "~3.2.0", + "blessed": "0.1.81", + "chalk": "3.0.0", + "chokidar": "^3.5.3", + "cli-tableau": "^2.0.0", + "commander": "2.15.1", + "croner": "~4.1.92", + "dayjs": "~1.11.5", + "debug": "^4.3.1", + "enquirer": "2.3.6", + "eventemitter2": "5.0.1", + "fclone": "1.0.11", + "js-yaml": "~4.1.0", + "mkdirp": "1.0.4", + "needle": "2.4.0", + "pidusage": "~3.0", + "pm2-axon": "~4.0.1", + "pm2-axon-rpc": "~0.7.1", + "pm2-deploy": "~1.0.2", + "pm2-multimeter": "^0.1.2", + "promptly": "^2", + "semver": "^7.2", + "source-map-support": "0.5.21", + "sprintf-js": "1.1.2", + "vizion": "~2.2.1" }, "bin": { - "resolve": "bin/resolve" + "pm2": "bin/pm2", + "pm2-dev": "bin/pm2-dev", + "pm2-docker": "bin/pm2-docker", + "pm2-runtime": "bin/pm2-runtime" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">=12.0.0" + }, + "optionalDependencies": { + "pm2-sysmonit": "^1.2.8" } }, - "node_modules/resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, + "node_modules/pm2-axon": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pm2-axon/-/pm2-axon-4.0.1.tgz", + "integrity": "sha512-kES/PeSLS8orT8dR5jMlNl+Yu4Ty3nbvZRmaAtROuVm9nYYGiaoXqqKQqQYzWQzMYWUKHMQTvBlirjE5GIIxqg==", + "license": "MIT", "dependencies": { - "resolve-from": "^5.0.0" + "amp": "~0.3.1", + "amp-message": "~0.1.1", + "debug": "^4.3.1", + "escape-string-regexp": "^4.0.0" }, "engines": { - "node": ">=8" + "node": ">=5" } }, - "node_modules/resolve-cwd/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, + "node_modules/pm2-axon-rpc": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/pm2-axon-rpc/-/pm2-axon-rpc-0.7.1.tgz", + "integrity": "sha512-FbLvW60w+vEyvMjP/xom2UPhUN/2bVpdtLfKJeYM3gwzYhoTEEChCOICfFzxkxuoEleOlnpjie+n1nue91bDQw==", + "license": "MIT", + "dependencies": { + "debug": "^4.3.1" + }, "engines": { - "node": ">=8" + "node": ">=5" } }, - "node_modules/resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "node_modules/pm2-deploy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pm2-deploy/-/pm2-deploy-1.0.2.tgz", + "integrity": "sha512-YJx6RXKrVrWaphEYf++EdOOx9EH18vM8RSZN/P1Y+NokTKqYAca/ejXwVLyiEpNju4HPZEk3Y2uZouwMqUlcgg==", + "license": "MIT", + "dependencies": { + "run-series": "^1.1.8", + "tv4": "^1.3.0" + }, "engines": { - "node": ">=4" + "node": ">=4.0.0" } }, - "node_modules/resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", - "dev": true, - "engines": { - "node": ">=10" + "node_modules/pm2-multimeter": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/pm2-multimeter/-/pm2-multimeter-0.1.2.tgz", + "integrity": "sha512-S+wT6XfyKfd7SJIBqRgOctGxaBzUOmVQzTAS+cg04TsEUObJVreha7lvCfX8zzGVr871XwCSnHUU7DQQ5xEsfA==", + "license": "MIT/X11", + "dependencies": { + "charm": "~0.1.1" } }, - "node_modules/responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", + "node_modules/pm2-sysmonit": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/pm2-sysmonit/-/pm2-sysmonit-1.2.8.tgz", + "integrity": "sha512-ACOhlONEXdCTVwKieBIQLSi2tQZ8eKinhcr9JpZSUAL8Qy0ajIgRtsLxG/lwPOW3JEKqPyw/UaHmTWhUzpP4kA==", + "license": "Apache", "optional": true, "dependencies": { - "lowercase-keys": "^1.0.0" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" + "async": "^3.2.0", + "debug": "^4.3.1", + "pidusage": "^2.0.21", + "systeminformation": "^5.7", + "tx2": "~1.0.4" } }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "node_modules/pm2-sysmonit/node_modules/pidusage": { + "version": "2.0.21", + "resolved": "https://registry.npmjs.org/pidusage/-/pidusage-2.0.21.tgz", + "integrity": "sha512-cv3xAQos+pugVX+BfXpHsbyz/dLzX+lr44zNMsYiGxUw+kV5sgQCIcLd1z+0vq+KyC7dJ+/ts2PsfgWfSC3WXA==", + "license": "MIT", + "optional": true, "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" + "safe-buffer": "^5.2.1" }, - "funding": { - "url": "https://github.com/sponsors/isaacs" + "engines": { + "node": ">=8" } }, - "node_modules/roarr": { - "version": "2.15.4", - "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", - "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", - "optional": true, + "node_modules/pm2/node_modules/chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "license": "MIT", "dependencies": { - "boolean": "^3.0.1", - "detect-node": "^2.0.4", - "globalthis": "^1.0.1", - "json-stringify-safe": "^5.0.1", - "semver-compare": "^1.0.0", - "sprintf-js": "^1.1.2" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "engines": { - "node": ">=8.0" + "node": ">=8" } }, - "node_modules/rrule": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/rrule/-/rrule-2.6.4.tgz", - "integrity": "sha512-sLdnh4lmjUqq8liFiOUXD5kWp/FcnbDLPwq5YAc/RrN6120XOPb86Ae5zxF7ttBVq8O3LxjjORMEit1baluahA==", + "node_modules/pm2/node_modules/commander": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "license": "MIT" + }, + "node_modules/pm2/node_modules/source-map-support": { + "version": "0.5.21", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.21.tgz", + "integrity": "sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==", + "license": "MIT", "dependencies": { - "tslib": "^1.10.0" - }, - "optionalDependencies": { - "luxon": "^1.21.3" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "node_modules/run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "node_modules/possible-typed-array-names": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", + "integrity": "sha512-d7Uw+eZoloe0EHDIYoe+bQ5WXnGMOpmiZFTuMWCwpjzzkL2nTjcKiAk4hh8TjnGye2TwWOk3UXucZ+3rbmBa8Q==", + "license": "MIT", + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/postcss": { + "version": "8.4.38", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz", + "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==", + "dev": true, "funding": [ { - "type": "github", - "url": "https://github.com/sponsors/feross" + "type": "opencollective", + "url": "https://opencollective.com/postcss/" }, { - "type": "patreon", - "url": "https://www.patreon.com/feross" + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" }, { - "type": "consulting", - "url": "https://feross.org/support" + "type": "github", + "url": "https://github.com/sponsors/ai" } ], + "license": "MIT", "dependencies": { - "queue-microtask": "^1.2.2" + "nanoid": "^3.3.7", + "picocolors": "^1.0.0", + "source-map-js": "^1.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "node_modules/postcss-resolve-nested-selector": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", + "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==", + "dev": true, + "license": "MIT" + }, + "node_modules/postcss-safe-parser": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-7.0.0.tgz", + "integrity": "sha512-ovehqRNVCpuFzbXoTb4qLtyzK3xn3t/CUBxOs8LsnQjQrShaB4lKiHoVqY8ANaC0hBMHq5QVWk77rwGklFUDrg==", + "dev": true, "funding": [ { - "type": "github", - "url": "https://github.com/sponsors/feross" + "type": "opencollective", + "url": "https://opencollective.com/postcss/" }, { - "type": "patreon", - "url": "https://www.patreon.com/feross" + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss-safe-parser" }, { - "type": "consulting", - "url": "https://feross.org/support" + "type": "github", + "url": "https://github.com/sponsors/ai" } - ] - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + ], + "license": "MIT", + "engines": { + "node": ">=18.0" + }, + "peerDependencies": { + "postcss": "^8.4.31" + } }, - "node_modules/saxes": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", - "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "node_modules/postcss-selector-parser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.1.0.tgz", + "integrity": "sha512-UMz42UD0UY0EApS0ZL9o1XnLhSTtvvvLe5Dc2H2O56fvRZi+KulDyf5ctDhhtYJBGKStV2FL1fy6253cmLgqVQ==", "dev": true, + "license": "MIT", "dependencies": { - "xmlchars": "^2.2.0" + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" }, "engines": { - "node": ">=v12.22.7" + "node": ">=4" } }, - "node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "devOptional": true, - "bin": { - "semver": "bin/semver.js" - } + "node_modules/postcss-value-parser": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", + "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", + "dev": true, + "license": "MIT" }, - "node_modules/semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", - "optional": true + "node_modules/prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "license": "MIT", + "engines": { + "node": ">= 0.8.0" + } }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dependencies": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" + "node_modules/prettier": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.3.2.tgz", + "integrity": "sha512-rAVeHYMcv8ATV5d508CFdn+8/pHPpXeIid1DdrPwXnaAdH7cqjVbpJaT5eq4yRAFU/lsbwYwSF/n5iNrdJHPQA==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" }, "engines": { - "node": ">= 0.8.0" + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/send/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "node_modules/prettier-linter-helpers": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", + "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", + "dev": true, + "license": "MIT", "dependencies": { - "ms": "2.0.0" + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" } }, - "node_modules/send/node_modules/debug/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - }, - "node_modules/send/node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - }, - "node_modules/serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", - "optional": true, + "node_modules/pretty-format": { + "version": "29.7.0", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz", + "integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==", + "dev": true, + "license": "MIT", "dependencies": { - "type-fest": "^0.13.1" + "@jest/schemas": "^29.6.3", + "ansi-styles": "^5.0.0", + "react-is": "^18.0.0" }, "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, - "node_modules/serialize-error/node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "optional": true, + "node_modules/pretty-format/node_modules/ansi-styles": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", + "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", + "dev": true, + "license": "MIT", "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "license": "MIT", + "optional": true, "engines": { - "node": ">= 0.8.0" + "node": ">=0.4.0" } }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" + "node_modules/promptly": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/promptly/-/promptly-2.2.0.tgz", + "integrity": "sha512-aC9j+BZsRSSzEsXBNBwDnAxujdx19HycZoKgRgzWnS8eOHg1asuf9heuLprfbe739zY3IdUQx+Egv6Jn135WHA==", + "license": "MIT", + "dependencies": { + "read": "^1.0.4" + } }, - "node_modules/shebang-command": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "node_modules/prompts": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", + "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", + "dev": true, + "license": "MIT", "dependencies": { - "shebang-regex": "^3.0.0" + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" }, "engines": { - "node": ">=8" + "node": ">= 6" } }, - "node_modules/shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "node_modules/proxy-addr": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", + "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", + "license": "MIT", + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, "engines": { - "node": ">=8" + "node": ">= 0.10" } }, - "node_modules/side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "node_modules/proxy-agent": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.3.1.tgz", + "integrity": "sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==", + "license": "MIT", "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" + "agent-base": "^7.0.2", + "debug": "^4.3.4", + "http-proxy-agent": "^7.0.0", + "https-proxy-agent": "^7.0.2", + "lru-cache": "^7.14.1", + "pac-proxy-agent": "^7.0.1", + "proxy-from-env": "^1.1.0", + "socks-proxy-agent": "^8.0.2" }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "engines": { + "node": ">= 14" } }, - "node_modules/signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true + "node_modules/proxy-agent/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "license": "ISC", + "engines": { + "node": ">=12" + } }, - "node_modules/sinon": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-14.0.1.tgz", - "integrity": "sha512-JhJ0jCiyBWVAHDS+YSjgEbDn7Wgz9iIjA1/RK+eseJN0vAAWIWiXBdrnb92ELPyjsfreCYntD1ORtLSfIrlvSQ==", + "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==", + "license": "MIT" + }, + "node_modules/psl": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", + "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", "dev": true, + "license": "MIT" + }, + "node_modules/pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "license": "MIT", + "optional": true, "dependencies": { - "@sinonjs/commons": "^1.8.3", - "@sinonjs/fake-timers": "^9.1.2", - "@sinonjs/samsam": "^6.1.1", - "diff": "^5.0.0", - "nise": "^5.1.1", - "supports-color": "^7.2.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/sinon" + "end-of-stream": "^1.1.0", + "once": "^1.3.1" } }, - "node_modules/sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "node_modules/slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true, + "node_modules/punycode": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", + "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=6" } }, - "node_modules/slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "node_modules/pure-rand": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/pure-rand/-/pure-rand-6.1.0.tgz", + "integrity": "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==", "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/dubzzz" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fast-check" + } + ], + "license": "MIT" + }, + "node_modules/qs": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", + "integrity": "sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==", + "license": "BSD-3-Clause", "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/querystringify": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", + "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", + "dev": true, + "license": "MIT" + }, + "node_modules/queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "license": "MIT", + "optional": true, "engines": { "node": ">=10" }, "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/socket.io": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.3.tgz", - "integrity": "sha512-zdpnnKU+H6mOp7nYRXH4GNv1ux6HL6+lHL8g7Ds7Lj8CkdK1jJK/dlwsKDculbyOHifcJ0Pr/yeXnZQ5GeFrcg==", + "node_modules/range_check": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/range_check/-/range_check-2.0.4.tgz", + "integrity": "sha512-aed0ocXXj+SIiNNN9b+mZWA3Ow2GXHtftOGk2xQwshK5GbEZAvUcPWNQBLTx/lPcdFRIUFlFCRtHTQNIFMqynQ==", + "license": "BSD-2-Clause", "dependencies": { - "accepts": "~1.3.4", - "base64id": "~2.0.0", - "debug": "~4.3.2", - "engine.io": "~6.2.0", - "socket.io-adapter": "~2.4.0", - "socket.io-parser": "~4.2.0" + "ip6": "^0.2.0", + "ipaddr.js": "^1.9.1" }, "engines": { "node": ">=10.0.0" } }, - "node_modules/socket.io-adapter": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz", - "integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==" - }, - "node_modules/socket.io-parser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz", - "integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==", - "dependencies": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1" - }, + "node_modules/range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "license": "MIT", "engines": { - "node": ">=10.0.0" + "node": ">= 0.6" } }, - "node_modules/source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true, + "node_modules/raw-body": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.2.tgz", + "integrity": "sha512-8zGqypfENjCIqGhgXToC8aB2r7YrBX+AQAfIPs/Mlk+BtPTztOvTS01NRW/3Eh60J+a48lt8qsCzirQ6loCVfA==", + "license": "MIT", + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, "engines": { - "node": ">=0.10.0" + "node": ">= 0.8" } }, - "node_modules/source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "license": "MIT", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, "engines": { "node": ">=0.10.0" } }, - "node_modules/source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } + "license": "MIT" }, - "node_modules/spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, + "node_modules/read": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz", + "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==", + "license": "ISC", "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "mute-stream": "~0.0.4" + }, + "engines": { + "node": ">=0.8" } }, - "node_modules/spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "node_modules/spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "node_modules/read-pkg": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", + "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", "dev": true, + "license": "MIT", "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "@types/normalize-package-data": "^2.4.0", + "normalize-package-data": "^2.5.0", + "parse-json": "^5.0.0", + "type-fest": "^0.6.0" + }, + "engines": { + "node": ">=8" } }, - "node_modules/spdx-license-ids": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", - "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", - "dev": true - }, - "node_modules/sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "optional": true - }, - "node_modules/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==", + "node_modules/read-pkg-up": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", + "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", "dev": true, + "license": "MIT", "dependencies": { - "escape-string-regexp": "^2.0.0" + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" }, "engines": { - "node": ">=10" + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/stack-utils/node_modules/escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", + "node_modules/read-pkg-up/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, + "license": "MIT", + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, "engines": { "node": ">=8" } }, - "node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "engines": { - "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", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "node_modules/read-pkg-up/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, + "license": "MIT", "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" + "p-locate": "^4.1.0" }, "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/string-width": { - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "node_modules/read-pkg-up/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, + "license": "MIT", "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" + "p-try": "^2.0.0" }, "engines": { - "node": ">=8" + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "node_modules/read-pkg-up/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, + "license": "MIT", "dependencies": { - "ansi-regex": "^5.0.1" + "p-limit": "^2.2.0" }, "engines": { "node": ">=8" } }, - "node_modules/strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "node_modules/read-pkg-up/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, + "license": "(MIT OR CC0-1.0)", "engines": { "node": ">=8" } }, - "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "node_modules/read-pkg/node_modules/type-fest": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", + "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", "dev": true, + "license": "(MIT OR CC0-1.0)", "engines": { - "node": ">=6" + "node": ">=8" } }, - "node_modules/strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", - "dev": true, + "node_modules/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "license": "MIT", "dependencies": { - "min-indent": "^1.0.0" + "picomatch": "^2.2.1" }, "engines": { - "node": ">=8" + "node": ">=8.10.0" } }, - "node_modules/strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "node_modules/readdirp/node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=8.6" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/jonschlinkert" } }, - "node_modules/style-search": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", - "integrity": "sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==", - "dev": true - }, - "node_modules/stylelint": { - "version": "14.14.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.14.0.tgz", - "integrity": "sha512-yUI+4xXfPHVnueYddSQ/e1GuEA/2wVhWQbGj16AmWLtQJtn28lVxfS4b0CsWyVRPgd3Auzi0NXOthIEUhtQmmA==", + "node_modules/regexp-tree": { + "version": "0.1.27", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.27.tgz", + "integrity": "sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==", "dev": true, - "dependencies": { - "@csstools/selector-specificity": "^2.0.2", - "balanced-match": "^2.0.0", - "colord": "^2.9.3", - "cosmiconfig": "^7.0.1", - "css-functions-list": "^3.1.0", - "debug": "^4.3.4", - "fast-glob": "^3.2.12", - "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^6.0.1", - "global-modules": "^2.0.0", - "globby": "^11.1.0", - "globjoin": "^0.1.4", - "html-tags": "^3.2.0", - "ignore": "^5.2.0", - "import-lazy": "^4.0.0", - "imurmurhash": "^0.1.4", - "is-plain-object": "^5.0.0", - "known-css-properties": "^0.25.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.17", - "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-value-parser": "^4.2.0", - "resolve-from": "^5.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "style-search": "^0.1.0", - "supports-hyperlinks": "^2.3.0", - "svg-tags": "^1.0.0", - "table": "^6.8.0", - "v8-compile-cache": "^2.3.0", - "write-file-atomic": "^4.0.2" - }, + "license": "MIT", "bin": { - "stylelint": "bin/stylelint.js" + "regexp-tree": "bin/regexp-tree" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.2.tgz", + "integrity": "sha512-NcDiDkTLuPR+++OCKB0nWafEmhg/Da8aUPLPMQbK+bxKKCm1/S5he+AqYa4PlMCVBalb4/yxIRub6qkEx5yJbw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "define-properties": "^1.2.1", + "es-errors": "^1.3.0", + "set-function-name": "^2.0.1" }, "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + "node": ">= 0.4" }, "funding": { - "type": "opencollective", - "url": "https://opencollective.com/stylelint" + "url": "https://github.com/sponsors/ljharb" } }, - "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==", + "node_modules/regjsparser": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.10.0.tgz", + "integrity": "sha512-qx+xQGZVsy55CH0a1hiVwHmqjLryfh7wQyF5HO07XJ9f7dQMY/gPQHhlyDkIzJKC+x2fUCpCcUODUUUFrm7SHA==", "dev": true, - "bin": { - "stylelint-config-prettier": "bin/check.js", - "stylelint-config-prettier-check": "bin/check.js" - }, - "engines": { - "node": ">= 12" + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~0.5.0" }, - "peerDependencies": { - "stylelint": ">=11.0.0" + "bin": { + "regjsparser": "bin/parser" } }, - "node_modules/stylelint-config-recommended": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-9.0.0.tgz", - "integrity": "sha512-9YQSrJq4NvvRuTbzDsWX3rrFOzOlYBmZP+o513BJN/yfEmGSr0AxdvrWs0P/ilSpVV/wisamAHu5XSk8Rcf4CQ==", + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", "dev": true, - "peerDependencies": { - "stylelint": "^14.10.0" + "bin": { + "jsesc": "bin/jsesc" } }, - "node_modules/stylelint-config-standard": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-29.0.0.tgz", - "integrity": "sha512-uy8tZLbfq6ZrXy4JKu3W+7lYLgRQBxYTUUB88vPgQ+ZzAxdrvcaSUW9hOMNLYBnwH+9Kkj19M2DHdZ4gKwI7tg==", - "dev": true, - "dependencies": { - "stylelint-config-recommended": "^9.0.0" - }, - "peerDependencies": { - "stylelint": "^14.14.0" + "node_modules/replace-last": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/replace-last/-/replace-last-1.2.6.tgz", + "integrity": "sha512-Cj+MK38VtNu1S5J73mEZY3ciQb9dJajNq1Q8inP4dn/MhJMjHwoAF3Z3FjspwAEV9pfABl565MQucmrjOkty4g==", + "license": "ISC", + "engines": { + "node": ">= 4.0.0" } }, - "node_modules/stylelint-prettier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/stylelint-prettier/-/stylelint-prettier-2.0.0.tgz", - "integrity": "sha512-jvT3G+9lopkeB0ARmDPszyfaOnvnIF+30QCjZxyt7E6fynI1T9mOKgYDNb9bXX17M7PXMZaX3j/26wqakjp1tw==", + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", "dev": true, - "dependencies": { - "prettier-linter-helpers": "^1.0.0" - }, + "license": "MIT", "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "prettier": ">=2.0.0", - "stylelint": ">=14.0.0" + "node": ">=0.10.0" } }, - "node_modules/stylelint/node_modules/balanced-match": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", - "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", - "dev": true - }, - "node_modules/stylelint/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==", + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", "dev": true, + "license": "MIT", "engines": { - "node": ">=8" + "node": ">=0.10.0" } }, - "node_modules/sumchecker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", - "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", - "optional": true, + "node_modules/require-in-the-middle": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/require-in-the-middle/-/require-in-the-middle-5.2.0.tgz", + "integrity": "sha512-efCx3b+0Z69/LGJmm9Yvi4cqEdxnoGnxYxGxBghkkTTFeXRtTCmmhO0AnAfHz59k957uTSuy8WaHqOs8wbYUWg==", + "license": "MIT", "dependencies": { - "debug": "^4.1.0" + "debug": "^4.1.1", + "module-details-from-path": "^1.0.3", + "resolve": "^1.22.1" }, "engines": { - "node": ">= 8.0" + "node": ">=6" } }, - "node_modules/suncalc": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/suncalc/-/suncalc-1.9.0.tgz", - "integrity": "sha512-vMJ8Byp1uIPoj+wb9c1AdK4jpkSKVAywgHX0lqY7zt6+EWRRC3Z+0Ucfjy/0yxTVO1hwwchZe4uoFNqrIC24+A==", - "dev": true + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", + "dev": true, + "license": "MIT" }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0" + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" }, - "engines": { - "node": ">=8" + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "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==", + "license": "MIT", + "optional": true + }, + "node_modules/resolve-cwd": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", + "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", "dev": true, + "license": "MIT", "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" + "resolve-from": "^5.0.0" }, "engines": { "node": ">=8" } }, - "node_modules/supports-preserve-symlinks-flag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", - "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "node_modules/resolve-cwd/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, + "license": "MIT", "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" + "node": ">=8" } }, - "node_modules/svg-tags": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", - "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", - "dev": true - }, - "node_modules/symbol-tree": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", - "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true + "node_modules/resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "license": "MIT", + "engines": { + "node": ">=4" + } }, - "node_modules/table": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", + "node_modules/resolve.exports": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.2.tgz", + "integrity": "sha512-X2UW6Nw3n/aMgDVy+0rSqgHlv39WZAlZrXCdnbyEiKm17DSqHX4MmQMaST3FbeWR5FTuRcUwYAziZajji0Y7mg==", "dev": true, - "dependencies": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, + "license": "MIT", "engines": { - "node": ">=10.0.0" + "node": ">=10" } }, - "node_modules/table/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "license": "MIT", + "optional": true, "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" + "lowercase-keys": "^2.0.0" }, "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/table/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, - "node_modules/test-exclude": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", - "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", + "node_modules/restore-cursor": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", "dev": true, + "license": "MIT", "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" - }, - "node_modules/tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "node_modules/to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==", - "dev": true, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "license": "MIT", "engines": { - "node": ">=4" + "iojs": ">=1.0.0", + "node": ">=0.10.0" } }, - "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/rfdc": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz", + "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==", + "dev": true, + "license": "MIT" + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "deprecated": "Rimraf versions prior to v4 are no longer supported", + "license": "ISC", + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "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, + "node_modules/roarr": { + "version": "2.15.4", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", + "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", + "license": "BSD-3-Clause", + "optional": true, "dependencies": { - "is-number": "^7.0.0" + "boolean": "^3.0.1", + "detect-node": "^2.0.4", + "globalthis": "^1.0.1", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0", + "sprintf-js": "^1.1.2" }, "engines": { "node": ">=8.0" } }, - "node_modules/toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "engines": { - "node": ">=0.6" + "node_modules/rrule": { + "version": "2.8.1", + "resolved": "https://registry.npmjs.org/rrule/-/rrule-2.8.1.tgz", + "integrity": "sha512-hM3dHSBMeaJ0Ktp7W38BJZ7O1zOgaFEsn41PDk+yHoEtfLV+PoJt9E9xAlZiWgf/iqEqionN0ebHFZIDAp+iGw==", + "license": "BSD-3-Clause", + "dependencies": { + "tslib": "^2.4.0" } }, - "node_modules/tough-cookie": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", - "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==", + "node_modules/rrule/node_modules/tslib": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.3.tgz", + "integrity": "sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==", + "license": "0BSD" + }, + "node_modules/rrweb-cssom": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rrweb-cssom/-/rrweb-cssom-0.7.1.tgz", + "integrity": "sha512-TrEMa7JGdVm0UThDJSx7ddw5nVm3UJS9o9CCIZ72B1vSyEZoziDqBYP3XIoi/12lKrJR8rE3jeFHMok2F/Mnsg==", "dev": true, - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.2.0", - "url-parse": "^1.5.3" - }, - "engines": { - "node": ">=6" - } + "license": "MIT" }, - "node_modules/tough-cookie/node_modules/universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" + "node_modules/run-parallel": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", + "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT", + "dependencies": { + "queue-microtask": "^1.2.2" } }, - "node_modules/tr46": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", - "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", - "dev": true, + "node_modules/run-series": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/run-series/-/run-series-1.1.9.tgz", + "integrity": "sha512-Arc4hUN896vjkqCYrUXquBFtRZdv1PfLbTYP71efP6butxyQ0kWpiNJyAgsxscmQg1cqvHY32/UCBzXedTpU2g==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-array-concat": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.2.tgz", + "integrity": "sha512-vj6RsCsWBCf19jIeHEfkRMw8DPiBb+DMXklQ/1SGDHOMlHdPUkZXFQ2YdplS23zESTijAcurb1aSgJA3AgMu1Q==", + "license": "MIT", "dependencies": { - "punycode": "^2.1.1" + "call-bind": "^1.0.7", + "get-intrinsic": "^1.2.4", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" }, "engines": { - "node": ">=12" + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/trim-newlines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", - "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", - "dev": true, + "node_modules/safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "license": "MIT" + }, + "node_modules/safe-regex-test": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.3.tgz", + "integrity": "sha512-CdASjNJPvRa7roO6Ra/gLYBTzYzzPyyBXxIMdGW3USQLyjWEls2RgW5UBTXaQVp+OrpeCK3bLem8smtmheoRuw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.6", + "es-errors": "^1.3.0", + "is-regex": "^1.1.4" + }, "engines": { - "node": ">=8" + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "license": "MIT" + }, + "node_modules/sax": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz", + "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==", + "license": "ISC" }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "node_modules/saxes": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", + "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", "dev": true, + "license": "ISC", "dependencies": { - "tslib": "^1.8.1" + "xmlchars": "^2.2.0" }, "engines": { - "node": ">= 6" + "node": ">=v12.22.7" + } + }, + "node_modules/selderee": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/selderee/-/selderee-0.11.0.tgz", + "integrity": "sha512-5TF+l7p4+OsnP8BCCvSyZiSPc4x4//p5uPwK8TCnVPJYRmU2aYKMpOXvw8zM5a5JvuuCGN1jmsMwuU2W02ukfA==", + "license": "MIT", + "dependencies": { + "parseley": "^0.12.0" }, - "peerDependencies": { - "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" + "funding": { + "url": "https://ko-fi.com/killymxi" } }, - "node_modules/tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", - "optional": true, + "node_modules/semver": { + "version": "7.6.2", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.2.tgz", + "integrity": "sha512-FNAIBWCx9qcRhoHcgcJ0gvU7SN1lYU2ZXuSfl04bSC5OpvDHFyJCjdNHomPXxjQlCBU67YW64PzY7/VIEH7F2w==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, "engines": { - "node": ">=0.6.11 <=0.7.0 || >=0.7.3" + "node": ">=10" } }, - "node_modules/type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "node_modules/semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", + "license": "MIT", + "optional": true + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "license": "MIT", "dependencies": { - "prelude-ls": "^1.2.1" + "debug": "2.6.9", + "depd": "2.0.0", + "destroy": "1.2.0", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "2.0.0", + "mime": "1.6.0", + "ms": "2.1.3", + "on-finished": "2.4.1", + "range-parser": "~1.2.1", + "statuses": "2.0.1" }, "engines": { "node": ">= 0.8.0" } }, - "node_modules/type-detect": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", - "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true, + "node_modules/send/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "license": "MIT", + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/send/node_modules/debug/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "license": "MIT" + }, + "node_modules/send/node_modules/ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "license": "MIT" + }, + "node_modules/serialize-error": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", + "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", + "license": "MIT", + "optional": true, + "dependencies": { + "type-fest": "^0.13.1" + }, "engines": { - "node": ">=4" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "node_modules/serialize-error/node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "license": "(MIT OR CC0-1.0)", + "optional": true, "engines": { "node": ">=10" }, @@ -7750,6495 +10362,1998 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "node_modules/serve-static": { + "version": "1.15.0", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", + "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", + "license": "MIT", "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" }, "engines": { - "node": ">= 0.6" + "node": ">= 0.8.0" } }, - "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/set-function-length": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", + "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + } }, - "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==", - "dev": true, - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" + "node_modules/set-function-name": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.2.tgz", + "integrity": "sha512-7PGFlmtwsEADb0WYyvCMa1t+yke6daIG4Wirafur5kcf+MhUnPms1UeR0CKQdTZD81yESwMHbtn+TR+dMviakQ==", + "license": "MIT", + "dependencies": { + "define-data-property": "^1.1.4", + "es-errors": "^1.3.0", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.2" }, "engines": { - "node": ">=4.2.0" + "node": ">= 0.4" } }, - "node_modules/universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "optional": true, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "license": "ISC" + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "license": "MIT", + "dependencies": { + "shebang-regex": "^3.0.0" + }, "engines": { - "node": ">= 4.0.0" + "node": ">=8" } }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "license": "MIT", "engines": { - "node": ">= 0.8" + "node": ">=8" } }, - "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==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], + "node_modules/shimmer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/shimmer/-/shimmer-1.2.1.tgz", + "integrity": "sha512-sQTKC1Re/rM6XyFM6fIAGHRPVGvyXfgzIDvzoq608vM+jeyVD0Tu1E6Np0Kc2zAIFWIj963V2800iF/9LPieQw==", + "license": "BSD-2-Clause" + }, + "node_modules/side-channel": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", + "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", + "license": "MIT", "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "get-intrinsic": "^1.2.4", + "object-inspect": "^1.13.1" }, - "bin": { - "browserslist-lint": "cli.js" + "engines": { + "node": ">= 0.4" }, - "peerDependencies": { - "browserslist": ">= 4.21.0" + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "node_modules/signal-exit": { + "version": "3.0.7", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", + "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", + "license": "ISC" + }, + "node_modules/sinon": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/sinon/-/sinon-18.0.0.tgz", + "integrity": "sha512-+dXDXzD1sBO6HlmZDd7mXZCR/y5ECiEiGCBSGuFD/kZ0bDTofPYc6JaeGmPSF+1j1MejGUWkORbYOLDyvqCWpA==", + "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "punycode": "^2.1.0" + "@sinonjs/commons": "^3.0.1", + "@sinonjs/fake-timers": "^11.2.2", + "@sinonjs/samsam": "^8.0.0", + "diff": "^5.2.0", + "nise": "^6.0.0", + "supports-color": "^7" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/sinon" } }, - "node_modules/url-parse": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", - "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", + "node_modules/sinon/node_modules/@sinonjs/fake-timers": { + "version": "11.2.2", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-11.2.2.tgz", + "integrity": "sha512-G2piCSxQ7oWOxwGSAyFHfPIsyeJGXYtc6mFbnFA+kRXkiEnTl8c/8jul2S329iFBnDI9HGoeWWAZvuvOkZccgw==", "dev": true, + "license": "BSD-3-Clause", "dependencies": { - "querystringify": "^2.1.1", - "requires-port": "^1.0.0" + "@sinonjs/commons": "^3.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" - }, + "node_modules/sinon/node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "dev": true, + "license": "BSD-3-Clause", "engines": { - "node": ">=4" + "node": ">=0.3.1" } }, - "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 + "node_modules/sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true, + "license": "MIT" }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "node_modules/slash": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", + "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", + "dev": true, + "license": "MIT", "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "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" + "node": ">=8" } }, - "node_modules/v8-compile-cache": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true - }, - "node_modules/v8-to-istanbul": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", - "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", + "node_modules/slice-ansi": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-5.0.0.tgz", + "integrity": "sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==", "dev": true, + "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.12", - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0" + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" }, "engines": { - "node": ">=10.12.0" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" } }, - "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", - "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "node_modules/slice-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", "dev": true, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" } }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "node_modules/smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "license": "MIT", "engines": { - "node": ">= 0.8" + "node": ">= 6.0.0", + "npm": ">= 3.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==", - "dev": true, + "node_modules/socket.io": { + "version": "4.7.5", + "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.7.5.tgz", + "integrity": "sha512-DmeAkF6cwM9jSfmp6Dr/5/mfMwb5Z5qRrSXLpo3Fq5SqyU8CMF15jIN4ZhfSwu35ksM1qmHZDQ/DK5XTccSTvA==", + "license": "MIT", "dependencies": { - "xml-name-validator": "^4.0.0" + "accepts": "~1.3.4", + "base64id": "~2.0.0", + "cors": "~2.8.5", + "debug": "~4.3.2", + "engine.io": "~6.5.2", + "socket.io-adapter": "~2.5.2", + "socket.io-parser": "~4.2.4" }, "engines": { - "node": ">=12" + "node": ">=10.2.0" } }, - "node_modules/walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, + "node_modules/socket.io-adapter": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.5.5.tgz", + "integrity": "sha512-eLDQas5dzPgOWCk9GuuJC2lBqItuhKI4uxGgo9aIV7MYbk2h9Q6uULEh8WBzThoI7l+qU9Ast9fVUmkqPP9wYg==", + "license": "MIT", "dependencies": { - "makeerror": "1.0.12" + "debug": "~4.3.4", + "ws": "~8.17.1" } }, - "node_modules/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "dev": true, + "node_modules/socket.io-parser": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.4.tgz", + "integrity": "sha512-/GbIKmo8ioc+NIWIhwdecY0ge+qVBSMdgxGygevmdHj24bsfgtCmcUUcQ5ZzcylGFHsN3k4HB4Cgkl96KVnuew==", + "license": "MIT", + "dependencies": { + "@socket.io/component-emitter": "~3.1.0", + "debug": "~4.3.1" + }, "engines": { - "node": ">=12" + "node": ">=10.0.0" } }, - "node_modules/whatwg-encoding": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", - "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", - "dev": true, + "node_modules/socks": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz", + "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==", + "license": "MIT", "dependencies": { - "iconv-lite": "0.6.3" + "ip-address": "^9.0.5", + "smart-buffer": "^4.2.0" }, "engines": { - "node": ">=12" + "node": ">= 10.0.0", + "npm": ">= 3.0.0" } }, - "node_modules/whatwg-mimetype": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", - "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", - "dev": true, + "node_modules/socks-proxy-agent": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.3.tgz", + "integrity": "sha512-VNegTZKhuGq5vSD6XNKlbqWhyt/40CgoEw8XxD6dhnm8Jq9IEa3nIa4HwnM8XOqU0CdB0BwWVXusqiFXfHB3+A==", + "license": "MIT", + "dependencies": { + "agent-base": "^7.1.1", + "debug": "^4.3.4", + "socks": "^2.7.1" + }, "engines": { - "node": ">=12" + "node": ">= 14" } }, - "node_modules/whatwg-url": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", - "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "node_modules/sort-object-keys": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/sort-object-keys/-/sort-object-keys-1.1.3.tgz", + "integrity": "sha512-855pvK+VkU7PaKYPc+Jjnmt4EzejQHyhhF33q31qG8x7maDzkeFhAAThdCYay11CISO+qAMwjOBP+fPZe0IPyg==", + "dev": true, + "license": "MIT" + }, + "node_modules/sort-package-json": { + "version": "1.57.0", + "resolved": "https://registry.npmjs.org/sort-package-json/-/sort-package-json-1.57.0.tgz", + "integrity": "sha512-FYsjYn2dHTRb41wqnv+uEqCUvBpK3jZcTp9rbz2qDTmel7Pmdtf+i2rLaaPMRZeSVM60V3Se31GyWFpmKs4Q5Q==", "dev": true, + "license": "MIT", "dependencies": { - "tr46": "^3.0.0", - "webidl-conversions": "^7.0.0" + "detect-indent": "^6.0.0", + "detect-newline": "3.1.0", + "git-hooks-list": "1.0.3", + "globby": "10.0.0", + "is-plain-obj": "2.1.0", + "sort-object-keys": "^1.1.3" }, - "engines": { - "node": ">=12" + "bin": { + "sort-package-json": "cli.js" } }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "node_modules/sort-package-json/node_modules/globby": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-10.0.0.tgz", + "integrity": "sha512-3LifW9M4joGZasyYPz2A1U74zbC/45fvpXUvO/9KbSa+VV0aGZarWkfdgKyR9sExNP0t0x0ss/UMJpNpcaTspw==", + "dev": true, + "license": "MIT", "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" + "@types/glob": "^7.1.1", + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.0.3", + "glob": "^7.1.3", + "ignore": "^5.1.1", + "merge2": "^1.2.3", + "slash": "^3.0.0" }, "engines": { - "node": ">= 8" + "node": ">=8" } }, - "node_modules/word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==", + "node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" } }, - "node_modules/wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "node_modules/source-map-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz", + "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==", "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, + "license": "BSD-3-Clause", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + "node": ">=0.10.0" } }, - "node_modules/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" - }, - "node_modules/write-file-atomic": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", - "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", + "node_modules/source-map-support": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", + "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", "dev": true, + "license": "MIT", "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" } }, - "node_modules/ws": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.9.0.tgz", - "integrity": "sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==", + "node_modules/spdx-correct": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.2.0.tgz", + "integrity": "sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==", "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } + "license": "Apache-2.0", + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" } }, - "node_modules/xml-name-validator": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", - "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", + "node_modules/spdx-correct/node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } }, - "node_modules/y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "node_modules/spdx-exceptions": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.5.0.tgz", + "integrity": "sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==", "dev": true, - "engines": { - "node": ">=10" - } + "license": "CC-BY-3.0" }, - "node_modules/yallist": { + "node_modules/spdx-expression-parse": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "devOptional": true - }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-4.0.0.tgz", + "integrity": "sha512-Clya5JIij/7C6bRR22+tnGXbc4VKlibKSVj2iHvVeX5iMW7s1SIQlqu699JkODJJIhh/pUu8L0/VLh8xflD+LQ==", "dev": true, - "engines": { - "node": ">= 6" + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" } }, - "node_modules/yargs": { - "version": "17.6.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.0.tgz", - "integrity": "sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==", + "node_modules/spdx-license-ids": { + "version": "3.0.18", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.18.tgz", + "integrity": "sha512-xxRs31BqRYHwiMzudOrpSiHtZ8i/GeionCBDSilhYRj+9gIcI8wCZTlXZKu9vZIVqViP3dcp9qE5G6AlIaD+TQ==", + "dev": true, + "license": "CC0-1.0" + }, + "node_modules/sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "license": "BSD-3-Clause" + }, + "node_modules/stack-utils": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/stack-utils/-/stack-utils-2.0.6.tgz", + "integrity": "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==", "dev": true, + "license": "MIT", "dependencies": { - "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" + "escape-string-regexp": "^2.0.0" }, "engines": { - "node": ">=12" + "node": ">=10" } }, - "node_modules/yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", + "node_modules/stack-utils/node_modules/escape-string-regexp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", + "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, + "license": "MIT", "engines": { - "node": ">=10" + "node": ">=8" } }, - "node_modules/yargs/node_modules/yargs-parser": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/string-argv": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz", + "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==", "dev": true, + "license": "MIT", "engines": { - "node": ">=12" + "node": ">=0.6.19" } }, - "node_modules/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "optional": true, + "node_modules/string-length": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", + "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "dev": true, + "license": "MIT", "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" } }, - "node_modules/yocto-queue": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "node_modules/string-width": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.1.0.tgz", + "integrity": "sha512-SEIJCWiX7Kg4c129n48aDRwLbFb2LJmXXFrWBG4NGaRtMQ3myKPKbwrD1BKqQn74oCoNMBVrfDEr5M9YxCsrkw==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^10.3.0", + "get-east-asian-width": "^1.0.0", + "strip-ansi": "^7.1.0" + }, "engines": { - "node": ">=10" + "node": ">=18" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" } - } - }, - "dependencies": { - "@ampproject/remapping": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz", - "integrity": "sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==", + }, + "node_modules/string-width/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.1.0", - "@jridgewell/trace-mapping": "^0.3.9" + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "@babel/code-frame": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", - "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "node_modules/string-width/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, - "requires": { - "@babel/highlight": "^7.18.6" + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "@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==", - "dev": true - }, - "@babel/core": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.19.3.tgz", - "integrity": "sha512-WneDJxdsjEvyKtXKsaBGbDeiyOjR5vYq4HcShxnIbG0qixpoHjI3MqeZM9NDvsojNCEBItQE4juOo/bU6e72gQ==", - "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", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" + "node_modules/string.prototype.matchall": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.11.tgz", + "integrity": "sha512-NUdh0aDavY2og7IbBPenWqR9exH+E26Sv8e0/eTe1tltDGZL+GtBkDAnnyBtmekfK6/Dq3MkcGtzXFEd1LQrtg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.2", + "es-errors": "^1.3.0", + "es-object-atoms": "^1.0.0", + "get-intrinsic": "^1.2.4", + "gopd": "^1.0.1", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.7", + "regexp.prototype.flags": "^1.5.2", + "set-function-name": "^2.0.2", + "side-channel": "^1.0.6" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "@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==", - "dev": true, - "requires": { - "@babel/types": "^7.19.3", - "@jridgewell/gen-mapping": "^0.3.2", - "jsesc": "^2.5.1" - }, + "node_modules/string.prototype.trim": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.9.tgz", + "integrity": "sha512-klHuCNxiMZ8MlsOihJhJEBJAiMVqU3Z2nEXWfWnIqjN0gEFS9J9+IxKozWWtQGcgoa1WUZzLjKPTr4ZHNFTFxw==", + "license": "MIT", "dependencies": { - "@jridgewell/gen-mapping": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz", - "integrity": "sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - } + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-abstract": "^1.23.0", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "@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==", - "dev": true, - "requires": { - "@babel/compat-data": "^7.19.3", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" + "node_modules/string.prototype.trimend": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.8.tgz", + "integrity": "sha512-p73uL5VCHCO2BZZ6krwwQE3kCzM7NKmis8S//xEC6fQonchbum4eP6kR4DLEjQFO3Wnj3Fuo8NM0kOSjVdHjZQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" } }, - "@babel/helper-environment-visitor": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz", - "integrity": "sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==", - "dev": true + "node_modules/string.prototype.trimstart": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.8.tgz", + "integrity": "sha512-UXSH262CSZY1tfu3G3Secr6uGLCFVPMhIqHjlgCUtCCcgihYc/xKs9djMTMUOb2j1mVSeU8EU6NWc/iQKU6Gfg==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "define-properties": "^1.2.1", + "es-object-atoms": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "@babel/helper-function-name": { - "version": "7.19.0", - "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.19.0.tgz", - "integrity": "sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==", - "dev": true, - "requires": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" + "node_modules/strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "@babel/helper-hoist-variables": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz", - "integrity": "sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==", + "node_modules/strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", "dev": true, - "requires": { - "@babel/types": "^7.18.6" + "license": "MIT", + "engines": { + "node": ">=8" } }, - "@babel/helper-module-imports": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz", - "integrity": "sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==", + "node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true, - "requires": { - "@babel/types": "^7.18.6" + "license": "MIT", + "engines": { + "node": ">=6" } }, - "@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==", + "node_modules/strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "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-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" + "license": "MIT", + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" } }, - "@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==", - "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==", - "dev": true, - "requires": { - "@babel/types": "^7.18.6" + "node_modules/strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "license": "MIT", + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, - "@babel/helper-split-export-declaration": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz", - "integrity": "sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==", + "node_modules/stylelint": { + "version": "16.6.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-16.6.1.tgz", + "integrity": "sha512-yNgz2PqWLkhH2hw6X9AweV9YvoafbAD5ZsFdKN9BvSDVwGvPh+AUIrn7lYwy1S7IHmtFin75LLfX1m0D2tHu8Q==", "dev": true, - "requires": { - "@babel/types": "^7.18.6" + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + }, + { + "type": "github", + "url": "https://github.com/sponsors/stylelint" + } + ], + "license": "MIT", + "dependencies": { + "@csstools/css-parser-algorithms": "^2.6.3", + "@csstools/css-tokenizer": "^2.3.1", + "@csstools/media-query-list-parser": "^2.1.11", + "@csstools/selector-specificity": "^3.1.1", + "@dual-bundle/import-meta-resolve": "^4.1.0", + "balanced-match": "^2.0.0", + "colord": "^2.9.3", + "cosmiconfig": "^9.0.0", + "css-functions-list": "^3.2.2", + "css-tree": "^2.3.1", + "debug": "^4.3.4", + "fast-glob": "^3.3.2", + "fastest-levenshtein": "^1.0.16", + "file-entry-cache": "^9.0.0", + "global-modules": "^2.0.0", + "globby": "^11.1.0", + "globjoin": "^0.1.4", + "html-tags": "^3.3.1", + "ignore": "^5.3.1", + "imurmurhash": "^0.1.4", + "is-plain-object": "^5.0.0", + "known-css-properties": "^0.31.0", + "mathml-tag-names": "^2.1.3", + "meow": "^13.2.0", + "micromatch": "^4.0.7", + "normalize-path": "^3.0.0", + "picocolors": "^1.0.1", + "postcss": "^8.4.38", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-safe-parser": "^7.0.0", + "postcss-selector-parser": "^6.1.0", + "postcss-value-parser": "^4.2.0", + "resolve-from": "^5.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^7.1.0", + "supports-hyperlinks": "^3.0.0", + "svg-tags": "^1.0.0", + "table": "^6.8.2", + "write-file-atomic": "^5.0.1" + }, + "bin": { + "stylelint": "bin/stylelint.mjs" + }, + "engines": { + "node": ">=18.12.0" } }, - "@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==", - "dev": true - }, - "@babel/helper-validator-identifier": { - "version": "7.19.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", - "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", - "dev": true - }, - "@babel/helper-validator-option": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.18.6.tgz", - "integrity": "sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==", - "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==", + "node_modules/stylelint-config-recommended": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-14.0.0.tgz", + "integrity": "sha512-jSkx290CglS8StmrLp2TxAppIajzIBZKYm3IxT89Kg6fGlxbPiTiyH9PS5YUuVAFwaJLl1ikiXX0QWjI0jmgZQ==", "dev": true, - "requires": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.19.0", - "@babel/types": "^7.19.0" + "license": "MIT", + "engines": { + "node": ">=18.12.0" + }, + "peerDependencies": { + "stylelint": "^16.0.0" } }, - "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "node_modules/stylelint-config-standard": { + "version": "36.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-36.0.0.tgz", + "integrity": "sha512-3Kjyq4d62bYFp/Aq8PMKDwlgUyPU4nacXsjDLWJdNPRUgpuxALu1KnlAHIj36cdtxViVhXexZij65yM0uNIHug==", "dev": true, - "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, + "license": "MIT", "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "dev": true - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", - "dev": true - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", - "dev": true - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@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==", - "dev": true - }, - "@babel/plugin-syntax-async-generators": { - "version": "7.8.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", - "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-bigint": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-bigint/-/plugin-syntax-bigint-7.8.3.tgz", - "integrity": "sha512-wnTnFlG+YxQm3vDxpGE57Pj0srRU4sHE/mDkt1qv2YJJSeUAec2ma4WLUnUPeKjyrfntVwe/N6dCXpU+zL3Npg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-class-properties": { - "version": "7.12.13", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.12.13.tgz", - "integrity": "sha512-fm4idjKla0YahUNgFNLCB0qySdsoPiZP3iQE3rky0mBUtMZ23yDJ9SJdg6dXTSDnulOVqiF3Hgr9nbXvXTQZYA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.12.13" - } - }, - "@babel/plugin-syntax-import-meta": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz", - "integrity": "sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-json-strings": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", - "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-jsx": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.18.6.tgz", - "integrity": "sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.18.6" - } - }, - "@babel/plugin-syntax-logical-assignment-operators": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz", - "integrity": "sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-nullish-coalescing-operator": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", - "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-numeric-separator": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz", - "integrity": "sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.10.4" - } - }, - "@babel/plugin-syntax-object-rest-spread": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", - "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-catch-binding": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", - "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-optional-chaining": { - "version": "7.8.3", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", - "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.8.0" - } - }, - "@babel/plugin-syntax-top-level-await": { - "version": "7.14.5", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.14.5.tgz", - "integrity": "sha512-hx++upLv5U1rgYfwe1xBQUhRmU41NEvpUvrp8jkrSCdvGSnM5/qdRMtylJ6PG5OFkBaHkbTAKTnd3/YyESRHFw==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.14.5" - } - }, - "@babel/plugin-syntax-typescript": { - "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.19.0" - } - }, - "@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" - } - }, - "@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==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.19.3", - "@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", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "dependencies": { - "globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "dev": true - } - } - }, - "@babel/types": { - "version": "7.19.3", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.19.3.tgz", - "integrity": "sha512-hGCaQzIY22DJlDh9CH7NOxgKkFjBk0Cw9xDO1Xmh2151ti7wiGfQ3LauXzL4HP1fmFlTX6XjpRETTpUcv7wQLw==", - "dev": true, - "requires": { - "@babel/helper-string-parser": "^7.18.10", - "@babel/helper-validator-identifier": "^7.19.1", - "to-fast-properties": "^2.0.0" - } - }, - "@bcoe/v8-coverage": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz", - "integrity": "sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==", - "dev": true - }, - "@csstools/selector-specificity": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.2.tgz", - "integrity": "sha512-IkpVW/ehM1hWKln4fCA3NzJU8KwD+kIOvPZA4cqxoJHtE21CCzjyp+Kxbu0i5I4tBNOlXPL9mjwnWlL0VEG4Fg==", - "dev": true, - "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==", - "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", - "progress": "^2.0.3", - "semver": "^6.2.0", - "sumchecker": "^3.0.1" - } - }, - "@es-joy/jsdoccomment": { - "version": "0.33.4", - "resolved": "https://registry.npmjs.org/@es-joy/jsdoccomment/-/jsdoccomment-0.33.4.tgz", - "integrity": "sha512-02XyYuvR/Gn+3BT6idHVNQ4SSQlA1X1FeEfeKm2ypv8ANB6Lt9KRFZ2S7y5xjwR+EPQ/Rzb0XFaD+xKyqe4ALw==", - "dev": true, - "requires": { - "comment-parser": "1.3.1", - "esquery": "^1.4.0", - "jsdoc-type-pratt-parser": "~3.1.0" - } - }, - "@eslint/eslintrc": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.3.3.tgz", - "integrity": "sha512-uj3pT6Mg+3t39fvLrj8iuCIJ38zKO9FpGtJ4BBJebJhEwjoT+KLVNCcHT5QC9NGRIEi7fZ0ZR8YRb884auB4Lg==", - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.15.0", - "ignore": "^5.2.0", - "import-fresh": "^3.2.1", - "js-yaml": "^4.1.0", - "minimatch": "^3.1.2", - "strip-json-comments": "^3.1.1" - } - }, - "@humanwhocodes/config-array": { - "version": "0.11.7", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.7.tgz", - "integrity": "sha512-kBbPWzN8oVMLb0hOUYXhmxggL/1cJE6ydvjDIGi9EnAGUyA7cLVKQg+d/Dsm+KZwx2czGHrCmMVLiyg8s5JPKw==", - "requires": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - } - }, - "@humanwhocodes/module-importer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", - "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==" - }, - "@humanwhocodes/object-schema": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz", - "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==" - }, - "@istanbuljs/load-nyc-config": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", - "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "find-up": "^4.1.0", - "get-package-type": "^0.1.0", - "js-yaml": "^3.13.1", - "resolve-from": "^5.0.0" - }, - "dependencies": { - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - } - }, - "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" - } - }, - "js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.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 - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", - "dev": true - } - } - }, - "@istanbuljs/schema": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", - "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", - "dev": true - }, - "@jest/console": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-29.2.1.tgz", - "integrity": "sha512-MF8Adcw+WPLZGBiNxn76DOuczG3BhODTcMlDCA4+cFi41OkaY/lyI0XUUhi73F88Y+7IHoGmD80pN5CtxQUdSw==", - "dev": true, - "requires": { - "@jest/types": "^29.2.1", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^29.2.1", - "jest-util": "^29.2.1", - "slash": "^3.0.0" - } - }, - "@jest/core": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-29.2.2.tgz", - "integrity": "sha512-susVl8o2KYLcZhhkvSB+b7xX575CX3TmSvxfeDjpRko7KmT89rHkXj6XkDkNpSeFMBzIENw5qIchO9HC9Sem+A==", - "dev": true, - "requires": { - "@jest/console": "^29.2.1", - "@jest/reporters": "^29.2.2", - "@jest/test-result": "^29.2.1", - "@jest/transform": "^29.2.2", - "@jest/types": "^29.2.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.2.0", - "jest-config": "^29.2.2", - "jest-haste-map": "^29.2.1", - "jest-message-util": "^29.2.1", - "jest-regex-util": "^29.2.0", - "jest-resolve": "^29.2.2", - "jest-resolve-dependencies": "^29.2.2", - "jest-runner": "^29.2.2", - "jest-runtime": "^29.2.2", - "jest-snapshot": "^29.2.2", - "jest-util": "^29.2.1", - "jest-validate": "^29.2.2", - "jest-watcher": "^29.2.2", - "micromatch": "^4.0.4", - "pretty-format": "^29.2.1", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "@jest/environment": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.2.2.tgz", - "integrity": "sha512-OWn+Vhu0I1yxuGBJEFFekMYc8aGBGrY4rt47SOh/IFaI+D7ZHCk7pKRiSoZ2/Ml7b0Ony3ydmEHRx/tEOC7H1A==", - "dev": true, - "requires": { - "@jest/fake-timers": "^29.2.2", - "@jest/types": "^29.2.1", - "@types/node": "*", - "jest-mock": "^29.2.2" - } - }, - "@jest/expect": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/@jest/expect/-/expect-29.2.2.tgz", - "integrity": "sha512-zwblIZnrIVt8z/SiEeJ7Q9wKKuB+/GS4yZe9zw7gMqfGf4C5hBLGrVyxu1SzDbVSqyMSlprKl3WL1r80cBNkgg==", - "dev": true, - "requires": { - "expect": "^29.2.2", - "jest-snapshot": "^29.2.2" - } - }, - "@jest/expect-utils": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/@jest/expect-utils/-/expect-utils-29.2.2.tgz", - "integrity": "sha512-vwnVmrVhTmGgQzyvcpze08br91OL61t9O0lJMDyb6Y/D8EKQ9V7rGUb/p7PDt0GPzK0zFYqXWFo4EO2legXmkg==", - "dev": true, - "requires": { - "jest-get-type": "^29.2.0" - } - }, - "@jest/fake-timers": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-29.2.2.tgz", - "integrity": "sha512-nqaW3y2aSyZDl7zQ7t1XogsxeavNpH6kkdq+EpXncIDvAkjvFD7hmhcIs1nWloengEWUoWqkqSA6MSbf9w6DgA==", - "dev": true, - "requires": { - "@jest/types": "^29.2.1", - "@sinonjs/fake-timers": "^9.1.2", - "@types/node": "*", - "jest-message-util": "^29.2.1", - "jest-mock": "^29.2.2", - "jest-util": "^29.2.1" - } - }, - "@jest/globals": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-29.2.2.tgz", - "integrity": "sha512-/nt+5YMh65kYcfBhj38B3Hm0Trk4IsuMXNDGKE/swp36yydBWfz3OXkLqkSvoAtPW8IJMSJDFCbTM2oj5SNprw==", - "dev": true, - "requires": { - "@jest/environment": "^29.2.2", - "@jest/expect": "^29.2.2", - "@jest/types": "^29.2.1", - "jest-mock": "^29.2.2" - } - }, - "@jest/reporters": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-29.2.2.tgz", - "integrity": "sha512-AzjL2rl2zJC0njIzcooBvjA4sJjvdoq98sDuuNs4aNugtLPSQ+91nysGKRF0uY1to5k0MdGMdOBggUsPqvBcpA==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^29.2.1", - "@jest/test-result": "^29.2.1", - "@jest/transform": "^29.2.2", - "@jest/types": "^29.2.1", - "@jridgewell/trace-mapping": "^0.3.15", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "istanbul-lib-coverage": "^3.0.0", - "istanbul-lib-instrument": "^5.1.0", - "istanbul-lib-report": "^3.0.0", - "istanbul-lib-source-maps": "^4.0.0", - "istanbul-reports": "^3.1.3", - "jest-message-util": "^29.2.1", - "jest-util": "^29.2.1", - "jest-worker": "^29.2.1", - "slash": "^3.0.0", - "string-length": "^4.0.1", - "strip-ansi": "^6.0.0", - "v8-to-istanbul": "^9.0.1" - } - }, - "@jest/schemas": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.0.0.tgz", - "integrity": "sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==", - "dev": true, - "requires": { - "@sinclair/typebox": "^0.24.1" - } - }, - "@jest/source-map": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-29.2.0.tgz", - "integrity": "sha512-1NX9/7zzI0nqa6+kgpSdKPK+WU1p+SJk3TloWZf5MzPbxri9UEeXX5bWZAPCzbQcyuAzubcdUHA7hcNznmRqWQ==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.15", - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9" - } - }, - "@jest/test-result": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-29.2.1.tgz", - "integrity": "sha512-lS4+H+VkhbX6z64tZP7PAUwPqhwj3kbuEHcaLuaBuB+riyaX7oa1txe0tXgrFj5hRWvZKvqO7LZDlNWeJ7VTPA==", - "dev": true, - "requires": { - "@jest/console": "^29.2.1", - "@jest/types": "^29.2.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-29.2.2.tgz", - "integrity": "sha512-Cuc1znc1pl4v9REgmmLf0jBd3Y65UXJpioGYtMr/JNpQEIGEzkmHhy6W6DLbSsXeUA13TDzymPv0ZGZ9jH3eIw==", - "dev": true, - "requires": { - "@jest/test-result": "^29.2.1", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.2.1", - "slash": "^3.0.0" - } - }, - "@jest/transform": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-29.2.2.tgz", - "integrity": "sha512-aPe6rrletyuEIt2axxgdtxljmzH8O/nrov4byy6pDw9S8inIrTV+2PnjyP/oFHMSynzGxJ2s6OHowBNMXp/Jzg==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@jest/types": "^29.2.1", - "@jridgewell/trace-mapping": "^0.3.15", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.1.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.2.1", - "jest-regex-util": "^29.2.0", - "jest-util": "^29.2.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "write-file-atomic": "^4.0.1" - } - }, - "@jest/types": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-29.2.1.tgz", - "integrity": "sha512-O/QNDQODLnINEPAI0cl9U6zUIDXEWXt6IC1o2N2QENuos7hlGUIthlKyV4p6ki3TvXFX071blj8HUhgLGquPjw==", - "dev": true, - "requires": { - "@jest/schemas": "^29.0.0", - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^17.0.8", - "chalk": "^4.0.0" - } - }, - "@jridgewell/gen-mapping": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz", - "integrity": "sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==", - "dev": true, - "requires": { - "@jridgewell/set-array": "^1.0.0", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "@jridgewell/resolve-uri": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz", - "integrity": "sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==", - "dev": true - }, - "@jridgewell/set-array": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/set-array/-/set-array-1.1.2.tgz", - "integrity": "sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==", - "dev": true - }, - "@jridgewell/sourcemap-codec": { - "version": "1.4.14", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz", - "integrity": "sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==", - "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==", - "dev": true, - "requires": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "@nodelib/fs.scandir": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", - "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==", - "requires": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - } - }, - "@nodelib/fs.stat": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz", - "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==" - }, - "@nodelib/fs.walk": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz", - "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==", - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@sinclair/typebox": { - "version": "0.24.51", - "resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.24.51.tgz", - "integrity": "sha512-1P1OROm/rdubP5aFDSZQILU0vrLCJ4fvHt6EoqHEM+2D/G5MK3bIaymUKLit8Js9gbns5UyJnkP/TZROLw4tUA==", - "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==", - "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==", - "dev": true, - "requires": { - "type-detect": "4.0.8" - } - }, - "@sinonjs/fake-timers": { - "version": "9.1.2", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-9.1.2.tgz", - "integrity": "sha512-BPS4ynJW/o92PUR4wgriz2Ud5gpST5vz6GQfMixEDK0Z8ZCUv2M7SkBLykH56T++Xs+8ln9zTGbOvNGIe02/jw==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "@sinonjs/samsam": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/@sinonjs/samsam/-/samsam-6.1.1.tgz", - "integrity": "sha512-cZ7rKJTLiE7u7Wi/v9Hc2fs3Ucc3jrWeMgPHbbTCeVAB2S0wOBbYlkJVeNSL04i7fdhT8wIbDq1zhC/PXTD2SA==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.6.0", - "lodash.get": "^4.4.2", - "type-detect": "^4.0.8" - } - }, - "@sinonjs/text-encoding": { - "version": "0.7.2", - "resolved": "https://registry.npmjs.org/@sinonjs/text-encoding/-/text-encoding-0.7.2.tgz", - "integrity": "sha512-sXXKG+uL9IrKqViTtao2Ws6dy0znu9sOaP1di/jKGW1M6VssO8vlpXCQcpZ+jisQ1tTFAC5Jo/EOzFbggBagFQ==", - "dev": true - }, - "@socket.io/component-emitter": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@socket.io/component-emitter/-/component-emitter-3.1.0.tgz", - "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==", - "optional": true, - "requires": { - "defer-to-connect": "^1.0.1" - } - }, - "@tootallnate/once": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", - "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==", - "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==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "@types/babel__generator": { - "version": "7.6.4", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", - "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", - "dev": true, - "requires": { - "@babel/types": "^7.0.0" - } - }, - "@types/babel__template": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", - "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", - "dev": true, - "requires": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "@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==", - "dev": true, - "requires": { - "@babel/types": "^7.3.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==" - }, - "@types/graceful-fs": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/@types/graceful-fs/-/graceful-fs-4.1.5.tgz", - "integrity": "sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/istanbul-lib-coverage": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.4.tgz", - "integrity": "sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==", - "dev": true - }, - "@types/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "*" - } - }, - "@types/istanbul-reports": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.1.tgz", - "integrity": "sha512-c3mAZEuK0lvBp8tmuL74XRKn1+y2dcwOUpH7x4WrF6gk1GIgiluDRgMYQtw2OFcBvAJWlt6ASU3tSqxp0Uu0Aw==", - "dev": true, - "requires": { - "@types/istanbul-lib-report": "*" - } - }, - "@types/json-schema": { - "version": "7.0.11", - "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz", - "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", - "dev": true - }, - "@types/minimatch": { - "version": "3.0.5", - "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.5.tgz", - "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==", - "dev": true - }, - "@types/minimist": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz", - "integrity": "sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==", - "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==" - }, - "@types/normalize-package-data": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz", - "integrity": "sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==", - "dev": true - }, - "@types/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==", - "dev": true - }, - "@types/prettier": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.7.1.tgz", - "integrity": "sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==", - "dev": true - }, - "@types/stack-utils": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@types/stack-utils/-/stack-utils-2.0.1.tgz", - "integrity": "sha512-Hl219/BT5fLAaz6NDkSuhzasy49dwQS/DSdu4MdggFB8zcXv7vflBI3xp7FEmkmdDkBUI2bPUNeMttp2knYdxw==", - "dev": true - }, - "@types/yargs": { - "version": "17.0.13", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.13.tgz", - "integrity": "sha512-9sWaruZk2JGxIQU+IhI1fhPYRcQ0UuTNuKuCW9bR5fp7qi2Llf7WDzNa17Cy7TKnh3cdxDOiyTu6gaLS0eDatg==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - }, - "@types/yargs-parser": { - "version": "21.0.0", - "resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz", - "integrity": "sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA==", - "dev": true - }, - "@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==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.38.1", - "@typescript-eslint/visitor-keys": "5.38.1" - } - }, - "@typescript-eslint/types": { - "version": "5.38.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.38.1.tgz", - "integrity": "sha512-QTW1iHq1Tffp9lNfbfPm4WJabbvpyaehQ0SrvVK2yfV79SytD9XDVxqiPvdrv2LK7DGSFo91TB2FgWanbJAZXg==", - "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==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.38.1", - "@typescript-eslint/visitor-keys": "5.38.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "dependencies": { - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, - "@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==", - "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", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "dependencies": { - "eslint-scope": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", - "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^4.1.1" - } - }, - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "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==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.38.1", - "eslint-visitor-keys": "^3.3.0" - } - }, - "abab": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.6.tgz", - "integrity": "sha512-j2afSsaIENvHZN2B8GOpF566vZ5WVk5opAiMTvWgaQT8DkbOqsTfvNAvHoRGU2zzP8cPoqys+xHTRDWW8L+/BA==", - "dev": true - }, - "accepts": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", - "integrity": "sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==", - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "acorn": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.0.tgz", - "integrity": "sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==" - }, - "acorn-globals": { - "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": "^8.1.0", - "acorn-walk": "^8.0.2" - } - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "requires": {} - }, - "acorn-walk": { - "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": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", - "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", - "dev": true, - "requires": { - "debug": "4" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "requires": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ansi-escapes": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz", - "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==", - "dev": true, - "requires": { - "type-fest": "^0.21.3" - }, - "dependencies": { - "type-fest": { - "version": "0.21.3", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz", - "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==", - "dev": true - } - } - }, - "ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==" - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "requires": { - "color-convert": "^2.0.1" - } - }, - "anymatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", - "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", - "dev": true, - "requires": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - } - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "array-differ": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/array-differ/-/array-differ-3.0.0.tgz", - "integrity": "sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==", - "dev": true - }, - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==" - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "arrify": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz", - "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==", - "dev": true - }, - "astral-regex": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", - "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==" - }, - "axios": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.1.3.tgz", - "integrity": "sha512-00tXVRwKx/FZr/IDVFt4C+f9FYairX517WoGCL6dpOntqLkZofjhu43F/Xl44UOpqa+9sLFDrG/XAnFsUYgkDA==", - "requires": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "babel-jest": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-29.2.2.tgz", - "integrity": "sha512-kkq2QSDIuvpgfoac3WZ1OOcHsQQDU5xYk2Ql7tLdJ8BVAYbefEXal+NfS45Y5LVZA7cxC8KYcQMObpCt1J025w==", - "dev": true, - "requires": { - "@jest/transform": "^29.2.2", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^29.2.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - } - }, - "babel-plugin-istanbul": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-6.1.1.tgz", - "integrity": "sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.0.0", - "@istanbuljs/load-nyc-config": "^1.0.0", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-instrument": "^5.0.4", - "test-exclude": "^6.0.0" - } - }, - "babel-plugin-jest-hoist": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-29.2.0.tgz", - "integrity": "sha512-TnspP2WNiR3GLfCsUNHqeXw0RoQ2f9U5hQ5L3XFpwuO8htQmSrhh8qsB6vi5Yi8+kuynN1yjDjQsPfkebmB6ZA==", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.1.14", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-preset-current-node-syntax": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/babel-preset-current-node-syntax/-/babel-preset-current-node-syntax-1.0.1.tgz", - "integrity": "sha512-M7LQ0bxarkxQoN+vz5aJPsLBn77n8QgTFmo8WK0/44auK2xlCXrYcUxHFxgU7qW5Yzw/CjmLRK2uJzaCd7LvqQ==", - "dev": true, - "requires": { - "@babel/plugin-syntax-async-generators": "^7.8.4", - "@babel/plugin-syntax-bigint": "^7.8.3", - "@babel/plugin-syntax-class-properties": "^7.8.3", - "@babel/plugin-syntax-import-meta": "^7.8.3", - "@babel/plugin-syntax-json-strings": "^7.8.3", - "@babel/plugin-syntax-logical-assignment-operators": "^7.8.3", - "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.3", - "@babel/plugin-syntax-numeric-separator": "^7.8.3", - "@babel/plugin-syntax-object-rest-spread": "^7.8.3", - "@babel/plugin-syntax-optional-catch-binding": "^7.8.3", - "@babel/plugin-syntax-optional-chaining": "^7.8.3", - "@babel/plugin-syntax-top-level-await": "^7.8.3" - } - }, - "babel-preset-jest": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-29.2.0.tgz", - "integrity": "sha512-z9JmMJppMxNv8N7fNRHvhMg9cvIkMxQBXgFkane3yKVEvEOP+kB50lk8DFRvF9PGqbyXxlmebKWhuDORO8RgdA==", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^29.2.0", - "babel-preset-current-node-syntax": "^1.0.0" - } - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==" - }, - "base-64": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/base-64/-/base-64-0.1.0.tgz", - "integrity": "sha512-Y5gU45svrR5tI2Vt/X9GPd3L0HNIKzGu202EjxrXMpuc2V2CiKgemAbUUsqYmZJvPtCXoUKjNZwBJzsNScUbXA==" - }, - "base64id": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/base64id/-/base64id-2.0.0.tgz", - "integrity": "sha512-lGe34o6EHj9y3Kts9R4ZYs/Gr+6N7MCaMlIFA3F1R2O5/m7K06AxfSeO5530PEERE6/WyEg3lsuyw4GHlPZHog==" - }, - "basic-auth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", - "dev": true, - "requires": { - "safe-buffer": "5.1.2" - }, - "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 - } - } - }, - "body-parser": { - "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", - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "on-finished": "2.4.1", - "qs": "6.11.0", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - } - } - }, - "boolean": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", - "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "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" - } - }, - "browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "dev": true, - "requires": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" - } - }, - "bser": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/bser/-/bser-2.1.1.tgz", - "integrity": "sha512-gQxTNE/GAfIIrmHLUE3oJyp5FO6HRBfhjnw4/wMmA63ZGDJnWBmgY/lyQBpnDUkGmAhbSe39tx2d/iTOAfglwQ==", - "dev": true, - "requires": { - "node-int64": "^0.4.0" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "optional": true - }, - "buffer-from": { - "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 - }, - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==" - }, - "cacheable-request": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz", - "integrity": "sha512-Oj3cAGPCqOZX7Rz64Uny2GYAZNliQSqfbePrgAQ1wKAihYmCUnraBtJtKcGR4xz7wF+LoJC+ssFZvv5BgF9Igg==", - "optional": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^3.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 - } - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "camelcase-keys": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", - "integrity": "sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "map-obj": "^4.0.0", - "quick-lru": "^4.0.1" - } - }, - "caniuse-lite": { - "version": "1.0.30001412", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001412.tgz", - "integrity": "sha512-+TeEIee1gS5bYOiuf+PS/kp2mrXic37Hl66VY6EAfxasIk5fELTktK2oOezYed12H8w7jt3s512PpulQidPjwA==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "char-regex": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", - "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==", - "dev": true - }, - "charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==" - }, - "ci-info": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.5.0.tgz", - "integrity": "sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==", - "dev": true - }, - "cjs-module-lexer": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.2.tgz", - "integrity": "sha512-cOU9usZw8/dXIXKtwa8pM0OTJQuJkxMN6w30csNRUerHfeQ5R6U3kkU/FtJeIf3M202OHfY2U8ccInBG7/xogA==", - "dev": true - }, - "clarinet": { - "version": "0.12.5", - "resolved": "https://registry.npmjs.org/clarinet/-/clarinet-0.12.5.tgz", - "integrity": "sha512-4833ySquSUW91fnPaYI94LX3OdnyfwD8/NrMi6a4Kt6EmOsphLWmEzx9bZPqO9+DtQzSv2s3WSYNLsrXt59FKg==" - }, - "cliui": { - "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.1", - "wrap-ansi": "^7.0.0" - } - }, - "clone-response": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", - "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", - "optional": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha512-QVb0dM5HvG+uaxitm8wONl7jltx8dqhfU33DcqtOZcLSVIKSDDLDi7+0LbAKiyI8hD9u42m2YxXSkMGWThaecQ==", - "dev": true - }, - "collect-v8-coverage": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/collect-v8-coverage/-/collect-v8-coverage-1.0.1.tgz", - "integrity": "sha512-iBPtljfCNcTKNAto0KEtDfZ3qzjJvqE3aTGZsbhjSBlorqpXJlaWWtPO35D+ZImoC3KWejX64o+yPGxhWSTzfg==", - "dev": true - }, - "color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "requires": { - "color-name": "~1.1.4" - } - }, - "color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" - }, - "colord": { - "version": "2.9.3", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.3.tgz", - "integrity": "sha512-jeC1axXpnb0/2nn/Y1LPuLdgXBLH7aDcHu4KEKfqw3CUhX7ZpfBSlPKyqXE6btIgEzfWtrX3/tyBCaCvXvMkOw==", - "dev": true - }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==" - }, - "combined-stream": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", - "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==", - "requires": { - "delayed-stream": "~1.0.0" - } - }, - "comment-parser": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/comment-parser/-/comment-parser-1.3.1.tgz", - "integrity": "sha512-B52sN2VNghyq5ofvUsqZjmk6YkihBX5vMSChmSK9v4ShjKf3Vk5Xcmgpw4o+iIgtrnM/u5FiMpz9VKb8lpBveA==", - "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==", - "requires": { - "chalk": "^4.1.2", - "dateformat": "^4.6.3" - } - }, - "content-disposition": { - "version": "0.5.4", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz", - "integrity": "sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==", - "requires": { - "safe-buffer": "5.2.1" - } - }, - "content-type": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", - "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" - }, - "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 - } - } - }, - "cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==" - }, - "cookie-signature": { - "version": "1.0.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", - "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", - "requires": { - "object-assign": "^4", - "vary": "^1" - } - }, - "cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", - "dev": true, - "requires": { - "@types/parse-json": "^4.0.0", - "import-fresh": "^3.2.1", - "parse-json": "^5.0.0", - "path-type": "^4.0.0", - "yaml": "^1.10.0" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "requires": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - } - }, - "crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==" - }, - "css-functions-list": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/css-functions-list/-/css-functions-list-3.1.0.tgz", - "integrity": "sha512-/9lCvYZaUbBGvYUgYGFJ4dcYiyqdhSjG7IPVluoV8A1ILjkF7ilmhp1OGUz8n+nmBcu0RNrQAzgD8B6FJbrt2w==", - "dev": true - }, - "cssesc": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", - "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", - "dev": true - }, - "cssom": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.5.0.tgz", - "integrity": "sha512-iKuQcq+NdHqlAcwUY0o/HL69XQrUaQdMjmStJ8JFmUaiiQErlhrmuigkg/CU4E2J0IyUKUrMAgl36TvN67MqTw==", - "dev": true - }, - "cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "requires": { - "cssom": "~0.3.6" - }, - "dependencies": { - "cssom": { - "version": "0.3.8", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.3.8.tgz", - "integrity": "sha512-b0tGHbfegbhPJpxpiBPU2sCkigAqtM9O121le6bbOlgyV+NyGyCmVfJ6QW9eRjz8CpNfWEOYBIMIGRYkLwsIYg==", - "dev": true - } - } - }, - "data-urls": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-3.0.2.tgz", - "integrity": "sha512-Jy/tj3ldjZJo63sVAvg6LHt2mHvl4V6AgRAmNDtLdm7faqtsx+aJG42rsyCo9JCoRVKwPFzKlIPx3DIibwSIaQ==", - "dev": true, - "requires": { - "abab": "^2.0.6", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^11.0.0" - } - }, - "dateformat": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/dateformat/-/dateformat-4.6.3.tgz", - "integrity": "sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==" - }, - "debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "requires": { - "ms": "2.1.2" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==", - "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==", - "dev": true, - "requires": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - }, - "dependencies": { - "map-obj": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-1.0.1.tgz", - "integrity": "sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==", - "dev": true - } - } - }, - "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==", - "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==", - "optional": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==", - "dev": true - }, - "deep-is": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", - "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==" - }, - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", - "dev": true - }, - "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 - }, - "define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", - "optional": true, - "requires": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" - }, - "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==" - }, - "detect-newline": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/detect-newline/-/detect-newline-3.1.0.tgz", - "integrity": "sha512-TLz+x/vEXm/Y7P7wn1EJFNLxYpUD4TgMosxY6fAVJUnJMbupHBOncxyWUG9OpTaH9EBD7uFI5LfEgmMOc54DsA==", - "dev": true - }, - "detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "optional": true - }, - "diff": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-5.1.0.tgz", - "integrity": "sha512-D+mk+qE8VC/PAUrlAU34N+VfXev0ghe5ywmpqrawphmVZc1bEfn56uo9qpyGp1p4xpzOHkSW4ztBd6L7Xx4ACw==", - "dev": true - }, - "diff-sequences": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-29.2.0.tgz", - "integrity": "sha512-413SY5JpYeSBZxmenGEmCVQ8mCgtFJF0w9PROdaS6z987XC2Pd2GOKqOITLtMftmyFZqgtCOb/QA7/Z3ZXfzIw==", - "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==", - "requires": { - "base-64": "^0.1.0", - "md5": "^2.3.0" - } - }, - "dir-glob": { - "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" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "requires": { - "esutils": "^2.0.2" - } - }, - "domexception": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-4.0.0.tgz", - "integrity": "sha512-A2is4PLG+eeSfoTMA95/s4pvAoSo2mKtiM5jlHkAVewmiO8ISFTFKZjH7UAM1Atli/OT/7JHOrJRJiMKUZKYBw==", - "dev": true, - "requires": { - "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.3", - "resolved": "https://registry.npmjs.org/electron/-/electron-19.1.3.tgz", - "integrity": "sha512-P2kfFc8UqVvPHE1w9qTZSPNpfOqd+CK34K3wBqJwokzYdVBLsVkbIoLxyByjJ/cU35WaeCL5bsI8kXALfPvebw==", - "optional": true, - "requires": { - "@electron/get": "^1.14.1", - "@types/node": "^16.11.26", - "extract-zip": "^1.0.3" - } - }, - "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==", - "dev": true - }, - "emittery": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.13.1.tgz", - "integrity": "sha512-DeWwawk6r5yR9jFgnDKYt4sLS0LmHJJi3ZOnb5/JdbYwj3nW+FxQnHIjhBKz8YLC7oRNPVM9NQ47I3CVx34eqQ==", - "dev": true - }, - "emoji-regex": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", - "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha512-TPJXq8JqFaVYm2CWmPvnP2Iyo4ZSM7/QKcSmuMLDObfpH5fi7RUGmd/rTDf+rut/saiDiQEeVTNgAmJEdAOx0w==" - }, - "end-of-stream": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", - "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", - "devOptional": true, - "requires": { - "once": "^1.4.0" - } - }, - "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==", - "requires": { - "@types/cookie": "^0.4.1", - "@types/cors": "^2.8.12", - "@types/node": ">=10.0.0", - "accepts": "~1.3.4", - "base64id": "2.0.0", - "cookie": "~0.4.1", - "cors": "~2.8.5", - "debug": "~4.3.1", - "engine.io-parser": "~5.0.3", - "ws": "~8.2.3" - }, - "dependencies": { - "cookie": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", - "integrity": "sha512-aSWTXFzaKWkvHO1Ny/s+ePFpvKsPnjc551iI41v3ny/ow6tBG5Vd+FuqGNhh1LxOmVzOlGUriIlOaokOvhaStA==" - }, - "ws": { - "version": "8.2.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.2.3.tgz", - "integrity": "sha512-wBuoj1BDpC6ZQ1B7DWQBYVLphPWkm8i9Y0/3YdHjHKHiohOJ1ws+3OccDWtH+PoC9DZD5WOTrJvNbWvjS6JWaA==", - "requires": {} - } - } - }, - "engine.io-parser": { - "version": "5.0.4", - "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-5.0.4.tgz", - "integrity": "sha512-+nVFp+5z1E3HcToEnO7ZIj3g+3k9389DvWtvJZz0T6/eOCPIyyxehFcedoYrZQrp0LgQbD9pPXhpMBKMd5QURg==" - }, - "entities": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz", - "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==", - "dev": true - }, - "env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "optional": true - }, - "error-ex": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", - "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", - "dev": true, - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "optional": true - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "dev": true - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==" - }, - "escape-string-regexp": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", - "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==" - }, - "escodegen": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz", - "integrity": "sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw==", - "dev": true, - "requires": { - "esprima": "^4.0.1", - "estraverse": "^5.2.0", - "esutils": "^2.0.2", - "optionator": "^0.8.1", - "source-map": "~0.6.1" - }, - "dependencies": { - "levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } - }, - "optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "requires": { - "deep-is": "~0.1.3", - "fast-levenshtein": "~2.0.6", - "levn": "~0.3.0", - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2", - "word-wrap": "~1.2.3" - } - }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w==", - "dev": true - }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg==", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - } - } - }, - "eslint": { - "version": "8.26.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.26.0.tgz", - "integrity": "sha512-kzJkpaw1Bfwheq4VXUezFriD1GxszX6dUekM7Z3aC2o4hju+tsR/XyTC3RcoSD7jmy9VkPU3+N6YjVU2e96Oyg==", - "requires": { - "@eslint/eslintrc": "^1.3.3", - "@humanwhocodes/config-array": "^0.11.6", - "@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", - "debug": "^4.3.2", - "doctrine": "^3.0.0", - "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-utils": "^3.0.0", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.4.0", - "esquery": "^1.4.0", - "esutils": "^2.0.2", - "fast-deep-equal": "^3.1.3", - "file-entry-cache": "^6.0.1", - "find-up": "^5.0.0", - "glob-parent": "^6.0.2", - "globals": "^13.15.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", - "levn": "^0.4.1", - "lodash.merge": "^4.6.2", - "minimatch": "^3.1.2", - "natural-compare": "^1.4.0", - "optionator": "^0.9.1", - "regexpp": "^3.2.0", - "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", - "text-table": "^0.2.0" - } - }, - "eslint-config-prettier": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.5.0.tgz", - "integrity": "sha512-obmWKLUNCnhtQRKc+tmnYuQl0pFU1ibYJQ5BGhTVB08bHe9wC8qUeG7c08dj9XX+AuPj1YSGSQIHl1pnDHZR0Q==", - "dev": true, - "requires": {} - }, - "eslint-plugin-jest": { - "version": "27.1.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-27.1.3.tgz", - "integrity": "sha512-7DrIfYRQPa7JQd1Le8G/BJsfYHVUKQdJQ/6vULSp/4NjKZmSMJ/605G2hhScEra++SiH68zPEjLnrO74nHrMLg==", - "dev": true, - "requires": { - "@typescript-eslint/utils": "^5.10.0" - } - }, - "eslint-plugin-jsdoc": { - "version": "39.3.25", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsdoc/-/eslint-plugin-jsdoc-39.3.25.tgz", - "integrity": "sha512-7JiFOOaipz7Z7lNQ9sMJ6cdvclmVUwNYtFWGS3a0k0uEFcdZPPD64WOfENuyNHpl86C0AKIEPgOpZby5kd+pew==", - "dev": true, - "requires": { - "@es-joy/jsdoccomment": "~0.33.4", - "comment-parser": "1.3.1", - "debug": "^4.3.4", - "escape-string-regexp": "^4.0.0", - "esquery": "^1.4.0", - "semver": "^7.3.8", - "spdx-expression-parse": "^3.0.1" - }, - "dependencies": { - "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" - } - } - } - }, - "eslint-plugin-prettier": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-4.2.1.tgz", - "integrity": "sha512-f/0rXLXUt0oFYs8ra4w49wYZBG5GKZpAYsJSm6rnYL5uVDjd+zowwMwVZHnAjf4edNrKpCDYfXDgmRE/Ak7QyQ==", - "dev": true, - "requires": { - "prettier-linter-helpers": "^1.0.0" - } - }, - "eslint-scope": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.1.1.tgz", - "integrity": "sha512-QKQM/UXpIiHcLqJ5AOyIW7XZmzjkzQXYE54n1++wb0u9V/abW3l9uQnxX8Z5Xd18xyKIMTUAyQ0k1e8pz6LUrw==", - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "requires": { - "eslint-visitor-keys": "^2.0.0" - }, - "dependencies": { - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==" - } - } - }, - "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==" - }, - "espree": { - "version": "9.4.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.0.tgz", - "integrity": "sha512-DQmnRpLj7f6TgN/NYb0MTzJXL+vJF9h3pHy4JhCIs3zwcgez8xmGg3sXHcEO97BrmO2OSvCwMdfdlyl+E9KjOw==", - "requires": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "requires": { - "estraverse": "^5.1.0" - } - }, - "esrecurse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz", - "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==", - "requires": { - "estraverse": "^5.2.0" - } - }, - "estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==" - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==" - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==" - }, - "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" - }, - "dependencies": { - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", - "dev": true - } - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==", - "dev": true - }, - "expect": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/expect/-/expect-29.2.2.tgz", - "integrity": "sha512-hE09QerxZ5wXiOhqkXy5d2G9ar+EqOyifnCXCpMNu+vZ6DG9TJ6CO2c2kPDSLqERTTWrO7OZj8EkYHQqSd78Yw==", - "dev": true, - "requires": { - "@jest/expect-utils": "^29.2.2", - "jest-get-type": "^29.2.0", - "jest-matcher-utils": "^29.2.2", - "jest-message-util": "^29.2.1", - "jest-util": "^29.2.1" - } - }, - "express": { - "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.1", - "content-disposition": "0.5.4", - "content-type": "~1.0.4", - "cookie": "0.5.0", - "cookie-signature": "1.0.6", - "debug": "2.6.9", - "depd": "2.0.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "finalhandler": "1.2.0", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "merge-descriptors": "1.0.1", - "methods": "~1.1.2", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "path-to-regexp": "0.1.7", - "proxy-addr": "~2.0.7", - "qs": "6.11.0", - "range-parser": "~1.2.1", - "safe-buffer": "5.2.1", - "send": "0.18.0", - "serve-static": "1.15.0", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "type-is": "~1.6.18", - "utils-merge": "1.0.1", - "vary": "~1.1.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "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==" - } - } - }, - "express-basic-auth": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/express-basic-auth/-/express-basic-auth-1.2.1.tgz", - "integrity": "sha512-L6YQ1wQ/mNjVLAmK3AG1RK6VkokA1BIY6wmiH304Xtt/cLTps40EusZsU1Uop+v9lTDPxdtzbFmdXfFO3KEnwA==", - "dev": true, - "requires": { - "basic-auth": "^2.0.1" - } - }, - "express-ipfilter": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/express-ipfilter/-/express-ipfilter-1.3.1.tgz", - "integrity": "sha512-9WZC8wGkI6I6ygZNzuZ2MbFJiGoDXs1dM+E8LKtSP13pdgqrnkonWlgvvbxG3YZpa7Haz7Ndum9/J6qkj52OqA==", - "requires": { - "ip": "^1.1.8", - "lodash": "^4.17.11", - "proxy-addr": "^2.0.7", - "range_check": "^2.0.4" - } - }, - "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==", - "optional": true, - "requires": { - "concat-stream": "^1.6.2", - "debug": "^2.6.9", - "mkdirp": "^0.5.4", - "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": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" - }, - "fast-diff": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/fast-diff/-/fast-diff-1.2.0.tgz", - "integrity": "sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==", - "dev": true - }, - "fast-glob": { - "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", - "glob-parent": "^5.1.2", - "merge2": "^1.3.0", - "micromatch": "^4.0.4" - }, - "dependencies": { - "glob-parent": { - "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" - } - } - } - }, - "fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==" - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==" - }, - "fastest-levenshtein": { - "version": "1.0.16", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz", - "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==", - "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==", - "requires": { - "reusify": "^1.0.4" - } - }, - "fb-watchman": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", - "integrity": "sha512-p5161BqbuCaSnB8jIbzQHOlpgsPmK5rJVDfDKO91Axs5NC1uu3HRQm6wt9cd9/+GtQQIO53JdGXXoyDpTAsgYA==", - "dev": true, - "requires": { - "bser": "2.1.1" - } - }, - "fd-slicer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", - "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==", - "optional": true, - "requires": { - "pend": "~1.2.0" - } - }, - "feedme": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/feedme/-/feedme-2.0.2.tgz", - "integrity": "sha512-0RNn0uLaSey8EThxgABR0T1Q47kSRatYnAXy1cfUc8/eypqXiAu38XGthuwwzb7mESCD9465k6Nym8D9AtB8HA==", - "requires": { - "clarinet": "^0.12.4", - "sax": "^1.2.4" - } - }, - "file-entry-cache": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", - "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", - "requires": { - "flat-cache": "^3.0.4" - } - }, - "fill-range": { - "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" - } - }, - "finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "requires": { - "debug": "2.6.9", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "on-finished": "2.4.1", - "parseurl": "~1.3.3", - "statuses": "2.0.1", - "unpipe": "~1.0.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "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==" - } - } - }, - "find-up": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", - "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", - "requires": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - } - }, - "flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz", - "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==" - }, - "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" - }, - "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==", - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==" - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==" - }, - "fs-extra": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-8.1.0.tgz", - "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==", - "optional": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" - }, - "fsevents": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", - "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", - "dev": true, - "optional": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "gensync": { - "version": "1.0.0-beta.2", - "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", - "integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - } - }, - "get-package-type": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", - "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", - "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, - "requires": { - "pump": "^3.0.0" - } - }, - "glob": { - "version": "7.2.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", - "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.1.1", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", - "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", - "requires": { - "is-glob": "^4.0.3" - } - }, - "global-agent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-agent/-/global-agent-3.0.0.tgz", - "integrity": "sha512-PT6XReJ+D07JvGoxQMkT6qji/jVNfX/h364XHZOWeRzy64sSFr+xJ5OX7LI3b4MPQzdL4H8Y8M0xzPpsVMwA8Q==", - "optional": true, - "requires": { - "boolean": "^3.0.1", - "es6-error": "^4.1.1", - "matcher": "^3.0.0", - "roarr": "^2.15.3", - "semver": "^7.3.2", - "serialize-error": "^7.0.1" - }, - "dependencies": { - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "optional": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, - "global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dev": true, - "requires": { - "global-prefix": "^3.0.0" - } - }, - "global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dev": true, - "requires": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "dependencies": { - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - } - } - }, - "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==", - "requires": { - "type-fest": "^0.20.2" - } - }, - "globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "optional": true, - "requires": { - "define-properties": "^1.1.3" - } - }, - "globby": { - "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", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - } - }, - "globjoin": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", - "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", - "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==", - "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" - } - }, - "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==", - "devOptional": true - }, - "grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==" - }, - "hard-rejection": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", - "integrity": "sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==", - "dev": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" - }, - "has-property-descriptors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz", - "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==", - "optional": true, - "requires": { - "get-intrinsic": "^1.1.1" - } - }, - "has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==" - }, - "helmet": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/helmet/-/helmet-6.0.0.tgz", - "integrity": "sha512-FO9RpR1wNJepH/GbLPQVtkE2eESglXL641p7SdyoT4LngHFJcZheHMoyUcjCZF4qpuMMO1u5q6RK0l9Ux8JBcg==" - }, - "hosted-git-info": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz", - "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - }, - "html-encoding-sniffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", - "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", - "dev": true, - "requires": { - "whatwg-encoding": "^2.0.0" - } - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==", - "dev": true - }, - "html-tags": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-3.2.0.tgz", - "integrity": "sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==", - "dev": true - }, - "http-cache-semantics": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz", - "integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==", - "optional": true - }, - "http-errors": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.0.tgz", - "integrity": "sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==", - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - } - }, - "http-proxy-agent": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz", - "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==", - "dev": true, - "requires": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - } - }, - "https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==", - "dev": true, - "requires": { - "agent-base": "6", - "debug": "4" - } - }, - "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", - "dev": true - }, - "husky": { - "version": "8.0.1", - "resolved": "https://registry.npmjs.org/husky/-/husky-8.0.1.tgz", - "integrity": "sha512-xs7/chUH/CKdOCs7Zy0Aev9e/dKOMZf3K1Az1nar3tzlv0jfqnYtu235bstsWTmXOR0EfINrPa97yy4Lz6RiKw==", - "dev": true - }, - "iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==" - }, - "import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "requires": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - } - }, - "import-lazy": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-4.0.0.tgz", - "integrity": "sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==", - "dev": true - }, - "import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "requires": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==" - }, - "indent-string": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", - "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "devOptional": true - }, - "ip": { - "version": "1.1.8", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.8.tgz", - "integrity": "sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==" - }, - "ip6": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/ip6/-/ip6-0.2.10.tgz", - "integrity": "sha512-1LdpyKjhvepd6EbAU6rW4g14vuYtx5TnJX9TfZZBhsM6DsyPQLNzW12rtbUqXBMwqFrLVV/Gcxv0GNFvJp2cYA==" - }, - "ipaddr.js": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", - "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==" - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==", - "dev": true - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "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==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==" - }, - "is-fullwidth-code-point": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", - "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", - "dev": true - }, - "is-generator-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-generator-fn/-/is-generator-fn-2.1.0.tgz", - "integrity": "sha512-cTIB4yPYL/Grw0EaSzASzg6bBy9gqCofvWN8okThAYIxKJZC+udlRAmGbM0XLeniEJSs8uEgHPGuHSe1XsOLSQ==", - "dev": true - }, - "is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-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", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "dev": true - }, - "is-plain-object": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-5.0.0.tgz", - "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==", - "dev": true - }, - "is-potential-custom-element-name": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz", - "integrity": "sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ==", - "dev": true - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "optional": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" - }, - "istanbul-lib-coverage": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.0.tgz", - "integrity": "sha512-eOeJ5BHCmHYvQK7xt9GkdHuzuCGS1Y6g9Gvnx3Ym33fz/HpLRYxiS0wHNr+m/MBC8B647Xt608vCDEvhl9c6Mw==", - "dev": true - }, - "istanbul-lib-instrument": { - "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", - "@babel/parser": "^7.14.7", - "@istanbuljs/schema": "^0.1.2", - "istanbul-lib-coverage": "^3.2.0", - "semver": "^6.3.0" - } - }, - "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, - "requires": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - } - }, - "istanbul-lib-source-maps": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-4.0.1.tgz", - "integrity": "sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - } - }, - "istanbul-reports": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.5.tgz", - "integrity": "sha512-nUsEMa9pBt/NOHqbcbeJEgqIlY/K7rVWUX6Lql2orY5e9roQOthbR3vtY4zzf2orPELg80fnxxk9zUyPlgwD1w==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "jest": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest/-/jest-29.2.2.tgz", - "integrity": "sha512-r+0zCN9kUqoON6IjDdjbrsWobXM/09Nd45kIPRD8kloaRh1z5ZCMdVsgLXGxmlL7UpAJsvCYOQNO+NjvG/gqiQ==", - "dev": true, - "requires": { - "@jest/core": "^29.2.2", - "@jest/types": "^29.2.1", - "import-local": "^3.0.2", - "jest-cli": "^29.2.2" - } - }, - "jest-changed-files": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-29.2.0.tgz", - "integrity": "sha512-qPVmLLyBmvF5HJrY7krDisx6Voi8DmlV3GZYX0aFNbaQsZeoz1hfxcCMbqDGuQCxU1dJy9eYc2xscE8QrCCYaA==", - "dev": true, - "requires": { - "execa": "^5.0.0", - "p-limit": "^3.1.0" - } - }, - "jest-circus": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.2.2.tgz", - "integrity": "sha512-upSdWxx+Mh4DV7oueuZndJ1NVdgtTsqM4YgywHEx05UMH5nxxA2Qu9T9T9XVuR021XxqSoaKvSmmpAbjwwwxMw==", - "dev": true, - "requires": { - "@jest/environment": "^29.2.2", - "@jest/expect": "^29.2.2", - "@jest/test-result": "^29.2.1", - "@jest/types": "^29.2.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "is-generator-fn": "^2.0.0", - "jest-each": "^29.2.1", - "jest-matcher-utils": "^29.2.2", - "jest-message-util": "^29.2.1", - "jest-runtime": "^29.2.2", - "jest-snapshot": "^29.2.2", - "jest-util": "^29.2.1", - "p-limit": "^3.1.0", - "pretty-format": "^29.2.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-cli": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-29.2.2.tgz", - "integrity": "sha512-R45ygnnb2CQOfd8rTPFR+/fls0d+1zXS6JPYTBBrnLPrhr58SSuPTiA5Tplv8/PXpz4zXR/AYNxmwIj6J6nrvg==", - "dev": true, - "requires": { - "@jest/core": "^29.2.2", - "@jest/test-result": "^29.2.1", - "@jest/types": "^29.2.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^29.2.2", - "jest-util": "^29.2.1", - "jest-validate": "^29.2.2", - "prompts": "^2.0.1", - "yargs": "^17.3.1" - } - }, - "jest-config": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-29.2.2.tgz", - "integrity": "sha512-Q0JX54a5g1lP63keRfKR8EuC7n7wwny2HoTRDb8cx78IwQOiaYUVZAdjViY3WcTxpR02rPUpvNVmZ1fkIlZPcw==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@jest/test-sequencer": "^29.2.2", - "@jest/types": "^29.2.1", - "babel-jest": "^29.2.2", - "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.2.2", - "jest-environment-node": "^29.2.2", - "jest-get-type": "^29.2.0", - "jest-regex-util": "^29.2.0", - "jest-resolve": "^29.2.2", - "jest-runner": "^29.2.2", - "jest-util": "^29.2.1", - "jest-validate": "^29.2.2", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^29.2.1", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - } - }, - "jest-diff": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-29.2.1.tgz", - "integrity": "sha512-gfh/SMNlQmP3MOUgdzxPOd4XETDJifADpT937fN1iUGz+9DgOu2eUPHH25JDkLVcLwwqxv3GzVyK4VBUr9fjfA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^29.2.0", - "jest-get-type": "^29.2.0", - "pretty-format": "^29.2.1" - } - }, - "jest-docblock": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-29.2.0.tgz", - "integrity": "sha512-bkxUsxTgWQGbXV5IENmfiIuqZhJcyvF7tU4zJ/7ioTutdz4ToB5Yx6JOFBpgI+TphRY4lhOyCWGNH/QFQh5T6A==", - "dev": true, - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-29.2.1.tgz", - "integrity": "sha512-sGP86H/CpWHMyK3qGIGFCgP6mt+o5tu9qG4+tobl0LNdgny0aitLXs9/EBacLy3Bwqy+v4uXClqJgASJWcruYw==", - "dev": true, - "requires": { - "@jest/types": "^29.2.1", - "chalk": "^4.0.0", - "jest-get-type": "^29.2.0", - "jest-util": "^29.2.1", - "pretty-format": "^29.2.1" - } - }, - "jest-environment-node": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.2.2.tgz", - "integrity": "sha512-B7qDxQjkIakQf+YyrqV5dICNs7tlCO55WJ4OMSXsqz1lpI/0PmeuXdx2F7eU8rnPbRkUR/fItSSUh0jvE2y/tw==", - "dev": true, - "requires": { - "@jest/environment": "^29.2.2", - "@jest/fake-timers": "^29.2.2", - "@jest/types": "^29.2.1", - "@types/node": "*", - "jest-mock": "^29.2.2", - "jest-util": "^29.2.1" - } - }, - "jest-get-type": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.2.0.tgz", - "integrity": "sha512-uXNJlg8hKFEnDgFsrCjznB+sTxdkuqiCL6zMgA75qEbAJjJYTs9XPrvDctrEig2GDow22T/LvHgO57iJhXB/UA==", - "dev": true - }, - "jest-haste-map": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-29.2.1.tgz", - "integrity": "sha512-wF460rAFmYc6ARcCFNw4MbGYQjYkvjovb9GBT+W10Um8q5nHq98jD6fHZMDMO3tA56S8XnmNkM8GcA8diSZfnA==", - "dev": true, - "requires": { - "@jest/types": "^29.2.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.2.0", - "jest-util": "^29.2.1", - "jest-worker": "^29.2.1", - "micromatch": "^4.0.4", - "walker": "^1.0.8" - } - }, - "jest-leak-detector": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-29.2.1.tgz", - "integrity": "sha512-1YvSqYoiurxKOJtySc+CGVmw/e1v4yNY27BjWTVzp0aTduQeA7pdieLiW05wTYG/twlKOp2xS/pWuikQEmklug==", - "dev": true, - "requires": { - "jest-get-type": "^29.2.0", - "pretty-format": "^29.2.1" - } - }, - "jest-matcher-utils": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-29.2.2.tgz", - "integrity": "sha512-4DkJ1sDPT+UX2MR7Y3od6KtvRi9Im1ZGLGgdLFLm4lPexbTaCgJW5NN3IOXlQHF7NSHY/VHhflQ+WoKtD/vyCw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^29.2.1", - "jest-get-type": "^29.2.0", - "pretty-format": "^29.2.1" - } - }, - "jest-message-util": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-29.2.1.tgz", - "integrity": "sha512-Dx5nEjw9V8C1/Yj10S/8ivA8F439VS8vTq1L7hEgwHFn9ovSKNpYW/kwNh7UglaEgXO42XxzKJB+2x0nSglFVw==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^29.2.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^29.2.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-mock": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-29.2.2.tgz", - "integrity": "sha512-1leySQxNAnivvbcx0sCB37itu8f4OX2S/+gxLAV4Z62shT4r4dTG9tACDywUAEZoLSr36aYUTsVp3WKwWt4PMQ==", - "dev": true, - "requires": { - "@jest/types": "^29.2.1", - "@types/node": "*", - "jest-util": "^29.2.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==", - "dev": true, - "requires": {} - }, - "jest-regex-util": { - "version": "29.2.0", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-29.2.0.tgz", - "integrity": "sha512-6yXn0kg2JXzH30cr2NlThF+70iuO/3irbaB4mh5WyqNIvLLP+B6sFdluO1/1RJmslyh/f9osnefECflHvTbwVA==", - "dev": true - }, - "jest-resolve": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-29.2.2.tgz", - "integrity": "sha512-3gaLpiC3kr14rJR3w7vWh0CBX2QAhfpfiQTwrFPvVrcHe5VUBtIXaR004aWE/X9B2CFrITOQAp5gxLONGrk6GA==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^29.2.1", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^29.2.1", - "jest-validate": "^29.2.2", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - } - }, - "jest-resolve-dependencies": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-29.2.2.tgz", - "integrity": "sha512-wWOmgbkbIC2NmFsq8Lb+3EkHuW5oZfctffTGvwsA4JcJ1IRk8b2tg+hz44f0lngvRTeHvp3Kyix9ACgudHH9aQ==", - "dev": true, - "requires": { - "jest-regex-util": "^29.2.0", - "jest-snapshot": "^29.2.2" - } - }, - "jest-runner": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-29.2.2.tgz", - "integrity": "sha512-1CpUxXDrbsfy9Hr9/1zCUUhT813kGGK//58HeIw/t8fa/DmkecEwZSWlb1N/xDKXg3uCFHQp1GCvlSClfImMxg==", - "dev": true, - "requires": { - "@jest/console": "^29.2.1", - "@jest/environment": "^29.2.2", - "@jest/test-result": "^29.2.1", - "@jest/transform": "^29.2.2", - "@jest/types": "^29.2.1", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^29.2.0", - "jest-environment-node": "^29.2.2", - "jest-haste-map": "^29.2.1", - "jest-leak-detector": "^29.2.1", - "jest-message-util": "^29.2.1", - "jest-resolve": "^29.2.2", - "jest-runtime": "^29.2.2", - "jest-util": "^29.2.1", - "jest-watcher": "^29.2.2", - "jest-worker": "^29.2.1", - "p-limit": "^3.1.0", - "source-map-support": "0.5.13" - } - }, - "jest-runtime": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-29.2.2.tgz", - "integrity": "sha512-TpR1V6zRdLynckKDIQaY41od4o0xWL+KOPUCZvJK2bu5P1UXhjobt5nJ2ICNeIxgyj9NGkO0aWgDqYPVhDNKjA==", - "dev": true, - "requires": { - "@jest/environment": "^29.2.2", - "@jest/fake-timers": "^29.2.2", - "@jest/globals": "^29.2.2", - "@jest/source-map": "^29.2.0", - "@jest/test-result": "^29.2.1", - "@jest/transform": "^29.2.2", - "@jest/types": "^29.2.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.2.1", - "jest-message-util": "^29.2.1", - "jest-mock": "^29.2.2", - "jest-regex-util": "^29.2.0", - "jest-resolve": "^29.2.2", - "jest-snapshot": "^29.2.2", - "jest-util": "^29.2.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - } - }, - "jest-snapshot": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-29.2.2.tgz", - "integrity": "sha512-GfKJrpZ5SMqhli3NJ+mOspDqtZfJBryGA8RIBxF+G+WbDoC7HCqKaeAss4Z/Sab6bAW11ffasx8/vGsj83jyjA==", - "dev": true, - "requires": { - "@babel/core": "^7.11.6", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-jsx": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.3.3", - "@jest/expect-utils": "^29.2.2", - "@jest/transform": "^29.2.2", - "@jest/types": "^29.2.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.2.2", - "graceful-fs": "^4.2.9", - "jest-diff": "^29.2.1", - "jest-get-type": "^29.2.0", - "jest-haste-map": "^29.2.1", - "jest-matcher-utils": "^29.2.2", - "jest-message-util": "^29.2.1", - "jest-util": "^29.2.1", - "natural-compare": "^1.4.0", - "pretty-format": "^29.2.1", - "semver": "^7.3.5" - }, - "dependencies": { - "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" - } - } - } - }, - "jest-util": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-29.2.1.tgz", - "integrity": "sha512-P5VWDj25r7kj7kl4pN2rG/RN2c1TLfYYYZYULnS/35nFDjBai+hBeo3MDrYZS7p6IoY3YHZnt2vq4L6mKnLk0g==", - "dev": true, - "requires": { - "@jest/types": "^29.2.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, - "jest-validate": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.2.2.tgz", - "integrity": "sha512-eJXATaKaSnOuxNfs8CLHgdABFgUrd0TtWS8QckiJ4L/QVDF4KVbZFBBOwCBZHOS0Rc5fOxqngXeGXE3nGQkpQA==", - "dev": true, - "requires": { - "@jest/types": "^29.2.1", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^29.2.0", - "leven": "^3.1.0", - "pretty-format": "^29.2.1" - }, - "dependencies": { - "camelcase": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz", - "integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==", - "dev": true - } - } - }, - "jest-watcher": { - "version": "29.2.2", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-29.2.2.tgz", - "integrity": "sha512-j2otfqh7mOvMgN2WlJ0n7gIx9XCMWntheYGlBK7+5g3b1Su13/UAK7pdKGyd4kDlrLwtH2QPvRv5oNIxWvsJ1w==", - "dev": true, - "requires": { - "@jest/test-result": "^29.2.1", - "@jest/types": "^29.2.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.13.1", - "jest-util": "^29.2.1", - "string-length": "^4.0.1" - } - }, - "jest-worker": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-29.2.1.tgz", - "integrity": "sha512-ROHTZ+oj7sBrgtv46zZ84uWky71AoYi0vEV9CdEtc1FQunsoAGe5HbQmW76nI5QWdvECVPrSi1MCVUmizSavMg==", - "dev": true, - "requires": { - "@types/node": "*", - "jest-util": "^29.2.1", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "dependencies": { - "supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - } - } - }, - "js-sdsl": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.1.4.tgz", - "integrity": "sha512-Y2/yD55y5jteOAmY50JbUZYwk3CP3wnLPEZnlR1w9oKhITrBEtAxwuWKebFf8hMrPMgbYwFoWK/lH2sBkErELw==" - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", - "dev": true - }, - "js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "requires": { - "argparse": "^2.0.1" - } - }, - "jsdoc-type-pratt-parser": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/jsdoc-type-pratt-parser/-/jsdoc-type-pratt-parser-3.1.0.tgz", - "integrity": "sha512-MgtD0ZiCDk9B+eI73BextfRrVQl0oyzRG8B2BjORts6jbunj4ScKPcyXGTbB6eXL4y9TzxCm6hyeLq/2ASzNdw==", - "dev": true - }, - "jsdom": { - "version": "20.0.1", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-20.0.1.tgz", - "integrity": "sha512-pksjj7Rqoa+wdpkKcLzQRHhJCEE42qQhl/xLMUKHgoSejaKOdaXEAnqs6uDNwMl/fciHTzKeR8Wm8cw7N+g98A==", - "dev": true, - "requires": { - "abab": "^2.0.6", - "acorn": "^8.8.0", - "acorn-globals": "^7.0.0", - "cssom": "^0.5.0", - "cssstyle": "^2.3.0", - "data-urls": "^3.0.2", - "decimal.js": "^10.4.1", - "domexception": "^4.0.0", - "escodegen": "^2.0.0", - "form-data": "^4.0.0", - "html-encoding-sniffer": "^3.0.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.1", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.2", - "parse5": "^7.1.1", - "saxes": "^6.0.0", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.1.2", - "w3c-xmlserializer": "^3.0.0", - "webidl-conversions": "^7.0.0", - "whatwg-encoding": "^2.0.0", - "whatwg-mimetype": "^3.0.0", - "whatwg-url": "^11.0.0", - "ws": "^8.9.0", - "xml-name-validator": "^4.0.0" - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "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==", - "optional": true - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" - }, - "json-stable-stringify-without-jsonify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", - "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" - }, - "json-stringify-safe": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==", - "optional": true - }, - "json5": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.1.tgz", - "integrity": "sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==", - "dev": true - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==", - "optional": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "just-extend": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/just-extend/-/just-extend-4.2.1.tgz", - "integrity": "sha512-g3UB796vUFIY90VIv/WX3L2c8CS2MdWUww3CNrYmqza1Fg0DURc2K/O4YrnklBdQarSJ/y8JnJYDGc+1iumQjg==", - "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==", - "optional": true, - "requires": { - "json-buffer": "3.0.0" - } - }, - "kind-of": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", - "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", - "dev": true - }, - "kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "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==", - "dev": true - }, - "leven": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", - "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", - "dev": true - }, - "levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lines-and-columns": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", - "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", - "dev": true - }, - "locate-path": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", - "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", - "requires": { - "p-locate": "^5.0.0" - } - }, - "lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" - }, - "lodash.get": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", - "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==", - "dev": true - }, - "lodash.merge": { - "version": "4.6.2", - "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", - "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" - }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "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==", - "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, - "requires": { - "yallist": "^4.0.0" - } - }, - "luxon": { - "version": "1.28.0", - "resolved": "https://registry.npmjs.org/luxon/-/luxon-1.28.0.tgz", - "integrity": "sha512-TfTiyvZhwBYM/7QdAVDh+7dBTBA29v4ik0Ce9zda3Mnf8on1S5KJI8P2jKFZ8+5C0jhmr0KwJEO/Wdpm0VeWJQ==" - }, - "make-dir": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", - "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", - "dev": true, - "requires": { - "semver": "^6.0.0" - } - }, - "makeerror": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", - "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", - "dev": true, - "requires": { - "tmpl": "1.0.5" - } - }, - "map-obj": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-4.3.0.tgz", - "integrity": "sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==", - "dev": true - }, - "matcher": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", - "optional": true, - "requires": { - "escape-string-regexp": "^4.0.0" - } - }, - "mathml-tag-names": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/mathml-tag-names/-/mathml-tag-names-2.1.3.tgz", - "integrity": "sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==", - "dev": true - }, - "md5": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", - "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", - "requires": { - "charenc": "0.0.2", - "crypt": "0.0.2", - "is-buffer": "~1.1.6" - } - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==" - }, - "meow": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", - "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", - "dev": true, - "requires": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize": "^1.2.0", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^3.0.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.18.0", - "yargs-parser": "^20.2.3" - }, - "dependencies": { - "type-fest": { - "version": "0.18.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.18.1.tgz", - "integrity": "sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==", - "dev": true - } - } - }, - "merge-descriptors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", - "integrity": "sha512-cCi6g3/Zr1iqQi6ySbseM1Xvooa98N0w31jzUYrXPX2xqObmFGHJ0tQ5u74H3mVh7wLouTseZyYIq39g8cNp1w==" - }, - "merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", - "dev": true - }, - "merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "dev": true - }, - "methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==" - }, - "micromatch": { - "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" - } - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==" - }, - "mime-db": { - "version": "1.52.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", - "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==" - }, - "mime-types": { - "version": "2.1.35", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz", - "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==", - "requires": { - "mime-db": "1.52.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "optional": true - }, - "min-indent": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", - "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "requires": { - "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", - "integrity": "sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==", - "dev": true, - "requires": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - }, - "dependencies": { - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true - } - } - }, - "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", - "integrity": "sha512-A/78XjoX2EmNvppVWEhM2oGk3x4lLxnkEA4jTbaK97QKSDjkIoOsKQlfylt/d3kKKi596Qy3NP5XrXJ6fZIC9Q==" - }, - "moment": { - "version": "2.29.4", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", - "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==", - "requires": { - "moment": ">= 2.9.0" - } - }, - "mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "dev": true - }, - "ms": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", - "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" - }, - "multimatch": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/multimatch/-/multimatch-4.0.0.tgz", - "integrity": "sha512-lDmx79y1z6i7RNx0ZGCPq1bzJ6ZoDDKbvh7jxr9SJcWLkShMzXrHbYVpTdnhNM5MXpDUxCQ4DgqVttVXlBgiBQ==", - "dev": true, - "requires": { - "@types/minimatch": "^3.0.3", - "array-differ": "^3.0.0", - "array-union": "^2.1.0", - "arrify": "^2.0.1", - "minimatch": "^3.0.4" - } - }, - "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", - "dev": true - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==" - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "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==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.8.3", - "@sinonjs/fake-timers": ">=5", - "@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 - }, - "path-to-regexp": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-1.8.0.tgz", - "integrity": "sha512-n43JRhlUKUAlibEJhPeir1ncUID16QnEjNpwzNdO3Lm4ywrBpBZ5oLD0I6br9evr1Y9JTqwRtAh7JLoOzAQdVA==", - "dev": true, - "requires": { - "isarray": "0.0.1" - } - } - } - }, - "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", - "requires": { - "whatwg-url": "^5.0.0" - }, - "dependencies": { - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - } - } - }, - "node-ical": { - "version": "0.15.2", - "resolved": "https://registry.npmjs.org/node-ical/-/node-ical-0.15.2.tgz", - "integrity": "sha512-p5KD4thji/9/rDLr4+Ig8QZzRhc1otRV1e85nFIgxJBJnLkF3hG15fxB30DlLQ9QtnzpR7AlgERTwhJuszC0cg==", - "requires": { - "axios": "^1.1.2", - "moment-timezone": "^0.5.31", - "rrule": "2.6.4", - "uuid": "^9.0.0" - } - }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw==", - "dev": true - }, - "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==", - "dev": true - }, - "normalize-package-data": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-3.0.3.tgz", - "integrity": "sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==", - "dev": true, - "requires": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "7.3.7", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.7.tgz", - "integrity": "sha512-QlYTucUYOews+WeEujDoEGziz4K6c47V/Bd+LjSSYcA94p+DmINdf7ncaUinThfvZyu13lN9OY1XDxt8C0Tw0g==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "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==", - "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", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", - "dev": true, - "requires": { - "path-key": "^3.0.0" - } - }, - "nwsapi": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.2.tgz", - "integrity": "sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==" - }, - "object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==" - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "optional": true - }, - "on-finished": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", - "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "requires": { - "ee-first": "1.1.1" - } - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dev": true, - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "requires": { - "deep-is": "^0.1.3", - "fast-levenshtein": "^2.0.6", - "levn": "^0.4.1", - "prelude-ls": "^1.2.1", - "type-check": "^0.4.0", - "word-wrap": "^1.2.3" - } - }, - "p-cancelable": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-1.1.0.tgz", - "integrity": "sha512-s73XxOZ4zpt1edZYZzvhqFa6uvQc1vwUa0K0BdtIZgQMAJj9IbebH+JkgKZc9h+B05PKHLOTl4ajG1BmNrVZlw==", - "optional": true - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "requires": { - "yocto-queue": "^0.1.0" - } - }, - "p-locate": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", - "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", - "requires": { - "p-limit": "^3.0.2" - } - }, - "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 - }, - "parent-module": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", - "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", - "requires": { - "callsites": "^3.0.0" - } - }, - "parse-json": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz", - "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.0.0", - "error-ex": "^1.3.1", - "json-parse-even-better-errors": "^2.3.0", - "lines-and-columns": "^1.1.6" - } - }, - "parse5": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.1.tgz", - "integrity": "sha512-kwpuwzB+px5WUg9pyK0IcK/shltJN5/OVhQagxhCQNtT9Y9QRZqNY2e1cmbu/paRh5LMnz/oVTVLBpjFmMZhSg==", - "dev": true, - "requires": { - "entities": "^4.4.0" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==" - }, - "path-exists": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", - "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==" - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==" - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==" - }, - "path-parse": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", - "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", - "dev": true - }, - "path-to-regexp": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", - "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", - "dev": true - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "optional": true - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==", - "dev": true - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "optional": true - }, - "pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", - "dev": true - }, - "pkg-dir": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", - "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", - "dev": true, - "requires": { - "find-up": "^4.0.0" - }, - "dependencies": { - "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" - } - }, - "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" - } - } - } - }, - "playwright": { - "version": "1.27.1", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.27.1.tgz", - "integrity": "sha512-xXYZ7m36yTtC+oFgqH0eTgullGztKSRMb4yuwLPl8IYSmgBM88QiB+3IWb1mRIC9/NNwcgbG0RwtFlg+EAFQHQ==", - "dev": true, - "requires": { - "playwright-core": "1.27.1" - } - }, - "playwright-core": { - "version": "1.27.1", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.27.1.tgz", - "integrity": "sha512-9EmeXDncC2Pmp/z+teoVYlvmPWUC6ejSSYZUln7YaP89Z6lpAaiaAnqroUt/BoLo8tn7WYShcfaCh+xofZa44Q==", - "dev": true - }, - "postcss": { - "version": "8.4.18", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.18.tgz", - "integrity": "sha512-Wi8mWhncLJm11GATDaQKobXSNEYGUHeQLiQqDFG1qQ5UTDPTEvKw0Xt5NsTpktGTwLps3ByrWsBrG0rB8YQ9oA==", - "dev": true, - "requires": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - } - }, - "postcss-media-query-parser": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz", - "integrity": "sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==", - "dev": true - }, - "postcss-resolve-nested-selector": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/postcss-resolve-nested-selector/-/postcss-resolve-nested-selector-0.1.1.tgz", - "integrity": "sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==", - "dev": true - }, - "postcss-safe-parser": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-6.0.0.tgz", - "integrity": "sha512-FARHN8pwH+WiS2OPCxJI8FuRJpTVnn6ZNFiqAM2aeW2LwTHWWmWgIyKC6cUo0L8aeKiF/14MNvnpls6R2PBeMQ==", - "dev": true, - "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==", - "dev": true, - "requires": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - } - }, - "postcss-value-parser": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz", - "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", - "dev": true - }, - "prelude-ls": { - "version": "1.2.1", - "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==", - "dev": true - }, - "prettier-linter-helpers": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/prettier-linter-helpers/-/prettier-linter-helpers-1.0.0.tgz", - "integrity": "sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==", - "dev": true, - "requires": { - "fast-diff": "^1.1.2" - } - }, - "pretty-format": { - "version": "29.2.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.2.1.tgz", - "integrity": "sha512-Y41Sa4aLCtKAXvwuIpTvcFBkyeYp2gdFWzXGA+ZNES3VwURIB165XO/z7CjETwzCCS53MjW/rLMyyqEnTtaOfA==", - "dev": true, - "requires": { - "@jest/schemas": "^29.0.0", - "ansi-styles": "^5.0.0", - "react-is": "^18.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz", - "integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==", - "dev": true - } - } - }, - "pretty-quick": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/pretty-quick/-/pretty-quick-3.1.3.tgz", - "integrity": "sha512-kOCi2FJabvuh1as9enxYmrnBC6tVMoVOenMaBqRfsvBHB0cbpYHjdQEpSglpASDFEXVwplpcGR4CLEaisYAFcA==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "execa": "^4.0.0", - "find-up": "^4.1.0", - "ignore": "^5.1.4", - "mri": "^1.1.5", - "multimatch": "^4.0.0" - }, - "dependencies": { - "chalk": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", - "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", - "dev": true, - "requires": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - } - }, - "execa": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-4.1.0.tgz", - "integrity": "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.0", - "get-stream": "^5.0.0", - "human-signals": "^1.1.1", - "is-stream": "^2.0.0", - "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.0", - "onetime": "^5.1.0", - "signal-exit": "^3.0.2", - "strip-final-newline": "^2.0.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" - } - }, - "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", - "integrity": "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==", - "dev": true - }, - "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" - } - } - } - }, - "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 - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "optional": true - }, - "prompts": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.2.tgz", - "integrity": "sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==", - "dev": true, - "requires": { - "kleur": "^3.0.3", - "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", - "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "requires": { - "forwarded": "0.2.0", - "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", - "integrity": "sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==", - "dev": true - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "devOptional": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" - }, - "qs": { - "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" - } - }, - "querystringify": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", - "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "dev": true - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "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 - }, - "range_check": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/range_check/-/range_check-2.0.4.tgz", - "integrity": "sha512-aed0ocXXj+SIiNNN9b+mZWA3Ow2GXHtftOGk2xQwshK5GbEZAvUcPWNQBLTx/lPcdFRIUFlFCRtHTQNIFMqynQ==", - "requires": { - "ip6": "^0.2.0", - "ipaddr.js": "^1.9.1" - } - }, - "range-parser": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", - "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==" - }, - "raw-body": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", - "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } - } - }, - "react-is": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", - "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==", - "dev": true - }, - "read-pkg": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", - "integrity": "sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==", - "dev": true, - "requires": { - "@types/normalize-package-data": "^2.4.0", - "normalize-package-data": "^2.5.0", - "parse-json": "^5.0.0", - "type-fest": "^0.6.0" - }, - "dependencies": { - "hosted-git-info": { - "version": "2.8.9", - "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.8.9.tgz", - "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==", - "dev": true - }, - "normalize-package-data": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", - "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", - "dev": true, - "requires": { - "hosted-git-info": "^2.1.4", - "resolve": "^1.10.0", - "semver": "2 || 3 || 4 || 5", - "validate-npm-package-license": "^3.0.1" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "type-fest": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.6.0.tgz", - "integrity": "sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==", - "dev": true - } - } - }, - "read-pkg-up": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-7.0.1.tgz", - "integrity": "sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==", - "dev": true, - "requires": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "dependencies": { - "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" - } - }, - "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" - } - }, - "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 - } - } - }, - "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", - "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", - "dev": true, - "requires": { - "indent-string": "^4.0.0", - "strip-indent": "^3.0.0" - } - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==" - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==", - "dev": true - }, - "require-from-string": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", - "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true - }, - "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "dev": true, - "requires": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-cwd": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", - "integrity": "sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==", - "dev": true, - "requires": { - "resolve-from": "^5.0.0" + "stylelint-config-recommended": "^14.0.0" }, - "dependencies": { - "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 - } - } - }, - "resolve-from": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", - "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==" - }, - "resolve.exports": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", - "integrity": "sha512-J1l+Zxxp4XK3LUDZ9m60LRJF/mAe4z6a4xyabPHk7pvK5t35dACV32iIjJDFeWZFfZlO29w6SZ67knR0tHzJtQ==", - "dev": true - }, - "responselike": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-1.0.2.tgz", - "integrity": "sha512-/Fpe5guzJk1gPqdJLJR5u7eG/gNY4nImjbRDaVWVMRhne55TCmj2i9Q+54PBRfatRC8v/rIiv9BN0pMd9OV5EQ==", - "optional": true, - "requires": { - "lowercase-keys": "^1.0.0" - } - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==" - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "requires": { - "glob": "^7.1.3" - } - }, - "roarr": { - "version": "2.15.4", - "resolved": "https://registry.npmjs.org/roarr/-/roarr-2.15.4.tgz", - "integrity": "sha512-CHhPh+UNHD2GTXNYhPWLnU8ONHdI+5DI+4EYIAOaiD63rHeYlZvyh8P+in5999TTSFgUYuKUAjzRI4mdh/p+2A==", - "optional": true, - "requires": { - "boolean": "^3.0.1", - "detect-node": "^2.0.4", - "globalthis": "^1.0.1", - "json-stringify-safe": "^5.0.1", - "semver-compare": "^1.0.0", - "sprintf-js": "^1.1.2" - } - }, - "rrule": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/rrule/-/rrule-2.6.4.tgz", - "integrity": "sha512-sLdnh4lmjUqq8liFiOUXD5kWp/FcnbDLPwq5YAc/RrN6120XOPb86Ae5zxF7ttBVq8O3LxjjORMEit1baluahA==", - "requires": { - "luxon": "^1.21.3", - "tslib": "^1.10.0" - } - }, - "run-parallel": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", - "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==", - "requires": { - "queue-microtask": "^1.2.2" + "engines": { + "node": ">=18.12.0" + }, + "peerDependencies": { + "stylelint": "^16.1.0" } }, - "safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==" - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "saxes": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-6.0.0.tgz", - "integrity": "sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==", + "node_modules/stylelint-prettier": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/stylelint-prettier/-/stylelint-prettier-5.0.0.tgz", + "integrity": "sha512-RHfSlRJIsaVg5Br94gZVdWlz/rBTyQzZflNE6dXvSxt/GthWMY3gEHsWZEBaVGg7GM+XrtVSp4RznFlB7i0oyw==", "dev": true, - "requires": { - "xmlchars": "^2.2.0" - } - }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "devOptional": true - }, - "semver-compare": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", - "integrity": "sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==", - "optional": true - }, - "send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "requires": { - "debug": "2.6.9", - "depd": "2.0.0", - "destroy": "1.2.0", - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "etag": "~1.8.1", - "fresh": "0.5.2", - "http-errors": "2.0.0", - "mime": "1.6.0", - "ms": "2.1.3", - "on-finished": "2.4.1", - "range-parser": "~1.2.1", - "statuses": "2.0.1" - }, + "license": "MIT", "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" - } - } - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" - } - } - }, - "serialize-error": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-7.0.1.tgz", - "integrity": "sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==", - "optional": true, - "requires": { - "type-fest": "^0.13.1" + "prettier-linter-helpers": "^1.0.0" }, - "dependencies": { - "type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "optional": true - } - } - }, - "serve-static": { - "version": "1.15.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", - "integrity": "sha512-XGuRDNjXUijsUL0vl6nSD7cwURuzEgglbOaFuZM9g3kwDXOWVTck0jLzjPzGD+TazWbboZYu52/9/XPdUgne9g==", - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" + "engines": { + "node": ">=18.12.0" + }, + "peerDependencies": { + "prettier": ">=3.0.0", + "stylelint": ">=16.0.0" } }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==" - }, - "shebang-command": { + "node_modules/stylelint/node_modules/balanced-match": { "version": "2.0.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", - "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", - "requires": { - "shebang-regex": "^3.0.0" - } - }, - "shebang-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", - "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==" - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "requires": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - } - }, - "signal-exit": { - "version": "3.0.7", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz", - "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==", - "dev": true - }, - "sinon": { - "version": "14.0.1", - "resolved": "https://registry.npmjs.org/sinon/-/sinon-14.0.1.tgz", - "integrity": "sha512-JhJ0jCiyBWVAHDS+YSjgEbDn7Wgz9iIjA1/RK+eseJN0vAAWIWiXBdrnb92ELPyjsfreCYntD1ORtLSfIrlvSQ==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.8.3", - "@sinonjs/fake-timers": "^9.1.2", - "@sinonjs/samsam": "^6.1.1", - "diff": "^5.0.0", - "nise": "^5.1.1", - "supports-color": "^7.2.0" - } - }, - "sisteransi": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", - "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", - "dev": true - }, - "slash": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", - "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==", - "dev": true - }, - "slice-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", - "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", + "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - }, - "socket.io": { - "version": "4.5.3", - "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.3.tgz", - "integrity": "sha512-zdpnnKU+H6mOp7nYRXH4GNv1ux6HL6+lHL8g7Ds7Lj8CkdK1jJK/dlwsKDculbyOHifcJ0Pr/yeXnZQ5GeFrcg==", - "requires": { - "accepts": "~1.3.4", - "base64id": "~2.0.0", - "debug": "~4.3.2", - "engine.io": "~6.2.0", - "socket.io-adapter": "~2.4.0", - "socket.io-parser": "~4.2.0" - } - }, - "socket.io-adapter": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-2.4.0.tgz", - "integrity": "sha512-W4N+o69rkMEGVuk2D/cvca3uYsvGlMwsySWV447y99gUPghxq42BxqLNMndb+a1mm/5/7NeXVQS7RLa2XyXvYg==" - }, - "socket.io-parser": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-4.2.1.tgz", - "integrity": "sha512-V4GrkLy+HeF1F/en3SpUaM+7XxYXpuMUWLGde1kSSh5nQMN4hLrbPIkD+otwh6q9R6NOQBN4AMaOZ2zVjui82g==", - "requires": { - "@socket.io/component-emitter": "~3.1.0", - "debug": "~4.3.1" - } - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true + "license": "MIT" }, - "source-map-js": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.0.2.tgz", - "integrity": "sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==", - "dev": true - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", + "node_modules/stylelint/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } + "license": "MIT" }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "node_modules/stylelint/node_modules/file-entry-cache": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-9.0.0.tgz", + "integrity": "sha512-6MgEugi8p2tiUhqO7GnPsmbCCzj0YRCwwaTbpGRyKZesjRSzkqkAE9fPp7V2yMs5hwfgbQLgdvSSkGNg1s5Uvw==", "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" + "license": "MIT", + "dependencies": { + "flat-cache": "^5.0.0" + }, + "engines": { + "node": ">=18" } }, - "spdx-exceptions": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz", - "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==", - "dev": true - }, - "spdx-expression-parse": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", - "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "node_modules/stylelint/node_modules/flat-cache": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-5.0.0.tgz", + "integrity": "sha512-JrqFmyUl2PnPi1OvLyTVHnQvwQ0S+e6lGSwu8OkAZlSaNIZciTY2H/cOOROxsBA1m/LZNHDsqAgDZt6akWcjsQ==", "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" + "license": "MIT", + "dependencies": { + "flatted": "^3.3.1", + "keyv": "^4.5.4" + }, + "engines": { + "node": ">=18" } }, - "spdx-license-ids": { - "version": "3.0.12", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.12.tgz", - "integrity": "sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==", - "dev": true - }, - "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "optional": true - }, - "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==", + "node_modules/stylelint/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", "dev": true, - "requires": { - "escape-string-regexp": "^2.0.0" - }, - "dependencies": { - "escape-string-regexp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", - "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", - "dev": true - } + "license": "MIT", + "engines": { + "node": ">=8" } }, - "statuses": { - "version": "2.0.1", - "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 - } + "node_modules/stylelint/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, + "license": "MIT", + "engines": { + "node": ">=8" } }, - "string-length": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", - "integrity": "sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==", + "node_modules/stylelint/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" + "license": "ISC", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } }, - "string-width": { + "node_modules/stylelint/node_modules/string-width": { "version": "4.2.3", "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "strip-ansi": { + "node_modules/stylelint/node_modules/string-width/node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "requires": { - "ansi-regex": "^5.0.1" - } - }, - "strip-bom": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", - "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", - "dev": true - }, - "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", - "dev": true - }, - "strip-indent": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", - "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", "dev": true, - "requires": { - "min-indent": "^1.0.0" + "license": "MIT", + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" } }, - "strip-json-comments": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", - "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==" - }, - "style-search": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", - "integrity": "sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==", - "dev": true - }, - "stylelint": { - "version": "14.14.0", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.14.0.tgz", - "integrity": "sha512-yUI+4xXfPHVnueYddSQ/e1GuEA/2wVhWQbGj16AmWLtQJtn28lVxfS4b0CsWyVRPgd3Auzi0NXOthIEUhtQmmA==", + "node_modules/stylelint/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", "dev": true, - "requires": { - "@csstools/selector-specificity": "^2.0.2", - "balanced-match": "^2.0.0", - "colord": "^2.9.3", - "cosmiconfig": "^7.0.1", - "css-functions-list": "^3.1.0", - "debug": "^4.3.4", - "fast-glob": "^3.2.12", - "fastest-levenshtein": "^1.0.16", - "file-entry-cache": "^6.0.1", - "global-modules": "^2.0.0", - "globby": "^11.1.0", - "globjoin": "^0.1.4", - "html-tags": "^3.2.0", - "ignore": "^5.2.0", - "import-lazy": "^4.0.0", - "imurmurhash": "^0.1.4", - "is-plain-object": "^5.0.0", - "known-css-properties": "^0.25.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.17", - "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-value-parser": "^4.2.0", - "resolve-from": "^5.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "style-search": "^0.1.0", - "supports-hyperlinks": "^2.3.0", - "svg-tags": "^1.0.0", - "table": "^6.8.0", - "v8-compile-cache": "^2.3.0", - "write-file-atomic": "^4.0.2" - }, + "license": "MIT", "dependencies": { - "balanced-match": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-2.0.0.tgz", - "integrity": "sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==", - "dev": true - }, - "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 - } + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "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==", - "dev": true, - "requires": {} - }, - "stylelint-config-recommended": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-9.0.0.tgz", - "integrity": "sha512-9YQSrJq4NvvRuTbzDsWX3rrFOzOlYBmZP+o513BJN/yfEmGSr0AxdvrWs0P/ilSpVV/wisamAHu5XSk8Rcf4CQ==", - "dev": true, - "requires": {} - }, - "stylelint-config-standard": { - "version": "29.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-29.0.0.tgz", - "integrity": "sha512-uy8tZLbfq6ZrXy4JKu3W+7lYLgRQBxYTUUB88vPgQ+ZzAxdrvcaSUW9hOMNLYBnwH+9Kkj19M2DHdZ4gKwI7tg==", + "node_modules/stylelint/node_modules/strip-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", "dev": true, - "requires": { - "stylelint-config-recommended": "^9.0.0" + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" } }, - "stylelint-prettier": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/stylelint-prettier/-/stylelint-prettier-2.0.0.tgz", - "integrity": "sha512-jvT3G+9lopkeB0ARmDPszyfaOnvnIF+30QCjZxyt7E6fynI1T9mOKgYDNb9bXX17M7PXMZaX3j/26wqakjp1tw==", + "node_modules/stylelint/node_modules/write-file-atomic": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-5.0.1.tgz", + "integrity": "sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==", "dev": true, - "requires": { - "prettier-linter-helpers": "^1.0.0" + "license": "ISC", + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, - "sumchecker": { + "node_modules/sumchecker": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", + "license": "Apache-2.0", "optional": true, - "requires": { + "dependencies": { "debug": "^4.1.0" + }, + "engines": { + "node": ">= 8.0" } }, - "suncalc": { + "node_modules/suncalc": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/suncalc/-/suncalc-1.9.0.tgz", - "integrity": "sha512-vMJ8Byp1uIPoj+wb9c1AdK4jpkSKVAywgHX0lqY7zt6+EWRRC3Z+0Ucfjy/0yxTVO1hwwchZe4uoFNqrIC24+A==", - "dev": true + "integrity": "sha512-vMJ8Byp1uIPoj+wb9c1AdK4jpkSKVAywgHX0lqY7zt6+EWRRC3Z+0Ucfjy/0yxTVO1hwwchZe4uoFNqrIC24+A==" }, - "supports-color": { + "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "requires": { + "license": "MIT", + "dependencies": { "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" } }, - "supports-hyperlinks": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz", - "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==", + "node_modules/supports-hyperlinks": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.0.0.tgz", + "integrity": "sha512-QBDPHyPQDRTy9ku4URNGY5Lah8PAaXs6tAAwp55sL5WCsSW7GIfdf6W5ixfziW+t7wh3GVvHyHHyQ1ESsoRvaA==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "has-flag": "^4.0.0", "supports-color": "^7.0.0" + }, + "engines": { + "node": ">=14.18" } }, - "supports-preserve-symlinks-flag": { + "node_modules/supports-preserve-symlinks-flag": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", - "dev": true + "license": "MIT", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "svg-tags": { + "node_modules/svg-tags": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", "integrity": "sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==", "dev": true }, - "symbol-tree": { + "node_modules/symbol-tree": { "version": "3.2.4", "resolved": "https://registry.npmjs.org/symbol-tree/-/symbol-tree-3.2.4.tgz", "integrity": "sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw==", - "dev": true + "dev": true, + "license": "MIT" + }, + "node_modules/systeminformation": { + "version": "5.22.11", + "resolved": "https://registry.npmjs.org/systeminformation/-/systeminformation-5.22.11.tgz", + "integrity": "sha512-aLws5yi4KCHTb0BVvbodQY5bY8eW4asMRDTxTW46hqw9lGjACX6TlLdJrkdoHYRB0qs+MekqEq1zG7WDnWE8Ug==", + "license": "MIT", + "os": [ + "darwin", + "linux", + "win32", + "freebsd", + "openbsd", + "netbsd", + "sunos", + "android" + ], + "bin": { + "systeminformation": "lib/cli.js" + }, + "engines": { + "node": ">=8.0.0" + }, + "funding": { + "type": "Buy me a coffee", + "url": "https://www.buymeacoffee.com/systeminfo" + } }, - "table": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", + "node_modules/table": { + "version": "6.8.2", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.2.tgz", + "integrity": "sha512-w2sfv80nrAh2VCbqR5AK27wswXhqcck2AhfnNW76beQXskGZ1V12GwS//yYVa3d3fcvAip2OUnbDAjW2k3v9fA==", "dev": true, - "requires": { + "license": "BSD-3-Clause", + "dependencies": { "ajv": "^8.0.1", "lodash.truncate": "^4.4.2", "slice-ansi": "^4.0.0", "string-width": "^4.2.3", "strip-ansi": "^6.0.1" }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/table/node_modules/ajv": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.16.0.tgz", + "integrity": "sha512-F0twR8U1ZU67JIEtekUcLkXkoO5mMMmgGD8sK/xUFzJ805jxHQl92hImFAqqXMyMYjSPOyUPAwHYhB72g5sTXw==", + "dev": true, + "license": "MIT", "dependencies": { - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } - }, - "json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - } + "fast-deep-equal": "^3.1.3", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.4.1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/table/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/table/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "dev": true, + "license": "MIT" + }, + "node_modules/table/node_modules/slice-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-4.0.0.tgz", + "integrity": "sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/table/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" } }, - "test-exclude": { + "node_modules/test-exclude": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-6.0.0.tgz", "integrity": "sha512-cAGWPIyOHU6zlmg88jwm7VRyXnMN7iV68OGAbYDk/Mh/xC/pzVPlQtY6ngoIH/5/tciuhGfvESU8GrHrcxD56w==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "@istanbuljs/schema": "^0.1.2", "glob": "^7.1.4", "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/test-exclude/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "license": "MIT", + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/test-exclude/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "license": "ISC", + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" } }, - "text-table": { + "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==" + "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==", + "license": "MIT" }, - "tmpl": { + "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true + "dev": true, + "license": "BSD-3-Clause" }, - "to-fast-properties": { + "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", "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 + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } }, - "to-regex-range": { + "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, - "requires": { + "license": "MIT", + "dependencies": { "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" } }, - "toidentifier": { + "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==" + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "license": "MIT", + "engines": { + "node": ">=0.6" + } }, - "tough-cookie": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", - "integrity": "sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==", + "node_modules/tough-cookie": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.4.tgz", + "integrity": "sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==", "dev": true, - "requires": { + "license": "BSD-3-Clause", + "dependencies": { "psl": "^1.1.33", "punycode": "^2.1.1", "universalify": "^0.2.0", "url-parse": "^1.5.3" }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie/node_modules/universalify": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", + "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/tr46": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-5.0.0.tgz", + "integrity": "sha512-tk2G5R2KRwBd+ZN0zaEXpmzdKyOYksXwywulIX95MBODjSzMIuQnQ3m8JxgbhnL1LeVo7lqQKsYa1O3Htl7K5g==", + "dev": true, + "license": "MIT", "dependencies": { - "universalify": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.2.0.tgz", - "integrity": "sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==", - "dev": true - } + "punycode": "^2.3.1" + }, + "engines": { + "node": ">=18" } }, - "tr46": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", - "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", + "node_modules/ts-api-utils": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.3.0.tgz", + "integrity": "sha512-UQMIo7pb8WRomKR1/+MFVLTroIvDVtMX3K6OUir8ynLyzB8Jeriont2bTAtmNPa1ekAgN7YPDyf6V+ygrdU+eQ==", "dev": true, - "requires": { - "punycode": "^2.1.1" + "license": "MIT", + "engines": { + "node": ">=16" + }, + "peerDependencies": { + "typescript": ">=4.2.0" } }, - "trim-newlines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", - "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", - "dev": true + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "license": "MIT", + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } }, - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "license": "MIT", + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "node_modules/tsconfig-paths/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", "dev": true, - "requires": { - "tslib": "^1.8.1" + "license": "MIT", + "engines": { + "node": ">=4" } }, - "tunnel": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/tunnel/-/tunnel-0.0.6.tgz", - "integrity": "sha512-1h/Lnq9yajKY2PEbBadPXj3VxsDDu844OnaAo52UVmIzIvwwtBPIuNvkjuzBlTWpfJyUbG3ez0KSBibQkj4ojg==", - "optional": true + "node_modules/tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "license": "Apache-2.0" + }, + "node_modules/tv4": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/tv4/-/tv4-1.3.0.tgz", + "integrity": "sha512-afizzfpJgvPr+eDkREK4MxJ/+r8nEEHcmitwgnPUqpaP+FpwQyadnxNoSACbgc/b1LsZYtODGoPiFxQrgJgjvw==", + "license": [ + { + "type": "Public Domain", + "url": "http://geraintluff.github.io/tv4/LICENSE.txt" + }, + { + "type": "MIT", + "url": "http://jsonary.com/LICENSE.txt" + } + ], + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/tx2": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tx2/-/tx2-1.0.5.tgz", + "integrity": "sha512-sJ24w0y03Md/bxzK4FU8J8JveYYUbSs2FViLJ2D/8bytSiyPRbuE3DyL/9UKYXTZlV3yXq0L8GLlhobTnekCVg==", + "license": "MIT", + "optional": true, + "dependencies": { + "json-stringify-safe": "^5.0.1" + } }, - "type-check": { + "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "requires": { + "license": "MIT", + "dependencies": { "prelude-ls": "^1.2.1" + }, + "engines": { + "node": ">= 0.8.0" } }, - "type-detect": { + "node_modules/type-detect": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", - "dev": true + "dev": true, + "license": "MIT", + "engines": { + "node": ">=4" + } }, - "type-fest": { + "node_modules/type-fest": { "version": "0.20.2", "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "license": "(MIT OR CC0-1.0)", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "type-is": { + "node_modules/type-is": { "version": "1.6.18", "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "requires": { + "license": "MIT", + "dependencies": { "media-typer": "0.3.0", "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" } }, - "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/typed-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.2.tgz", + "integrity": "sha512-gEymJYKZtKXzzBzM4jqa9w6Q1Jjm7x2d+sh19AdsD4wqnMPDYyvwpsIc2Q/835kHuo3BEQ7CjelGhfTsoBb2MQ==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "es-errors": "^1.3.0", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.1.tgz", + "integrity": "sha512-3iMJ9q0ao7WE9tWcaYKIptkNBuOIcZCCT0d4MRvuuH88fEoEH62IuQe0OtraD3ebQEoTRk8XCBoknUNc1Y67pw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.2.tgz", + "integrity": "sha512-Ous0vodHa56FviZucS2E63zkgtgrACj7omjwd/8lTEMEPFFyjfixMZ1ZXenpgCFBBt4EC1J2XsyVS2gkG0eTFA==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.6.tgz", + "integrity": "sha512-/OxDN6OtAk5KBpGb28T+HZc2M+ADtvRxXrKKbUwtsLgdoxgX13hyy7ek6bFRl5+aBs2yZzB0c4CnQfAtVypW/g==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-proto": "^1.0.3", + "is-typed-array": "^1.1.13", + "possible-typed-array-names": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "node_modules/typescript": { + "version": "5.4.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.4.5.tgz", + "integrity": "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ==", "dev": true, - "peer": true + "license": "Apache-2.0", + "peer": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=14.17" + } + }, + "node_modules/uglify-js": { + "version": "3.18.0", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.18.0.tgz", + "integrity": "sha512-SyVVbcNBCk0dzr9XL/R/ySrmYf0s372K6/hFklzgcp2lBFyXtw4I7BOdDjlLhE1aVqaI/SHWXWmYdlZxuyF38A==", + "license": "BSD-2-Clause", + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "license": "MIT", + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "license": "MIT" }, - "universalify": { + "node_modules/universalify": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "optional": true + "license": "MIT", + "optional": true, + "engines": { + "node": ">= 4.0.0" + } }, - "unpipe": { + "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==" + "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } }, - "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==", + "node_modules/update-browserslist-db": { + "version": "1.0.16", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.16.tgz", + "integrity": "sha512-KVbTxlBYlckhF5wgfyZXTWnMn7MMZjMu9XG8bPlliUOP9ThaF4QnhP8qrjrH7DRzHfSk0oQv1wToW+iA5GajEQ==", "dev": true, - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], + "license": "MIT", + "dependencies": { + "escalade": "^3.1.2", + "picocolors": "^1.0.1" + }, + "bin": { + "update-browserslist-db": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" } }, - "uri-js": { + "node_modules/uri-js": { "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "requires": { + "license": "BSD-2-Clause", + "dependencies": { "punycode": "^2.1.0" } }, - "url-parse": { + "node_modules/url-parse": { "version": "1.5.10", "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "querystringify": "^2.1.1", "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": { + "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, + "license": "MIT" }, - "utils-merge": { + "node_modules/utils-merge": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==" - }, - "uuid": { - "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", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz", - "integrity": "sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==", - "dev": true + "integrity": "sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA==", + "license": "MIT", + "engines": { + "node": ">= 0.4.0" + } }, - "v8-to-istanbul": { + "node_modules/uuid": { "version": "9.0.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.0.1.tgz", - "integrity": "sha512-74Y4LqY74kLE6IFyIjPtkSTWzUZmj8tdHT9Ii/26dvQ6K9Dl2NbEfj0XgU2sHCtKgt5VupqhlO/5aWuqS+IY1w==", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/v8-to-istanbul": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-9.2.0.tgz", + "integrity": "sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "@jridgewell/trace-mapping": "^0.3.12", "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0" + "convert-source-map": "^2.0.0" + }, + "engines": { + "node": ">=10.12.0" } }, - "validate-npm-package-license": { + "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", "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", "dev": true, - "requires": { + "license": "Apache-2.0", + "dependencies": { "spdx-correct": "^3.0.0", "spdx-expression-parse": "^3.0.0" } }, - "vary": { + "node_modules/validate-npm-package-license/node_modules/spdx-expression-parse": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz", + "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==", + "dev": true, + "license": "MIT", + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/validate-npm-package-name": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz", + "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==", + "dev": true, + "license": "ISC", + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==" + "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", + "license": "MIT", + "engines": { + "node": ">= 0.8" + } }, - "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==", + "node_modules/vizion": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vizion/-/vizion-2.2.1.tgz", + "integrity": "sha512-sfAcO2yeSU0CSPFI/DmZp3FsFE9T+8913nv1xWBOyzODv13fwkn6Vl7HqxGpkr9F608M+8SuFId3s+BlZqfXww==", + "license": "Apache-2.0", + "dependencies": { + "async": "^2.6.3", + "git-node-fs": "^1.0.0", + "ini": "^1.3.5", + "js-git": "^0.7.8" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/vizion/node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "license": "MIT", + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-5.0.0.tgz", + "integrity": "sha512-o8qghlI8NZHU1lLPrpi2+Uq7abh4GGPpYANlalzWxyWteJOCsr/P+oPBA49TOLu5FTZO4d3F9MnWJfiMo4BkmA==", "dev": true, - "requires": { - "xml-name-validator": "^4.0.0" + "license": "MIT", + "dependencies": { + "xml-name-validator": "^5.0.0" + }, + "engines": { + "node": ">=18" } }, - "walker": { + "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, - "requires": { + "license": "Apache-2.0", + "dependencies": { "makeerror": "1.0.12" } }, - "webidl-conversions": { + "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==", - "dev": true + "dev": true, + "license": "BSD-2-Clause", + "engines": { + "node": ">=12" + } }, - "whatwg-encoding": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", - "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" } }, - "whatwg-mimetype": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-3.0.0.tgz", - "integrity": "sha512-nt+N2dzIutVRxARx1nghPKGv1xHikU7HKdfafKkLNLindmPU/ch3U31NOCGGA/dmPcmb1VlofO0vnKAcsm0o/Q==", - "dev": true + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=18" + } }, - "whatwg-url": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", - "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", + "node_modules/whatwg-url": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-14.0.0.tgz", + "integrity": "sha512-1lfMEm2IEr7RIV+f4lUNPOqfFL+pO+Xw3fJSqmjX9AbXcXcYOkCe1P6+9VBZB6n94af16NfZf+sSk0JCBZC9aw==", "dev": true, - "requires": { - "tr46": "^3.0.0", + "license": "MIT", + "dependencies": { + "tr46": "^5.0.0", "webidl-conversions": "^7.0.0" + }, + "engines": { + "node": ">=18" } }, - "which": { + "node_modules/which": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "requires": { + "license": "ISC", + "dependencies": { "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" } }, - "word-wrap": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", - "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "license": "MIT", + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } }, - "wrap-ansi": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "node_modules/which-typed-array": { + "version": "1.1.15", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.15.tgz", + "integrity": "sha512-oV0jmFtUky6CXfkqehVvBP/LSWJ2sy4vWMioiENyJLePrBO/yKyV9OyJySfAKosh+RYkIl5zJCNZ8/4JncrpdA==", + "license": "MIT", + "dependencies": { + "available-typed-arrays": "^1.0.7", + "call-bind": "^1.0.7", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/word-wrap": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz", + "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "license": "MIT" + }, + "node_modules/wrap-ansi": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.0.tgz", + "integrity": "sha512-G8ura3S+3Z2G+mkgNRq8dqaFZAuxfsxpBB8OCTGRTCtp+l/v9nbFNmCUP1BZMts3G1142MsZfn6eeUKrr4PD1Q==", "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" + "license": "MIT", + "dependencies": { + "ansi-styles": "^6.2.1", + "string-width": "^7.0.0", + "strip-ansi": "^7.1.0" + }, + "engines": { + "node": ">=18" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "license": "MIT", + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" } }, - "wrappy": { + "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "license": "ISC" }, - "write-file-atomic": { + "node_modules/write-file-atomic": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.2.tgz", "integrity": "sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==", "dev": true, - "requires": { + "license": "ISC", + "dependencies": { "imurmurhash": "^0.1.4", "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" } }, - "ws": { - "version": "8.9.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.9.0.tgz", - "integrity": "sha512-Ja7nszREasGaYUYCI2k4lCKIRTt+y7XuqVoHR44YpI49TtryyqbqvDMn5eqfW7e6HzTukDRIsXqzVHScqRcafg==", - "dev": true, - "requires": {} + "node_modules/ws": { + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.17.1.tgz", + "integrity": "sha512-6XQFvXTkbfUOZOKKILFG1PDK2NDQs4azKQl26T0YS5CxqWLgXajbPZ+h4gZekJyRqFU8pvnbAbbs/3TgRPy+GQ==", + "license": "MIT", + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } }, - "xml-name-validator": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-4.0.0.tgz", - "integrity": "sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==", - "dev": true + "node_modules/xml-name-validator": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-5.0.0.tgz", + "integrity": "sha512-EvGK8EJ3DhaHfbRlETOWAS5pO9MZITeauHKJyb8wyajUfQUenkIg2MvLDTZ4T/TgIcm3HU0TFBgWWboAZ30UHg==", + "dev": true, + "license": "Apache-2.0", + "engines": { + "node": ">=18" + } }, - "xmlchars": { + "node_modules/xmlchars": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true + "dev": true, + "license": "MIT" }, - "y18n": { + "node_modules/y18n": { "version": "5.0.8", "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true + "dev": true, + "license": "ISC", + "engines": { + "node": ">=10" + } }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", - "devOptional": true + "node_modules/yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true, + "license": "ISC" }, - "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "dev": true + "node_modules/yaml": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.5.tgz", + "integrity": "sha512-aBx2bnqDzVOyNKfsysjA2ms5ZlnjSAW2eG3/L5G/CSujfjLJTJsEw1bGw8kCf04KodQWk1pxlGnZ56CRxiawmg==", + "dev": true, + "license": "ISC", + "bin": { + "yaml": "bin.mjs" + }, + "engines": { + "node": ">= 14" + } }, - "yargs": { - "version": "17.6.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.0.tgz", - "integrity": "sha512-8H/wTDqlSwoSnScvV2N/JHfLWOKuh5MVla9hqLjK3nsfyy6Y4kDSYSvkU5YCUEPOSnRXfIyx3Sq+B/IWudTo4g==", + "node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", "dev": true, - "requires": { + "license": "MIT", + "dependencies": { "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": { - "version": "21.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", - "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", - "dev": true - } + "engines": { + "node": ">=12" } }, - "yargs-parser": { - "version": "20.2.9", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz", - "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==", - "dev": true + "node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "license": "ISC", + "engines": { + "node": ">=12" + } + }, + "node_modules/yargs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true, + "license": "MIT" + }, + "node_modules/yargs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=8" + } + }, + "node_modules/yargs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "license": "MIT", + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } }, - "yauzl": { + "node_modules/yauzl": { "version": "2.10.0", "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "license": "MIT", "optional": true, - "requires": { + "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } }, - "yocto-queue": { + "node_modules/yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", - "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==" + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "license": "MIT", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } } } } diff --git a/package.json b/package.json index e459ea2fa5..b79a8caa77 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,27 @@ { "name": "magicmirror", - "version": "2.22.0-develop", + "version": "2.28.0-develop", "description": "The open source modular smart mirror platform.", + "keywords": [ + "magic mirror", + "magicmirror", + "smart mirror", + "mirror UI", + "modular" + ], + "homepage": "https://magicmirror.builders", + "bugs": { + "url": "https://github.com/MagicMirrorOrg/MagicMirror/issues" + }, + "repository": { + "type": "git", + "url": "https://github.com/MagicMirrorOrg/MagicMirror" + }, + "license": "MIT", + "author": "Michael Teeuw", + "contributors": [ + "https://github.com/MagicMirrorOrg/MagicMirror/graphs/contributors" + ], "main": "js/electron.js", "scripts": { "start": "DISPLAY=\"${DISPLAY:=:0}\" ./node_modules/.bin/electron js/electron.js", @@ -13,87 +33,72 @@ "install-fonts": "echo \"Installing fonts ...\n\" && cd fonts && npm install --loglevel=error --no-audit --no-fund --no-update-notifier", "postinstall": "npm run install-vendor && npm run install-fonts && echo \"MagicMirror² installation finished successfully! \n\"", "test": "NODE_ENV=test jest -i --forceExit", - "test:coverage": "NODE_ENV=test jest --coverage -i --forceExit", + "test:coverage": "NODE_ENV=test jest --coverage -i --verbose false --forceExit", "test:electron": "NODE_ENV=test jest --selectProjects electron -i --forceExit", "test:e2e": "NODE_ENV=test jest --selectProjects e2e -i --forceExit", - "test:unit": "NODE_ENV=test jest --selectProjects unit -i --forceExit", + "test:unit": "NODE_ENV=test jest --selectProjects unit", "test:prettier": "prettier . --check", - "test:js": "eslint 'js/**/*.js' 'modules/default/**/*.js' 'clientonly/*.js' 'serveronly/*.js' 'translations/*.js' 'vendor/*.js' 'tests/**/*.js' 'config/*' --config .eslintrc.json", + "test:js": "eslint .", "test:css": "stylelint 'css/main.css' 'fonts/*.css' 'modules/default/**/*.css' 'vendor/*.css' --config .stylelintrc.json", "test:calendar": "node ./modules/default/calendar/debug.js", "config:check": "node js/check_config.js", "lint:prettier": "prettier . --write", - "lint:js": "eslint 'js/**/*.js' 'modules/default/**/*.js' 'clientonly/*.js' 'serveronly/*.js' 'translations/*.js' 'vendor/*.js' 'tests/**/*.js' 'config/*' --config .eslintrc.json --fix", + "lint:js": "eslint . --fix", "lint:css": "stylelint 'css/main.css' 'fonts/*.css' 'modules/default/**/*.css' 'vendor/*.css' --config .stylelintrc.json --fix", - "lint:staged": "pretty-quick --staged", - "prepare": "[ -f node_modules/.bin/husky ] && husky install || echo no husky installed." + "lint:staged": "lint-staged", + "prepare": "[ -f node_modules/.bin/husky ] && husky || echo no husky installed." }, - "repository": { - "type": "git", - "url": "git+https://github.com/MichMich/MagicMirror.git" + "lint-staged": { + "*": "prettier --write", + "*.js": "eslint --fix", + "*.css": "stylelint --fix" }, - "keywords": [ - "magic mirror", - "magicmirror", - "smart mirror", - "mirror UI", - "modular" - ], - "author": "Michael Teeuw", - "contributors": [ - "https://github.com/MichMich/MagicMirror/graphs/contributors" - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/MichMich/MagicMirror/issues" + "dependencies": { + "ansis": "^3.2.0", + "console-stamp": "^3.1.2", + "envsub": "^4.1.0", + "eslint": "^8.57.0", + "express": "^4.19.2", + "express-ipfilter": "^1.3.2", + "feedme": "^2.0.2", + "helmet": "^7.1.0", + "html-to-text": "^9.0.5", + "iconv-lite": "^0.6.3", + "module-alias": "^2.2.3", + "moment": "^2.30.1", + "node-ical": "^0.18.0", + "pm2": "^5.4.1", + "socket.io": "^4.7.5", + "suncalc": "^1.9.0", + "systeminformation": "^5.22.11" }, - "homepage": "https://magicmirror.builders", "devDependencies": { - "eslint-config-prettier": "^8.5.0", - "eslint-plugin-jest": "^27.1.3", - "eslint-plugin-jsdoc": "^39.3.25", - "eslint-plugin-prettier": "^4.2.1", + "@stylistic/eslint-plugin": "^1.8.1", + "eslint-plugin-import": "^2.29.1", + "eslint-plugin-jest": "^28.6.0", + "eslint-plugin-jsdoc": "^48.2.12", + "eslint-plugin-package-json": "^0.15.0", + "eslint-plugin-unicorn": "^54.0.0", "express-basic-auth": "^1.2.1", - "husky": "^8.0.1", - "jest": "^29.2.2", - "jsdom": "^20.0.1", - "lodash": "^4.17.21", - "playwright": "^1.27.1", - "prettier": "^2.7.1", - "pretty-quick": "^3.1.3", - "sinon": "^14.0.1", - "stylelint": "^14.14.0", - "stylelint-config-prettier": "^9.0.3", - "stylelint-config-standard": "^29.0.0", - "stylelint-prettier": "^2.0.0", - "suncalc": "^1.9.0" + "husky": "^9.0.11", + "jest": "^29.7.0", + "jsdom": "^24.1.0", + "lint-staged": "^15.2.7", + "playwright": "^1.44.1", + "prettier": "^3.3.2", + "sinon": "^18.0.0", + "stylelint": "^16.6.1", + "stylelint-config-standard": "^36.0.0", + "stylelint-prettier": "^5.0.0" }, "optionalDependencies": { - "electron": "^19.1.3" + "electron": "^31.0.1" }, - "dependencies": { - "colors": "^1.4.0", - "console-stamp": "^3.0.6", - "digest-fetch": "^1.3.0", - "eslint": "^8.26.0", - "express": "^4.18.2", - "express-ipfilter": "^1.3.1", - "feedme": "^2.0.2", - "helmet": "^6.0.0", - "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.2", - "socket.io": "^4.5.3" + "engines": { + "node": ">=20" }, "_moduleAliases": { "node_helper": "js/node_helper.js", - "logger": "js/logger.js", - "fetch": "js/fetch.js" - }, - "engines": { - "node": ">=14" + "logger": "js/logger.js" } } diff --git a/serveronly/index.js b/serveronly/index.js index 00d6b64be3..66632ac105 100644 --- a/serveronly/index.js +++ b/serveronly/index.js @@ -1,8 +1,8 @@ -const app = require("../js/app.js"); -const Log = require("logger"); +const app = require("../js/app"); +const Log = require("../js/logger"); -app.start((config) => { +app.start().then((config) => { const bindAddress = config.address ? config.address : "localhost"; const httpType = config.useHttps ? "https" : "http"; - Log.log("\nReady to go! Please point your browser to: " + httpType + "://" + bindAddress + ":" + config.port); + Log.info(`\n>>> Ready to go! Please point your browser to: ${httpType}://${bindAddress}:${config.port} <<<`); }); diff --git a/tests/configs/default.js b/tests/configs/default.js index 509dfd9860..ba6652068c 100644 --- a/tests/configs/default.js +++ b/tests/configs/default.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test default config for modules - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ exports.configFactory = (options) => { return Object.assign( { diff --git a/tests/configs/empty_ipWhiteList.js b/tests/configs/empty_ipWhiteList.js index d49f7a9f98..8fdfc0e42d 100644 --- a/tests/configs/empty_ipWhiteList.js +++ b/tests/configs/empty_ipWhiteList.js @@ -1,10 +1,6 @@ -/* MagicMirror² Test config sample ipWhitelist - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ - ipWhitelist: [] +let config = require(`${process.cwd()}/tests/configs/default.js`).configFactory({ + ipWhitelist: [], + port: 8282 }); /*************** DO NOT EDIT THE LINE BELOW ***************/ diff --git a/tests/configs/modules/alert/default.js b/tests/configs/modules/alert/default.js index 45ffefe5b2..ea77b574be 100644 --- a/tests/configs/modules/alert/default.js +++ b/tests/configs/modules/alert/default.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config sample module alert - * - * By rejas - * MIT Licensed. - */ let config = { modules: [ { diff --git a/tests/configs/modules/calendar/auth-default.js b/tests/configs/modules/calendar/auth-default.js index 0b2491612f..99ce3922b0 100644 --- a/tests/configs/modules/calendar/auth-default.js +++ b/tests/configs/modules/calendar/auth-default.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config default calendar with auth by default - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ let config = { timeFormat: 12, diff --git a/tests/configs/modules/calendar/bad_rrule.js b/tests/configs/modules/calendar/bad_rrule.js new file mode 100644 index 0000000000..3810794384 --- /dev/null +++ b/tests/configs/modules/calendar/bad_rrule.js @@ -0,0 +1,22 @@ +let config = { + timeFormat: 12, + logLevel: ["INFO", "LOG", "WARN", "ERROR", "DEBUG"], + modules: [ + { + module: "calendar", + position: "bottom_bar", + config: { + calendars: [ + { + url: "http://localhost:8080/tests/mocks/bad_rrule.ics" + } + ] + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/calendar/basic-auth.js b/tests/configs/modules/calendar/basic-auth.js index 5cbebceb2f..f322f573d7 100644 --- a/tests/configs/modules/calendar/basic-auth.js +++ b/tests/configs/modules/calendar/basic-auth.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config default calendar - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ let config = { timeFormat: 12, diff --git a/tests/configs/modules/calendar/changed-port.js b/tests/configs/modules/calendar/changed-port.js index 5027726115..15bf920739 100644 --- a/tests/configs/modules/calendar/changed-port.js +++ b/tests/configs/modules/calendar/changed-port.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config default calendar with auth by default - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ let config = { timeFormat: 12, diff --git a/tests/configs/modules/calendar/custom.js b/tests/configs/modules/calendar/custom.js index 54d117d7a7..8552bcbe5c 100644 --- a/tests/configs/modules/calendar/custom.js +++ b/tests/configs/modules/calendar/custom.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config custom calendar - * - * By Rejas - * MIT Licensed. - */ let config = { timeFormat: 12, @@ -11,9 +6,11 @@ let config = { module: "calendar", position: "bottom_bar", config: { + customEvents: [{ keyword: "CustomEvent", symbol: "dice", eventClass: "undo" }], + forceUseCurrentTime: true, calendars: [ { - maximumEntries: 4, + maximumEntries: 5, maximumNumberOfDays: 10000, symbol: "birthday-cake", fullDaySymbol: "calendar-day", diff --git a/tests/configs/modules/calendar/default.js b/tests/configs/modules/calendar/default.js index 2dee121203..67c943d3c9 100644 --- a/tests/configs/modules/calendar/default.js +++ b/tests/configs/modules/calendar/default.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config default calendar - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ let config = { timeFormat: 12, diff --git a/tests/configs/modules/calendar/exdate_la_at_midnight_dst.js b/tests/configs/modules/calendar/exdate_la_at_midnight_dst.js new file mode 100644 index 0000000000..608c71da96 --- /dev/null +++ b/tests/configs/modules/calendar/exdate_la_at_midnight_dst.js @@ -0,0 +1,37 @@ +/* MagicMirror² Test calendar exdate + * + * By jkriegshauser + * MIT Licensed. + * + * See issue #3250 + * See tests/electron/modules/calendar_spec.js + */ +let config = { + timeFormat: 12, + + modules: [ + { + module: "calendar", + position: "bottom_bar", + config: { + maximumEntries: 100, + calendars: [ + { + maximumEntries: 100, + maximumNumberOfDays: 28, // 4 weeks, 2 of which are skipped + url: "http://localhost:8080/tests/mocks/exdate_la_at_midnight_dst.ics" + } + ] + } + } + ] +}; + +Date.now = () => { + return new Date("19 Oct 2023 12:30:00 GMT-07:00").valueOf(); +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/calendar/exdate_la_at_midnight_std.js b/tests/configs/modules/calendar/exdate_la_at_midnight_std.js new file mode 100644 index 0000000000..6128c97f50 --- /dev/null +++ b/tests/configs/modules/calendar/exdate_la_at_midnight_std.js @@ -0,0 +1,37 @@ +/* MagicMirror² Test calendar exdate + * + * By jkriegshauser + * MIT Licensed. + * + * See issue #3250 + * See tests/electron/modules/calendar_spec.js + */ +let config = { + timeFormat: 12, + + modules: [ + { + module: "calendar", + position: "bottom_bar", + config: { + maximumEntries: 100, + calendars: [ + { + maximumEntries: 100, + maximumNumberOfDays: 28, // 4 weeks, 2 of which are skipped + url: "http://localhost:8080/tests/mocks/exdate_la_at_midnight_std.ics" + } + ] + } + } + ] +}; + +Date.now = () => { + return new Date("19 Oct 2023 12:30:00 GMT-07:00").valueOf(); +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/calendar/exdate_la_before_midnight.js b/tests/configs/modules/calendar/exdate_la_before_midnight.js new file mode 100644 index 0000000000..8c886f775a --- /dev/null +++ b/tests/configs/modules/calendar/exdate_la_before_midnight.js @@ -0,0 +1,37 @@ +/* MagicMirror² Test calendar exdate + * + * By jkriegshauser + * MIT Licensed. + * + * See issue #3250 + * See tests/electron/modules/calendar_spec.js + */ +let config = { + timeFormat: 12, + + modules: [ + { + module: "calendar", + position: "bottom_bar", + config: { + maximumEntries: 100, + calendars: [ + { + maximumEntries: 100, + maximumNumberOfDays: 28, // 4 weeks, 2 of which are skipped + url: "http://localhost:8080/tests/mocks/exdate_la_before_midnight.ics" + } + ] + } + } + ] +}; + +Date.now = () => { + return new Date("19 Oct 2023 12:30:00 GMT-07:00").valueOf(); +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/calendar/exdate_syd_at_midnight_dst.js b/tests/configs/modules/calendar/exdate_syd_at_midnight_dst.js new file mode 100644 index 0000000000..f98b75f4c7 --- /dev/null +++ b/tests/configs/modules/calendar/exdate_syd_at_midnight_dst.js @@ -0,0 +1,37 @@ +/* MagicMirror² Test calendar exdate + * + * By jkriegshauser + * MIT Licensed. + * + * See issue #3250 + * See tests/electron/modules/calendar_spec.js + */ +let config = { + timeFormat: 12, + + modules: [ + { + module: "calendar", + position: "bottom_bar", + config: { + maximumEntries: 100, + calendars: [ + { + maximumEntries: 100, + maximumNumberOfDays: 28, // 4 weeks, 2 of which are skipped + url: "http://localhost:8080/tests/mocks/exdate_syd_at_midnight_dst.ics" + } + ] + } + } + ] +}; + +Date.now = () => { + return new Date("14 Sep 2023 12:30:00 GMT+10:00").valueOf(); +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/calendar/exdate_syd_at_midnight_std.js b/tests/configs/modules/calendar/exdate_syd_at_midnight_std.js new file mode 100644 index 0000000000..06c7ff5319 --- /dev/null +++ b/tests/configs/modules/calendar/exdate_syd_at_midnight_std.js @@ -0,0 +1,37 @@ +/* MagicMirror² Test calendar exdate + * + * By jkriegshauser + * MIT Licensed. + * + * See issue #3250 + * See tests/electron/modules/calendar_spec.js + */ +let config = { + timeFormat: 12, + + modules: [ + { + module: "calendar", + position: "bottom_bar", + config: { + maximumEntries: 100, + calendars: [ + { + maximumEntries: 100, + maximumNumberOfDays: 28, // 4 weeks, 2 of which are skipped + url: "http://localhost:8080/tests/mocks/exdate_syd_at_midnight_std.ics" + } + ] + } + } + ] +}; + +Date.now = () => { + return new Date("14 Sep 2023 12:30:00 GMT+10:00").valueOf(); +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/calendar/exdate_syd_before_midnight.js b/tests/configs/modules/calendar/exdate_syd_before_midnight.js new file mode 100644 index 0000000000..849c1f5363 --- /dev/null +++ b/tests/configs/modules/calendar/exdate_syd_before_midnight.js @@ -0,0 +1,37 @@ +/* MagicMirror² Test calendar exdate + * + * By jkriegshauser + * MIT Licensed. + * + * See issue #3250 + * See tests/electron/modules/calendar_spec.js + */ +let config = { + timeFormat: 12, + + modules: [ + { + module: "calendar", + position: "bottom_bar", + config: { + maximumEntries: 100, + calendars: [ + { + maximumEntries: 100, + maximumNumberOfDays: 28, // 4 weeks, 2 of which are skipped + url: "http://localhost:8080/tests/mocks/exdate_syd_before_midnight.ics" + } + ] + } + } + ] +}; + +Date.now = () => { + return new Date("14 Sep 2023 12:30:00 GMT+10:00").valueOf(); +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/calendar/fail-basic-auth.js b/tests/configs/modules/calendar/fail-basic-auth.js index e0b3ff15ae..2a58d623d6 100644 --- a/tests/configs/modules/calendar/fail-basic-auth.js +++ b/tests/configs/modules/calendar/fail-basic-auth.js @@ -1,10 +1,3 @@ -/* MagicMirror² Test calendar calendar - * - * This configuration is a wrong authentication - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ let config = { timeFormat: 12, diff --git a/tests/configs/modules/calendar/long-fullday-event.js b/tests/configs/modules/calendar/long-fullday-event.js new file mode 100644 index 0000000000..efbc244886 --- /dev/null +++ b/tests/configs/modules/calendar/long-fullday-event.js @@ -0,0 +1,28 @@ +/* MagicMirror² Test config for fullday calendar entries over multiple days + * + * By Paranoid93 https://github.com/Paranoid93/ + * MIT Licensed. + */ +let config = { + timeFormat: 12, + + modules: [ + { + module: "calendar", + position: "bottom_bar", + config: { + calendars: [ + { + maximumNumberOfDays: 2, + url: "http://localhost:8080/tests/mocks/calendar_test_multi_day_starting_today.ics" + } + ] + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/calendar/old-basic-auth.js b/tests/configs/modules/calendar/old-basic-auth.js index 01805e5c8c..08dc407316 100644 --- a/tests/configs/modules/calendar/old-basic-auth.js +++ b/tests/configs/modules/calendar/old-basic-auth.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config default calendar - * with authentication old config - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ let config = { timeFormat: 12, diff --git a/tests/configs/modules/calendar/recurring.js b/tests/configs/modules/calendar/recurring.js index d05cce6c9b..fe1d36629e 100644 --- a/tests/configs/modules/calendar/recurring.js +++ b/tests/configs/modules/calendar/recurring.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config custom calendar - * - * By Rejas - * MIT Licensed. - */ let config = { timeFormat: 12, diff --git a/tests/configs/modules/calendar/rrule_until.js b/tests/configs/modules/calendar/rrule_until.js new file mode 100644 index 0000000000..e553ebd194 --- /dev/null +++ b/tests/configs/modules/calendar/rrule_until.js @@ -0,0 +1,30 @@ +let config = { + timeFormat: 12, + + modules: [ + { + module: "calendar", + position: "bottom_bar", + config: { + hideDuplicates: false, + maximumEntries: 100, + calendars: [ + { + maximumEntries: 100, + maximumNumberOfDays: 1, // Just today + url: "http://localhost:8080/tests/mocks/rrule_until.ics" + } + ] + } + } + ] +}; + +Date.now = () => { + return new Date("07 Mar 2024 10:38:00 GMT-07:00").valueOf(); +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/calendar/show-duplicates-in-calendar.js b/tests/configs/modules/calendar/show-duplicates-in-calendar.js new file mode 100644 index 0000000000..c4a1c95811 --- /dev/null +++ b/tests/configs/modules/calendar/show-duplicates-in-calendar.js @@ -0,0 +1,31 @@ +let config = { + timeFormat: 12, + + modules: [ + { + module: "calendar", + position: "bottom_bar", + config: { + maximumEntries: 30, + hideDuplicates: false, + calendars: [ + { + maximumEntries: 15, + maximumNumberOfDays: 10000, + url: "http://localhost:8080/tests/mocks/calendar_test.ics" // contains 11 events + }, + { + maximumEntries: 15, + maximumNumberOfDays: 10000, + url: "http://localhost:8080/tests/mocks/calendar_test_clone.ics" // clone of upper calendar + } + ] + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/calendar/single-fullday-event.js b/tests/configs/modules/calendar/single-fullday-event.js new file mode 100644 index 0000000000..9149d2d9ab --- /dev/null +++ b/tests/configs/modules/calendar/single-fullday-event.js @@ -0,0 +1,28 @@ +/* MagicMirror² Test config for fullday calendar entries over multiple days + * + * By Paranoid93 https://github.com/Paranoid93/ + * MIT Licensed. + */ +let config = { + timeFormat: 12, + + modules: [ + { + module: "calendar", + position: "bottom_bar", + config: { + calendars: [ + { + maximumNumberOfDays: 2, + url: "http://localhost:8080/tests/mocks/calendar_test_full_day_events.ics" + } + ] + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/clock/clock_12hr.js b/tests/configs/modules/clock/clock_12hr.js index 18170e7c9c..4a7318f58d 100644 --- a/tests/configs/modules/clock/clock_12hr.js +++ b/tests/configs/modules/clock/clock_12hr.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config for default clock module - * - * By Sergey Morozov - * MIT Licensed. - */ let config = { timeFormat: 12, diff --git a/tests/configs/modules/clock/clock_24hr.js b/tests/configs/modules/clock/clock_24hr.js index f9bd451436..f75287eb04 100644 --- a/tests/configs/modules/clock/clock_24hr.js +++ b/tests/configs/modules/clock/clock_24hr.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config for default clock module - * - * By Sergey Morozov - * MIT Licensed. - */ let config = { modules: [ { diff --git a/tests/configs/modules/clock/clock_analog.js b/tests/configs/modules/clock/clock_analog.js index fdca561562..98331ee389 100644 --- a/tests/configs/modules/clock/clock_analog.js +++ b/tests/configs/modules/clock/clock_analog.js @@ -1,7 +1,3 @@ -/* MagicMirror² Test config for analog clock face - * - * MIT Licensed. - */ let config = { modules: [ { @@ -9,7 +5,8 @@ let config = { position: "middle_center", config: { displayType: "analog", - analogFace: "face-006" + analogFace: "face-006", + showDate: false } } ] diff --git a/tests/configs/modules/clock/clock_displaySeconds_false.js b/tests/configs/modules/clock/clock_displaySeconds_false.js index cf33332090..181e8c6085 100644 --- a/tests/configs/modules/clock/clock_displaySeconds_false.js +++ b/tests/configs/modules/clock/clock_displaySeconds_false.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config for default clock module - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ let config = { timeFormat: 12, diff --git a/tests/configs/modules/clock/clock_showDateAnalog.js b/tests/configs/modules/clock/clock_showDateAnalog.js new file mode 100644 index 0000000000..772261c187 --- /dev/null +++ b/tests/configs/modules/clock/clock_showDateAnalog.js @@ -0,0 +1,20 @@ +let config = { + timeFormat: 12, + + modules: [ + { + module: "clock", + position: "middle_center", + config: { + showTime: true, + showDate: true, + displayType: "analog" + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/clock/clock_showPeriodUpper.js b/tests/configs/modules/clock/clock_showPeriodUpper.js index 3dd8b5c52f..78a1f315ef 100644 --- a/tests/configs/modules/clock/clock_showPeriodUpper.js +++ b/tests/configs/modules/clock/clock_showPeriodUpper.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config for default clock module - * - * By Sergey Morozov - * MIT Licensed. - */ let config = { timeFormat: 12, diff --git a/tests/configs/modules/clock/clock_showSunMoon.js b/tests/configs/modules/clock/clock_showSunMoon.js new file mode 100644 index 0000000000..c5766aa255 --- /dev/null +++ b/tests/configs/modules/clock/clock_showSunMoon.js @@ -0,0 +1,19 @@ +let config = { + timeFormat: 12, + + modules: [ + { + module: "clock", + position: "middle_center", + config: { + showSunTimes: true, + showMoonTimes: true + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/clock/clock_showTime.js b/tests/configs/modules/clock/clock_showTime.js index 17ea4590d1..5e68951e2f 100644 --- a/tests/configs/modules/clock/clock_showTime.js +++ b/tests/configs/modules/clock/clock_showTime.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config for default clock module - * - * By Johan Hammar - * MIT Licensed. - */ let config = { timeFormat: 12, diff --git a/tests/configs/modules/clock/clock_showWeek.js b/tests/configs/modules/clock/clock_showWeek.js index 71377e0bc5..7af4740655 100644 --- a/tests/configs/modules/clock/clock_showWeek.js +++ b/tests/configs/modules/clock/clock_showWeek.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config for default clock module - * - * By Johan Hammar - * MIT Licensed. - */ let config = { timeFormat: 12, diff --git a/tests/configs/modules/clock/es/clock_12hr.js b/tests/configs/modules/clock/es/clock_12hr.js index 44444c06e4..66d380f8bf 100644 --- a/tests/configs/modules/clock/es/clock_12hr.js +++ b/tests/configs/modules/clock/es/clock_12hr.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config for default clock module - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ let config = { language: "es", timeFormat: 12, diff --git a/tests/configs/modules/clock/es/clock_24hr.js b/tests/configs/modules/clock/es/clock_24hr.js index 66b5304d17..752c5fd054 100644 --- a/tests/configs/modules/clock/es/clock_24hr.js +++ b/tests/configs/modules/clock/es/clock_24hr.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config for default clock module - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ let config = { language: "es", diff --git a/tests/configs/modules/clock/es/clock_showPeriodUpper.js b/tests/configs/modules/clock/es/clock_showPeriodUpper.js index 5e1fbb4be2..76f5fd0433 100644 --- a/tests/configs/modules/clock/es/clock_showPeriodUpper.js +++ b/tests/configs/modules/clock/es/clock_showPeriodUpper.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config for default clock module - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ let config = { language: "es", timeFormat: 12, diff --git a/tests/configs/modules/clock/es/clock_showWeek.js b/tests/configs/modules/clock/es/clock_showWeek.js index 73635c0ec0..c43eccdaef 100644 --- a/tests/configs/modules/clock/es/clock_showWeek.js +++ b/tests/configs/modules/clock/es/clock_showWeek.js @@ -1,9 +1,3 @@ -/* MagicMirror² Test config for default clock module - * Language es for showWeek feature - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ let config = { language: "es", timeFormat: 12, diff --git a/tests/configs/modules/compliments/compliments_animateCSS.js b/tests/configs/modules/compliments/compliments_animateCSS.js new file mode 100644 index 0000000000..1e3d3d2f9d --- /dev/null +++ b/tests/configs/modules/compliments/compliments_animateCSS.js @@ -0,0 +1,22 @@ +let config = { + modules: [ + { + module: "compliments", + position: "lower_third", + animateIn: "flipInX", + animateOut: "flipOutX", + config: { + compliments: { + anytime: ["AnimateCSS Testing..."] + }, + updateInterval: 2000, + fadeSpeed: 1000 + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/compliments/compliments_animateCSS_fallbackToDefault.js b/tests/configs/modules/compliments/compliments_animateCSS_fallbackToDefault.js new file mode 100644 index 0000000000..48f41cbfeb --- /dev/null +++ b/tests/configs/modules/compliments/compliments_animateCSS_fallbackToDefault.js @@ -0,0 +1,22 @@ +let config = { + modules: [ + { + module: "compliments", + position: "lower_third", + animateIn: "foo", + animateOut: "bar", + config: { + compliments: { + anytime: ["AnimateCSS Testing..."] + }, + updateInterval: 2000, + fadeSpeed: 1000 + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/compliments/compliments_animateCSS_invertedAnimationName.js b/tests/configs/modules/compliments/compliments_animateCSS_invertedAnimationName.js new file mode 100644 index 0000000000..310210bfc1 --- /dev/null +++ b/tests/configs/modules/compliments/compliments_animateCSS_invertedAnimationName.js @@ -0,0 +1,22 @@ +let config = { + modules: [ + { + module: "compliments", + position: "lower_third", + animateIn: "flipOutX", + animateOut: "flipInX", + config: { + compliments: { + anytime: ["AnimateCSS Testing..."] + }, + updateInterval: 2000, + fadeSpeed: 1000 + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/compliments/compliments_anytime.js b/tests/configs/modules/compliments/compliments_anytime.js index 89253d9140..102b59ca8e 100644 --- a/tests/configs/modules/compliments/compliments_anytime.js +++ b/tests/configs/modules/compliments/compliments_anytime.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config compliments with anytime type - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ let config = { timeFormat: 12, diff --git a/tests/configs/modules/compliments/compliments_date.js b/tests/configs/modules/compliments/compliments_date.js index 2d9018b1d6..f1822f6a1c 100644 --- a/tests/configs/modules/compliments/compliments_date.js +++ b/tests/configs/modules/compliments/compliments_date.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config compliments with date type - * - * By Rejas - * MIT Licensed. - */ let config = { timeFormat: 12, diff --git a/tests/configs/modules/compliments/compliments_only_anytime.js b/tests/configs/modules/compliments/compliments_only_anytime.js index f1da683a94..8714bebd7e 100644 --- a/tests/configs/modules/compliments/compliments_only_anytime.js +++ b/tests/configs/modules/compliments/compliments_only_anytime.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config compliments with anytime type - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ let config = { timeFormat: 12, diff --git a/tests/configs/modules/compliments/compliments_parts_day.js b/tests/configs/modules/compliments/compliments_parts_day.js index ff34803a5b..f5a2bb7f42 100644 --- a/tests/configs/modules/compliments/compliments_parts_day.js +++ b/tests/configs/modules/compliments/compliments_parts_day.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config for default compliments - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ let config = { timeFormat: 12, diff --git a/tests/configs/modules/compliments/compliments_remote.js b/tests/configs/modules/compliments/compliments_remote.js index 4658929682..5d8543e1c8 100644 --- a/tests/configs/modules/compliments/compliments_remote.js +++ b/tests/configs/modules/compliments/compliments_remote.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config compliments with remote file - * - * By Rejas - * MIT Licensed. - */ let config = { modules: [ { diff --git a/tests/configs/modules/display.js b/tests/configs/modules/display.js index a416607743..c66e586a7b 100644 --- a/tests/configs/modules/display.js +++ b/tests/configs/modules/display.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config for display setters module using the helloworld module - * - * By Rejas - * MIT Licensed. - */ let config = { modules: [ { diff --git a/tests/configs/modules/helloworld/helloworld.js b/tests/configs/modules/helloworld/helloworld.js index 7225662127..d9aa0cb442 100644 --- a/tests/configs/modules/helloworld/helloworld.js +++ b/tests/configs/modules/helloworld/helloworld.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config sample module hello world - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ let config = { modules: [ { diff --git a/tests/configs/modules/helloworld/helloworld_default.js b/tests/configs/modules/helloworld/helloworld_default.js index 06e6fe8dda..b0b35c7e48 100644 --- a/tests/configs/modules/helloworld/helloworld_default.js +++ b/tests/configs/modules/helloworld/helloworld_default.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config sample module hello world default config - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ let config = { modules: [ { diff --git a/tests/configs/modules/newsfeed/default.js b/tests/configs/modules/newsfeed/default.js index 34a7587fb0..0023c4c386 100644 --- a/tests/configs/modules/newsfeed/default.js +++ b/tests/configs/modules/newsfeed/default.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config newsfeed module - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ let config = { timeFormat: 12, diff --git a/tests/configs/modules/newsfeed/ignore_items.js b/tests/configs/modules/newsfeed/ignore_items.js index fd104ba414..425ef78398 100644 --- a/tests/configs/modules/newsfeed/ignore_items.js +++ b/tests/configs/modules/newsfeed/ignore_items.js @@ -1,7 +1,3 @@ -/* MagicMirror² Test config newsfeed module - * - * MIT Licensed. - */ let config = { timeFormat: 12, diff --git a/tests/configs/modules/newsfeed/incorrect_url.js b/tests/configs/modules/newsfeed/incorrect_url.js index f9d75b09a3..565da18997 100644 --- a/tests/configs/modules/newsfeed/incorrect_url.js +++ b/tests/configs/modules/newsfeed/incorrect_url.js @@ -1,7 +1,3 @@ -/* MagicMirror² Test config newsfeed module - * - * MIT Licensed. - */ let config = { timeFormat: 12, diff --git a/tests/configs/modules/newsfeed/prohibited_words.js b/tests/configs/modules/newsfeed/prohibited_words.js index 4ff6aec0fa..143fcf903c 100644 --- a/tests/configs/modules/newsfeed/prohibited_words.js +++ b/tests/configs/modules/newsfeed/prohibited_words.js @@ -1,7 +1,3 @@ -/* MagicMirror² Test config newsfeed module - * - * MIT Licensed. - */ let config = { timeFormat: 12, diff --git a/tests/configs/modules/positions.js b/tests/configs/modules/positions.js index 77ad8f72c9..e9e0d07a76 100644 --- a/tests/configs/modules/positions.js +++ b/tests/configs/modules/positions.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config for position setters module using the helloworld module - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ let config = { modules: // Using exotic content. This is why don't accept go to JSON configuration file @@ -14,7 +9,7 @@ let config = { module: "helloworld", position: positions[idx], config: { - text: "Text in " + positions[idx] + text: `Text in ${positions[idx]}` } }); } diff --git a/tests/configs/modules/weather/currentweather_compliments.js b/tests/configs/modules/weather/currentweather_compliments.js index 4af544663f..25303fd3cb 100644 --- a/tests/configs/modules/weather/currentweather_compliments.js +++ b/tests/configs/modules/weather/currentweather_compliments.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config current weather compliments - * - * By rejas https://github.com/rejas - * MIT Licensed. - */ let config = { modules: [ { diff --git a/tests/configs/modules/weather/currentweather_default.js b/tests/configs/modules/weather/currentweather_default.js index e2ef16b764..b6601aa378 100644 --- a/tests/configs/modules/weather/currentweather_default.js +++ b/tests/configs/modules/weather/currentweather_default.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config default weather - * - * By fewieden https://github.com/fewieden - * MIT Licensed. - */ let config = { timeFormat: 12, @@ -12,6 +7,7 @@ let config = { position: "bottom_bar", config: { location: "Munich", + showHumidity: "feelslike", mockData: '"#####WEATHERDATA#####"' } } diff --git a/tests/configs/modules/weather/currentweather_options.js b/tests/configs/modules/weather/currentweather_options.js index 2dd9216327..f7c2e3f116 100644 --- a/tests/configs/modules/weather/currentweather_options.js +++ b/tests/configs/modules/weather/currentweather_options.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config default weather - * - * By fewieden https://github.com/fewieden - * MIT Licensed. - */ let config = { modules: [ { @@ -14,7 +9,7 @@ let config = { windUnits: "beaufort", showWindDirectionAsArrow: true, showSun: false, - showHumidity: true, + showHumidity: "wind", roundTemp: true, degreeLabel: true } diff --git a/tests/configs/modules/weather/currentweather_units.js b/tests/configs/modules/weather/currentweather_units.js index ac007314a5..eedbc37de8 100644 --- a/tests/configs/modules/weather/currentweather_units.js +++ b/tests/configs/modules/weather/currentweather_units.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config default weather - * - * By fewieden https://github.com/fewieden - * MIT Licensed. - */ let config = { units: "imperial", @@ -14,7 +9,7 @@ let config = { location: "Munich", mockData: '"#####WEATHERDATA#####"', decimalSymbol: ",", - showHumidity: true + showHumidity: "wind" } } ] diff --git a/tests/configs/modules/weather/forecastweather_absolute.js b/tests/configs/modules/weather/forecastweather_absolute.js index 9972383b4e..a2640d3025 100644 --- a/tests/configs/modules/weather/forecastweather_absolute.js +++ b/tests/configs/modules/weather/forecastweather_absolute.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config default weather - * - * By fewieden https://github.com/fewieden - * MIT Licensed. - */ let config = { timeFormat: 12, diff --git a/tests/configs/modules/weather/forecastweather_default.js b/tests/configs/modules/weather/forecastweather_default.js index 6f535b39c3..4cddef62fa 100644 --- a/tests/configs/modules/weather/forecastweather_default.js +++ b/tests/configs/modules/weather/forecastweather_default.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config default weather - * - * By fewieden https://github.com/fewieden - * MIT Licensed. - */ let config = { timeFormat: 12, diff --git a/tests/configs/modules/weather/forecastweather_options.js b/tests/configs/modules/weather/forecastweather_options.js index 23cda84f67..0eea8292ed 100644 --- a/tests/configs/modules/weather/forecastweather_options.js +++ b/tests/configs/modules/weather/forecastweather_options.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config default weather - * - * By fewieden https://github.com/fewieden - * MIT Licensed. - */ let config = { timeFormat: 12, diff --git a/tests/configs/modules/weather/forecastweather_units.js b/tests/configs/modules/weather/forecastweather_units.js index 7e1ac86f28..8ac58a43b0 100644 --- a/tests/configs/modules/weather/forecastweather_units.js +++ b/tests/configs/modules/weather/forecastweather_units.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test config default weather - * - * By rejas - * MIT Licensed. - */ let config = { units: "imperial", @@ -15,7 +10,8 @@ let config = { location: "Munich", mockData: '"#####WEATHERDATA#####"', weatherEndpoint: "/forecast/daily", - decimalSymbol: "_" + decimalSymbol: "_", + showPrecipitationAmount: true } } ] diff --git a/tests/configs/modules/weather/hourlyweather_default.js b/tests/configs/modules/weather/hourlyweather_default.js new file mode 100644 index 0000000000..8e46b44cab --- /dev/null +++ b/tests/configs/modules/weather/hourlyweather_default.js @@ -0,0 +1,20 @@ +let config = { + timeFormat: 12, + + modules: [ + { + module: "weather", + position: "bottom_bar", + config: { + type: "hourly", + location: "Berlin", + mockData: '"#####WEATHERDATA#####"' + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/weather/hourlyweather_options.js b/tests/configs/modules/weather/hourlyweather_options.js new file mode 100644 index 0000000000..b37fd7b9f1 --- /dev/null +++ b/tests/configs/modules/weather/hourlyweather_options.js @@ -0,0 +1,21 @@ +let config = { + timeFormat: 12, + + modules: [ + { + module: "weather", + position: "bottom_bar", + config: { + type: "hourly", + location: "Berlin", + mockData: '"#####WEATHERDATA#####"', + hourlyForecastIncrements: 2 + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/modules/weather/hourlyweather_showPrecipitation.js b/tests/configs/modules/weather/hourlyweather_showPrecipitation.js new file mode 100644 index 0000000000..0e79858f16 --- /dev/null +++ b/tests/configs/modules/weather/hourlyweather_showPrecipitation.js @@ -0,0 +1,22 @@ +let config = { + timeFormat: 12, + + modules: [ + { + module: "weather", + position: "bottom_bar", + config: { + type: "hourly", + location: "Berlin", + mockData: '"#####WEATHERDATA#####"', + showPrecipitationAmount: true, + showPrecipitationProbability: true + } + } + ] +}; + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/noIpWhiteList.js b/tests/configs/noIpWhiteList.js index 36035c16b4..57eaa91215 100644 --- a/tests/configs/noIpWhiteList.js +++ b/tests/configs/noIpWhiteList.js @@ -1,10 +1,6 @@ -/* MagicMirror² Test config sample ipWhitelist - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ - ipWhitelist: ["x.x.x.x"] +let config = require(`${process.cwd()}/tests/configs/default.js`).configFactory({ + ipWhitelist: ["x.x.x.x"], + port: 8181 }); /*************** DO NOT EDIT THE LINE BELOW ***************/ diff --git a/tests/configs/port_8090.js b/tests/configs/port_8090.js index df6bf7dc74..4019be8e89 100644 --- a/tests/configs/port_8090.js +++ b/tests/configs/port_8090.js @@ -1,9 +1,4 @@ -/* MagicMirror² Test config sample environment set port 8090 - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ -let config = require(process.cwd() + "/tests/configs/default.js").configFactory({ +let config = require(`${process.cwd()}/tests/configs/default.js`).configFactory({ port: 8090 }); diff --git a/tests/configs/port_variable.env b/tests/configs/port_variable.env new file mode 100644 index 0000000000..2b19af0113 --- /dev/null +++ b/tests/configs/port_variable.env @@ -0,0 +1 @@ +MM_PORT=8090 diff --git a/tests/configs/port_variable.js.template b/tests/configs/port_variable.js.template new file mode 100644 index 0000000000..e44aa5ac90 --- /dev/null +++ b/tests/configs/port_variable.js.template @@ -0,0 +1,8 @@ +let config = require(`${process.cwd()}/tests/configs/default.js`).configFactory({ + port: ${MM_PORT} +}); + +/*************** DO NOT EDIT THE LINE BELOW ***************/ +if (typeof module !== "undefined") { + module.exports = config; +} diff --git a/tests/configs/without_modules.js b/tests/configs/without_modules.js index 51ce02f6e0..abe8fbc42e 100644 --- a/tests/configs/without_modules.js +++ b/tests/configs/without_modules.js @@ -1,8 +1,3 @@ -/* MagicMirror² Test default config for modules - * - * By Rodrigo Ramírez Norambuena https://rodrigoramirez.com - * MIT Licensed. - */ let config = { ipWhitelist: ["127.0.0.1", "::ffff:127.0.0.1", "::1", "::ffff:192.168.10.1"] }; diff --git a/tests/e2e/animateCSS_spec.js b/tests/e2e/animateCSS_spec.js new file mode 100644 index 0000000000..d7fcb52e44 --- /dev/null +++ b/tests/e2e/animateCSS_spec.js @@ -0,0 +1,73 @@ +const helpers = require("./helpers/global-setup"); + +describe("AnimateCSS integration Test", () => { + // define config file for testing + let testConfigFile = "tests/configs/modules/compliments/compliments_animateCSS.js"; + // define config file to fallback to default: wrong animation name (must return no animation) + let testConfigFileFallbackToDefault = "tests/configs/modules/compliments/compliments_animateCSS_fallbackToDefault.js"; + // define config file with an inversed name animation : in for out and vice versa (must return no animation) + let testConfigFileInvertedAnimationName = "tests/configs/modules/compliments/compliments_animateCSS_invertedAnimationName.js"; + // define config file with no animation defined + let testConfigByDefault = "tests/configs/modules/compliments/compliments_anytime.js"; + + /** + * move similar tests in function doTest + * @param {string} [animationIn] animation in name of AnimateCSS to test. + * @param {string} [animationOut] animation out name of AnimateCSS to test. + * @returns {boolean} result + */ + const doTest = async (animationIn, animationOut) => { + await helpers.getDocument(); + let elem = await helpers.waitForElement(".compliments"); + expect(elem).not.toBeNull(); + let styles = window.getComputedStyle(elem); + + if (animationIn && animationIn !== "") { + expect(styles._values["animation-name"]).toBe(animationIn); + } else { + expect(styles._values["animation-name"]).toBeUndefined(); + } + + if (animationOut && animationOut !== "") { + elem = await helpers.waitForElement(`.compliments.animate__animated.animate__${animationOut}`); + expect(elem).not.toBeNull(); + styles = window.getComputedStyle(elem); + expect(styles._values["animation-name"]).toBe(animationOut); + } else { + expect(styles._values["animation-name"]).toBeUndefined(); + } + return true; + }; + + afterEach(async () => { + await helpers.stopApplication(); + }); + + describe("animateIn and animateOut Test", () => { + it("with flipInX and flipOutX animation", async () => { + await helpers.startApplication(testConfigFile); + await expect(doTest("flipInX", "flipOutX")).resolves.toBe(true); + }); + }); + + describe("use animateOut name for animateIn (vice versa) Test", () => { + it("without animation", async () => { + await helpers.startApplication(testConfigFileInvertedAnimationName); + await expect(doTest()).resolves.toBe(true); + }); + }); + + describe("false Animation name test", () => { + it("without animation", async () => { + await helpers.startApplication(testConfigFileFallbackToDefault); + await expect(doTest()).resolves.toBe(true); + }); + }); + + describe("no Animation defined test", () => { + it("without animation", async () => { + await helpers.startApplication(testConfigByDefault); + await expect(doTest()).resolves.toBe(true); + }); + }); +}); diff --git a/tests/e2e/env_spec.js b/tests/e2e/env_spec.js index a62ab54448..eebc8912f0 100644 --- a/tests/e2e/env_spec.js +++ b/tests/e2e/env_spec.js @@ -10,18 +10,18 @@ describe("App environment", () => { }); it("get request from http://localhost:8080 should return 200", async () => { - const res = await helpers.fetch("http://localhost:8080"); + const res = await fetch("http://localhost:8080"); expect(res.status).toBe(200); }); it("get request from http://localhost:8080/nothing should return 404", async () => { - const res = await helpers.fetch("http://localhost:8080/nothing"); + const res = await fetch("http://localhost:8080/nothing"); expect(res.status).toBe(404); }); it("should show the title MagicMirror²", async () => { const elem = await helpers.waitForElement("title"); - expect(elem).not.toBe(null); + expect(elem).not.toBeNull(); expect(elem.textContent).toBe("MagicMirror²"); }); }); diff --git a/tests/e2e/fonts_spec.js b/tests/e2e/fonts_spec.js index b0d642d026..80e3e34081 100644 --- a/tests/e2e/fonts_spec.js +++ b/tests/e2e/fonts_spec.js @@ -3,7 +3,7 @@ const helpers = require("./helpers/global-setup"); describe("All font files from roboto.css should be downloadable", () => { const fontFiles = []; // Statements below filters out all 'url' lines in the CSS file - const fileContent = require("fs").readFileSync(__dirname + "/../../fonts/roboto.css", "utf8"); + const fileContent = require("node:fs").readFileSync(`${__dirname}/../../fonts/roboto.css`, "utf8"); const regex = /\burl\(['"]([^'"]+)['"]\)/g; let match = regex.exec(fileContent); while (match !== null) { @@ -20,9 +20,9 @@ describe("All font files from roboto.css should be downloadable", () => { await helpers.stopApplication(); }); - test.each(fontFiles)("should return 200 HTTP code for file '%s'", async (fontFile) => { - const fontUrl = "http://localhost:8080/fonts/" + fontFile; - const res = await helpers.fetch(fontUrl); + it.each(fontFiles)("should return 200 HTTP code for file '%s'", async (fontFile) => { + const fontUrl = `http://localhost:8080/fonts/${fontFile}`; + const res = await fetch(fontUrl); expect(res.status).toBe(200); }); }); diff --git a/tests/e2e/helpers/basic-auth.js b/tests/e2e/helpers/basic-auth.js index 84917a44f0..c10e0f3ce9 100644 --- a/tests/e2e/helpers/basic-auth.js +++ b/tests/e2e/helpers/basic-auth.js @@ -1,6 +1,7 @@ -const path = require("path"); +const path = require("node:path"); const auth = require("express-basic-auth"); const express = require("express"); + const app = express(); const basicAuth = auth({ @@ -12,7 +13,7 @@ app.use(basicAuth); // Set available directories const directories = ["/tests/configs", "/tests/mocks"]; -const rootPath = path.resolve(__dirname + "/../../../"); +const rootPath = path.resolve(`${__dirname}/../../../`); for (let directory of directories) { app.use(directory, express.static(path.resolve(rootPath + directory))); diff --git a/tests/e2e/helpers/global-setup.js b/tests/e2e/helpers/global-setup.js index ee8fb83ef2..31a3e036c2 100644 --- a/tests/e2e/helpers/global-setup.js +++ b/tests/e2e/helpers/global-setup.js @@ -1,5 +1,4 @@ const jsdom = require("jsdom"); -const corefetch = require("fetch"); exports.startApplication = async (configFilename, exec) => { jest.resetModules(); @@ -13,28 +12,31 @@ exports.startApplication = async (configFilename, exec) => { process.env.MM_CONFIG_FILE = configFilename; } if (exec) exec; - global.app = require("app.js"); + global.app = require("../../../js/app"); - return new Promise((resolve) => { - global.app.start(resolve); - }); + return global.app.start(); }; exports.stopApplication = async () => { - if (global.app) { - return new Promise((resolve) => { - global.app.stop(resolve); - delete global.app; - }); + if (!global.app) { + return Promise.resolve(); } - return Promise.resolve(); + await global.app.stop(); + delete global.app; }; exports.getDocument = () => { return new Promise((resolve) => { - const url = "http://" + (config.address || "localhost") + ":" + (config.port || "8080"); + const url = `http://${config.address || "localhost"}:${config.port || "8080"}`; jsdom.JSDOM.fromURL(url, { resources: "usable", runScripts: "dangerously" }).then((dom) => { dom.window.name = "jsdom"; + global.window = dom.window; + // Following fixes `navigator is not defined` errors in e2e tests, found here + // https://www.appsloveworld.com/reactjs/100/37/mocha-react-navigator-is-not-defined + global.navigator = { + useragent: "node.js" + }; + dom.window.fetch = fetch; dom.window.onload = () => { global.document = dom.window.document; resolve(); @@ -83,16 +85,9 @@ exports.waitForAllElements = (selector) => { }); }; -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).not.toBeNull(); expect(elem.textContent).toMatch(regex); + return true; }; diff --git a/tests/e2e/helpers/mock-console.js b/tests/e2e/helpers/mock-console.js index 3f9909f11a..c593b7062e 100644 --- a/tests/e2e/helpers/mock-console.js +++ b/tests/e2e/helpers/mock-console.js @@ -1,10 +1,17 @@ /** * Suppresses errors concerning web server already shut down. - * * @param {string} err The error message. */ 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")) { + if ( + err.includes("ECONNREFUSED") + || err.includes("ECONNRESET") + || err.includes("socket hang up") + || err.includes("exports is not defined") + || err.includes("write EPIPE") + || err.includes("AggregateError") + || err.includes("ERR_SOCKET_CONNECTION_TIMEOUT") + ) { jest.fn(); } else { console.dir(err); diff --git a/tests/e2e/helpers/weather-functions.js b/tests/e2e/helpers/weather-functions.js index 5aa71c488a..9b55f15e6a 100644 --- a/tests/e2e/helpers/weather-functions.js +++ b/tests/e2e/helpers/weather-functions.js @@ -1,29 +1,19 @@ +const { injectMockData } = require("../../utils/weather_mocker"); const helpers = require("./global-setup"); -const path = require("path"); -const fs = require("fs"); -const { generateWeather, generateWeatherForecast } = require("../../mocks/weather_test"); exports.getText = async (element, result) => { const elem = await helpers.waitForElement(element); - expect(elem).not.toBe(null); + expect(elem).not.toBeNull(); expect( elem.textContent .trim() .replace(/(\r\n|\n|\r)/gm, "") .replace(/[ ]+/g, " ") ).toBe(result); + return true; }; -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(""); +exports.startApp = async (configFileName, additionalMockData) => { + await helpers.startApplication(injectMockData(configFileName, additionalMockData)); await helpers.getDocument(); }; diff --git a/tests/e2e/ipWhitelist_spec.js b/tests/e2e/ipWhitelist_spec.js index 4b3d3c0ff2..07a0425e8d 100644 --- a/tests/e2e/ipWhitelist_spec.js +++ b/tests/e2e/ipWhitelist_spec.js @@ -10,7 +10,7 @@ describe("ipWhitelist directive configuration", () => { }); it("should return 403", async () => { - const res = await helpers.fetch("http://localhost:8080"); + const res = await fetch("http://localhost:8181"); expect(res.status).toBe(403); }); }); @@ -24,7 +24,7 @@ describe("ipWhitelist directive configuration", () => { }); it("should return 200", async () => { - const res = await helpers.fetch("http://localhost:8080"); + const res = await fetch("http://localhost:8282"); expect(res.status).toBe(200); }); }); diff --git a/tests/e2e/modules/alert_spec.js b/tests/e2e/modules/alert_spec.js index c118e17ef3..f3c95a6c3c 100644 --- a/tests/e2e/modules/alert_spec.js +++ b/tests/e2e/modules/alert_spec.js @@ -11,7 +11,7 @@ describe("Alert module", () => { 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).not.toBeNull(); 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 e1bee78e49..0dcd562cd1 100644 --- a/tests/e2e/modules/calendar_spec.js +++ b/tests/e2e/modules/calendar_spec.js @@ -1,26 +1,30 @@ const helpers = require("../helpers/global-setup"); -const serverBasicAuth = require("../helpers/basic-auth.js"); +const serverBasicAuth = require("../helpers/basic-auth"); describe("Calendar module", () => { + /** * @param {string} element css selector * @param {string} result expected number * @param {string} not reverse result + * @returns {boolean} result */ const testElementLength = async (element, result, not) => { const elem = await helpers.waitForAllElements(element); - expect(elem).not.toBe(null); + expect(elem).not.toBeNull(); if (not === "not") { - expect(elem.length).not.toBe(result); + expect(elem).not.toHaveLength(result); } else { - expect(elem.length).toBe(result); + expect(elem).toHaveLength(result); } + return true; }; const testTextContain = async (element, text) => { const elem = await helpers.waitForElement(element, "undefinedLoading"); - expect(elem).not.toBe(null); + expect(elem).not.toBeNull(); expect(elem.textContent).toContain(text); + return true; }; afterAll(async () => { @@ -34,11 +38,11 @@ describe("Calendar module", () => { }); it("should show the default maximumEntries of 10", async () => { - await testElementLength(".calendar .event", 10); + await expect(testElementLength(".calendar .event", 10)).resolves.toBe(true); }); it("should show the default calendar symbol in each event", async () => { - await testElementLength(".calendar .event .fa-calendar-alt", 0, "not"); + await expect(testElementLength(".calendar .event .fa-calendar-alt", 0, "not")).resolves.toBe(true); }); }); @@ -48,20 +52,28 @@ describe("Calendar module", () => { await helpers.getDocument(); }); - it("should show the custom maximumEntries of 4", async () => { - await testElementLength(".calendar .event", 4); + it("should show the custom maximumEntries of 5", async () => { + await expect(testElementLength(".calendar .event", 5)).resolves.toBe(true); + }); + + it("should show the custom calendar symbol in four events", async () => { + await expect(testElementLength(".calendar .event .fa-birthday-cake", 4)).resolves.toBe(true); }); - it("should show the custom calendar symbol in each event", async () => { - await testElementLength(".calendar .event .fa-birthday-cake", 4); + it("should show a customEvent calendar symbol in one event", async () => { + await expect(testElementLength(".calendar .event .fa-dice", 1)).resolves.toBe(true); + }); + + it("should show a customEvent calendar eventClass in one event", async () => { + await expect(testElementLength(".calendar .event.undo", 1)).resolves.toBe(true); }); it("should show two custom icons for repeating events", async () => { - await testElementLength(".calendar .event .fa-undo", 2); + await expect(testElementLength(".calendar .event .fa-undo", 2)).resolves.toBe(true); }); it("should show two custom icons for day events", async () => { - await testElementLength(".calendar .event .fa-calendar-day", 2); + await expect(testElementLength(".calendar .event .fa-calendar-day", 2)).resolves.toBe(true); }); }); @@ -72,7 +84,49 @@ describe("Calendar module", () => { }); it("should show the recurring birthday event 6 times", async () => { - await testElementLength(".calendar .event", 6); + await expect(testElementLength(".calendar .event", 6)).resolves.toBe(true); + }); + }); + + describe("Events from multiple calendars", () => { + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/calendar/show-duplicates-in-calendar.js"); + await helpers.getDocument(); + }); + + it("should show multiple events with the same title and start time from different calendars", async () => { + await expect(testElementLength(".calendar .event", 22)).resolves.toBe(true); + }); + }); + + //Will contain everyday an fullDayEvent that starts today and ends tomorrow, and one starting tomorrow and ending the day after tomorrow + describe("FullDayEvent over several days should show how many days are left from the from the starting date on", () => { + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/calendar/long-fullday-event.js"); + await helpers.getDocument(); + }); + + it("should contain text 'Ends in' with the left days", async () => { + await expect(testTextContain(".calendar .today .time", "Ends in")).resolves.toBe(true); + await expect(testTextContain(".calendar .yesterday .time", "Today")).resolves.toBe(true); + await expect(testTextContain(".calendar .tomorrow .time", "Tomorrow")).resolves.toBe(true); + }); + it("should contain in total three events", async () => { + await expect(testElementLength(".calendar .event", 3)).resolves.toBe(true); + }); + }); + + describe("FullDayEvent Single day, should show Today", () => { + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/calendar/single-fullday-event.js"); + await helpers.getDocument(); + }); + + it("should contain text 'Today'", async () => { + await expect(testTextContain(".calendar .time", "Today")).resolves.toBe(true); + }); + it("should contain in total two events", async () => { + await expect(testElementLength(".calendar .event", 2)).resolves.toBe(true); }); }); @@ -87,8 +141,8 @@ describe("Calendar module", () => { await helpers.getDocument(); }); - it('should contain text "Mar 25th" in timezone UTC ' + -i, async () => { - await testTextContain(".calendar", "Mar 25th"); + it(`should contain text "Mar 25th" in timezone UTC ${-i}`, async () => { + await expect(testTextContain(".calendar", "Mar 25th")).resolves.toBe(true); }); }); } @@ -105,7 +159,7 @@ describe("Calendar module", () => { }); it("should return TestEvents", async () => { - await testElementLength(".calendar .event", 0, "not"); + await expect(testElementLength(".calendar .event", 0, "not")).resolves.toBe(true); }); }); @@ -116,7 +170,7 @@ describe("Calendar module", () => { }); it("should return TestEvents", async () => { - await testElementLength(".calendar .event", 0, "not"); + await expect(testElementLength(".calendar .event", 0, "not")).resolves.toBe(true); }); }); @@ -127,7 +181,7 @@ describe("Calendar module", () => { }); it("should return TestEvents", async () => { - await testElementLength(".calendar .event", 0, "not"); + await expect(testElementLength(".calendar .event", 0, "not")).resolves.toBe(true); }); }); @@ -138,7 +192,7 @@ describe("Calendar module", () => { }); it("should return TestEvents", async () => { - await testElementLength(".calendar .event", 0, "not"); + await expect(testElementLength(".calendar .event", 0, "not")).resolves.toBe(true); }); }); @@ -154,7 +208,7 @@ describe("Calendar module", () => { }); it("should show Unauthorized error", async () => { - await testTextContain(".calendar", "Error in the calendar module. Authorization failed"); + await expect(testTextContain(".calendar", "Error in the calendar module. Authorization failed")).resolves.toBe(true); }); }); }); diff --git a/tests/e2e/modules/clock_es_spec.js b/tests/e2e/modules/clock_es_spec.js index 4bdc4bccf7..134c795b0a 100644 --- a/tests/e2e/modules/clock_es_spec.js +++ b/tests/e2e/modules/clock_es_spec.js @@ -13,12 +13,12 @@ describe("Clock set to spanish language module", () => { 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}$/; - await helpers.testMatch(".clock .date", dateRegex); + await expect(helpers.testMatch(".clock .date", dateRegex)).resolves.toBe(true); }); it("shows time in 24hr format", async () => { const timeRegex = /^(?:2[0-3]|[01]\d):[0-5]\d[0-5]\d$/; - await helpers.testMatch(".clock .time", timeRegex); + await expect(helpers.testMatch(".clock .time", timeRegex)).resolves.toBe(true); }); }); @@ -30,12 +30,12 @@ describe("Clock set to spanish language module", () => { 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}$/; - await helpers.testMatch(".clock .date", dateRegex); + await expect(helpers.testMatch(".clock .date", dateRegex)).resolves.toBe(true); }); it("shows time in 12hr format", async () => { const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[ap]m$/; - await helpers.testMatch(".clock .time", timeRegex); + await expect(helpers.testMatch(".clock .time", timeRegex)).resolves.toBe(true); }); }); @@ -47,7 +47,7 @@ describe("Clock set to spanish language module", () => { 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$/; - await helpers.testMatch(".clock .time", timeRegex); + await expect(helpers.testMatch(".clock .time", timeRegex)).resolves.toBe(true); }); }); @@ -59,7 +59,7 @@ describe("Clock set to spanish language module", () => { it("shows week with correct format", async () => { const weekRegex = /^Semana [0-9]{1,2}$/; - await helpers.testMatch(".clock .week", weekRegex); + await expect(helpers.testMatch(".clock .week", weekRegex)).resolves.toBe(true); }); }); }); diff --git a/tests/e2e/modules/clock_spec.js b/tests/e2e/modules/clock_spec.js index e91237b248..651b20de66 100644 --- a/tests/e2e/modules/clock_spec.js +++ b/tests/e2e/modules/clock_spec.js @@ -1,5 +1,5 @@ -const helpers = require("../helpers/global-setup"); const moment = require("moment"); +const helpers = require("../helpers/global-setup"); describe("Clock module", () => { afterAll(async () => { @@ -14,12 +14,12 @@ describe("Clock module", () => { 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}$/; - await helpers.testMatch(".clock .date", dateRegex); + await expect(helpers.testMatch(".clock .date", dateRegex)).resolves.toBe(true); }); it("should show the time in 24hr format", async () => { const timeRegex = /^(?:2[0-3]|[01]\d):[0-5]\d[0-5]\d$/; - await helpers.testMatch(".clock .time", timeRegex); + await expect(helpers.testMatch(".clock .time", timeRegex)).resolves.toBe(true); }); }); @@ -31,12 +31,12 @@ describe("Clock module", () => { 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}$/; - await helpers.testMatch(".clock .date", dateRegex); + await expect(helpers.testMatch(".clock .date", dateRegex)).resolves.toBe(true); }); it("should show the time in 12hr format", async () => { const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[0-5]\d[ap]m$/; - await helpers.testMatch(".clock .time", timeRegex); + await expect(helpers.testMatch(".clock .time", timeRegex)).resolves.toBe(true); }); }); @@ -48,7 +48,7 @@ describe("Clock module", () => { 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$/; - await helpers.testMatch(".clock .time", timeRegex); + await expect(helpers.testMatch(".clock .time", timeRegex)).resolves.toBe(true); }); }); @@ -60,7 +60,7 @@ describe("Clock module", () => { it("should show 12hr time without seconds am/pm", async () => { const timeRegex = /^(?:1[0-2]|[1-9]):[0-5]\d[ap]m$/; - await helpers.testMatch(".clock .time", timeRegex); + await expect(helpers.testMatch(".clock .time", timeRegex)).resolves.toBe(true); }); }); @@ -71,8 +71,25 @@ describe("Clock module", () => { }); it("should not show the time when digital clock is shown", async () => { - const elem = await document.querySelector(".clock .digital .time"); - expect(elem).toBe(null); + const elem = document.querySelector(".clock .digital .time"); + expect(elem).toBeNull(); + }); + }); + + describe("with showSun/MoonTime enabled", () => { + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/clock/clock_showSunMoon.js"); + await helpers.getDocument(); + }); + + it("should show the sun times", async () => { + const elem = await helpers.waitForElement(".clock .digital .sun"); + expect(elem).not.toBeNull(); + }); + + it("should show the moon times", async () => { + const elem = await helpers.waitForElement(".clock .digital .moon"); + expect(elem).not.toBeNull(); }); }); @@ -84,14 +101,14 @@ describe("Clock module", () => { it("should show the week in the correct format", async () => { const weekRegex = /^Week [0-9]{1,2}$/; - await helpers.testMatch(".clock .week", weekRegex); + await expect(helpers.testMatch(".clock .week", weekRegex)).resolves.toBe(true); }); it("should show the week with the correct number of week of year", async () => { const currentWeekNumber = moment().week(); - const weekToShow = "Week " + currentWeekNumber; + const weekToShow = `Week ${currentWeekNumber}`; const elem = await helpers.waitForElement(".clock .week"); - expect(elem).not.toBe(null); + expect(elem).not.toBeNull(); expect(elem.textContent).toBe(weekToShow); }); }); @@ -103,8 +120,22 @@ describe("Clock module", () => { }); it("should show the analog clock face", async () => { - const elem = helpers.waitForElement(".clockCircle"); - expect(elem).not.toBe(null); + const elem = helpers.waitForElement(".clock-circle"); + expect(elem).not.toBeNull(); + }); + }); + + describe("with analog clock face and date enabled", () => { + beforeAll(async () => { + await helpers.startApplication("tests/configs/modules/clock/clock_showDateAnalog.js"); + await helpers.getDocument(); + }); + + it("should show the analog clock face and the date", async () => { + const elemClock = helpers.waitForElement(".clock-circle"); + await expect(elemClock).not.toBeNull(); + const elemDate = helpers.waitForElement(".clock .date"); + await expect(elemDate).not.toBeNull(); }); }); }); diff --git a/tests/e2e/modules/compliments_spec.js b/tests/e2e/modules/compliments_spec.js index 52d232e5dc..0604dab49f 100644 --- a/tests/e2e/modules/compliments_spec.js +++ b/tests/e2e/modules/compliments_spec.js @@ -1,17 +1,19 @@ const helpers = require("../helpers/global-setup"); describe("Compliments module", () => { + /** * move similar tests in function doTest - * * @param {Array} complimentsArray The array of compliments. + * @returns {boolean} result */ const doTest = async (complimentsArray) => { let elem = await helpers.waitForElement(".compliments"); - expect(elem).not.toBe(null); + expect(elem).not.toBeNull(); elem = await helpers.waitForElement(".module-content"); - expect(elem).not.toBe(null); + expect(elem).not.toBeNull(); expect(complimentsArray).toContain(elem.textContent); + return true; }; afterAll(async () => { @@ -19,14 +21,14 @@ describe("Compliments module", () => { }); describe("Feature anytime in compliments module", () => { - describe("Set anytime and empty compliments for morning, evening and afternoon ", () => { + describe("Set anytime and empty compliments for morning, evening and afternoon", () => { 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", async () => { - await doTest(["Anytime here"]); + it("shows anytime because if configure empty parts of day compliments and set anytime compliments", async () => { + await expect(doTest(["Anytime here"])).resolves.toBe(true); }); }); @@ -36,8 +38,8 @@ describe("Compliments module", () => { await helpers.getDocument(); }); - it("Show anytime compliments", async () => { - await doTest(["Anytime here"]); + it("shows anytime compliments", async () => { + await expect(doTest(["Anytime here"])).resolves.toBe(true); }); }); }); @@ -49,7 +51,7 @@ describe("Compliments module", () => { }); it("should show compliments from a remote file", async () => { - await doTest(["Remote compliment file works!"]); + await expect(doTest(["Remote compliment file works!"])).resolves.toBe(true); }); }); }); diff --git a/tests/e2e/modules/helloworld_spec.js b/tests/e2e/modules/helloworld_spec.js index ecdcdf2076..413c60e509 100644 --- a/tests/e2e/modules/helloworld_spec.js +++ b/tests/e2e/modules/helloworld_spec.js @@ -13,7 +13,7 @@ describe("Test helloworld module", () => { it("Test message helloworld module", async () => { const elem = await helpers.waitForElement(".helloworld"); - expect(elem).not.toBe(null); + expect(elem).not.toBeNull(); expect(elem.textContent).toContain("Test HelloWorld Module"); }); }); @@ -26,7 +26,7 @@ describe("Test helloworld module", () => { it("Test message helloworld module", async () => { const elem = await helpers.waitForElement(".helloworld"); - expect(elem).not.toBe(null); + expect(elem).not.toBeNull(); expect(elem.textContent).toContain("Hello World!"); }); }); diff --git a/tests/e2e/modules/newsfeed_spec.js b/tests/e2e/modules/newsfeed_spec.js index bf3066e753..141b880661 100644 --- a/tests/e2e/modules/newsfeed_spec.js +++ b/tests/e2e/modules/newsfeed_spec.js @@ -13,20 +13,20 @@ describe("Newsfeed module", () => { it("should show the newsfeed title", async () => { const elem = await helpers.waitForElement(".newsfeed .newsfeed-source"); - expect(elem).not.toBe(null); + expect(elem).not.toBeNull(); expect(elem.textContent).toContain("Rodrigo Ramirez Blog"); }); it("should show the newsfeed article", async () => { const elem = await helpers.waitForElement(".newsfeed .newsfeed-title"); - expect(elem).not.toBe(null); + expect(elem).not.toBeNull(); expect(elem.textContent).toContain("QPanel"); }); it("should NOT show the newsfeed description", async () => { await helpers.waitForElement(".newsfeed"); - const element = document.querySelector(".newsfeed .newsfeed-desc"); - expect(element).toBe(null); + const elem = document.querySelector(".newsfeed .newsfeed-desc"); + expect(elem).toBeNull(); }); }); @@ -38,14 +38,14 @@ describe("Newsfeed module", () => { it("should not show articles with prohibited words", async () => { const elem = await helpers.waitForElement(".newsfeed .newsfeed-title"); - expect(elem).not.toBe(null); + expect(elem).not.toBeNull(); expect(elem.textContent).toContain("Problema VirtualBox"); }); 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); + expect(elem).not.toBeNull(); + expect(elem.textContent).not.toHaveLength(0); }); }); @@ -57,7 +57,7 @@ describe("Newsfeed module", () => { 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).not.toBeNull(); expect(elem.textContent).toContain("Error in the Newsfeed module. Malformed url."); }); }); @@ -70,7 +70,7 @@ describe("Newsfeed module", () => { it("should show empty items info message", async () => { const elem = await helpers.waitForElement(".newsfeed .small"); - expect(elem).not.toBe(null); + expect(elem).not.toBeNull(); 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 index 97ae3eec85..d24ea1b133 100644 --- a/tests/e2e/modules/weather_current_spec.js +++ b/tests/e2e/modules/weather_current_spec.js @@ -1,9 +1,11 @@ const helpers = require("../helpers/global-setup"); const weatherFunc = require("../helpers/weather-functions"); +const { cleanupMockData } = require("../../utils/weather_mocker"); describe("Weather module", () => { afterAll(async () => { await helpers.stopApplication(); + await cleanupMockData(); }); describe("Current weather", () => { @@ -13,15 +15,19 @@ describe("Weather module", () => { }); it("should render wind speed and wind direction", async () => { - await weatherFunc.getText(".weather .normal.medium span:nth-child(2)", "12 WSW"); + await expect(weatherFunc.getText(".weather .normal.medium span:nth-child(2)", "12 WSW")).resolves.toBe(true); }); it("should render temperature with icon", async () => { - await weatherFunc.getText(".weather .large.light span.bright", "1.5°"); + await expect(weatherFunc.getText(".weather .large span.light.bright", "1.5°")).resolves.toBe(true); }); it("should render feels like temperature", async () => { - await weatherFunc.getText(".weather .normal.medium.feelslike span.dimmed", "Feels like -5.6°"); + // Template contains   which renders as \xa0 + await expect(weatherFunc.getText(".weather .normal.medium.feelslike span.dimmed", "93.7\xa0 Feels like -5.6°")).resolves.toBe(true); + }); + it("should render humidity next to feels-like", async () => { + await expect(weatherFunc.getText(".weather .normal.medium.feelslike span.dimmed .humidity", "93.7")).resolves.toBe(true); }); }); }); @@ -32,7 +38,7 @@ describe("Weather module", () => { }); it("should render a compliment based on the current weather", async () => { - await weatherFunc.getText(".compliments .module-content span", "snow"); + await expect(weatherFunc.getText(".compliments .module-content span", "snow")).resolves.toBe(true); }); }); @@ -42,25 +48,25 @@ describe("Weather module", () => { }); it("should render windUnits in beaufort", async () => { - await weatherFunc.getText(".weather .normal.medium span:nth-child(2)", "6"); + await expect(weatherFunc.getText(".weather .normal.medium span:nth-child(2)", "6")).resolves.toBe(true); }); 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);"); + const elem = await helpers.waitForElement(".weather .normal.medium sup i.fa-long-arrow-alt-down"); + expect(elem).not.toBeNull(); + 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 humidity next to wind", async () => { + await expect(weatherFunc.getText(".weather .normal.medium .humidity", "93.7")).resolves.toBe(true); }); it("should render degreeLabel for temp", async () => { - await weatherFunc.getText(".weather .large.light span.bright", "1°C"); + await expect(weatherFunc.getText(".weather .large span.bright.light", "1°C")).resolves.toBe(true); }); it("should render degreeLabel for feels like", async () => { - await weatherFunc.getText(".weather .normal.medium.feelslike span.dimmed", "Feels like -6°C"); + await expect(weatherFunc.getText(".weather .normal.medium.feelslike span.dimmed", "Feels like -6°C")).resolves.toBe(true); }); }); @@ -70,15 +76,15 @@ describe("Weather module", () => { }); it("should render wind in imperial units", async () => { - await weatherFunc.getText(".weather .normal.medium span:nth-child(2)", "26 WSW"); + await expect(weatherFunc.getText(".weather .normal.medium span:nth-child(2)", "26 WSW")).resolves.toBe(true); }); it("should render temperatures in fahrenheit", async () => { - await weatherFunc.getText(".weather .large.light span.bright", "34,7°"); + await expect(weatherFunc.getText(".weather .large span.bright.light", "34,7°")).resolves.toBe(true); }); it("should render 'feels like' in fahrenheit", async () => { - await weatherFunc.getText(".weather .normal.medium.feelslike span.dimmed", "Feels like 21,9°"); + await expect(weatherFunc.getText(".weather .normal.medium.feelslike span.dimmed", "Feels like 21,9°")).resolves.toBe(true); }); }); }); diff --git a/tests/e2e/modules/weather_forecast_spec.js b/tests/e2e/modules/weather_forecast_spec.js index cd03691609..da4c918875 100644 --- a/tests/e2e/modules/weather_forecast_spec.js +++ b/tests/e2e/modules/weather_forecast_spec.js @@ -1,9 +1,11 @@ const helpers = require("../helpers/global-setup"); const weatherFunc = require("../helpers/weather-functions"); +const { cleanupMockData } = require("../../utils/weather_mocker"); describe("Weather module: Weather Forecast", () => { afterAll(async () => { await helpers.stopApplication(); + await cleanupMockData(); }); describe("Default configuration", () => { @@ -13,38 +15,38 @@ describe("Weather module: Weather Forecast", () => { const days = ["Today", "Tomorrow", "Sun", "Mon", "Tue"]; for (const [index, day] of days.entries()) { - it("should render day " + day, async () => { - await weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(1)`, day); + it(`should render day ${day}`, async () => { + await expect(weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(1)`, day)).resolves.toBe(true); }); } const icons = ["day-cloudy", "rain", "day-sunny", "day-sunny", "day-sunny"]; for (const [index, icon] of icons.entries()) { - it("should render icon " + icon, async () => { + it(`should render icon ${icon}`, async () => { const elem = await helpers.waitForElement(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(2) span.wi-${icon}`); - expect(elem).not.toBe(null); + expect(elem).not.toBeNull(); }); } 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); + it(`should render max temperature ${temp}`, async () => { + await expect(weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(3)`, temp)).resolves.toBe(true); }); } 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); + it(`should render min temperature ${temp}`, async () => { + await expect(weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(4)`, temp)).resolves.toBe(true); }); } const opacities = [1, 1, 0.8, 0.5333333333333333, 0.2666666666666667]; for (const [index, opacity] of opacities.entries()) { - it("should render fading of rows with opacity=" + opacity, async () => { + it(`should render fading of rows with opacity=${opacity}`, async () => { const elem = await helpers.waitForElement(`.weather table.small tr:nth-child(${index + 1})`); - expect(elem).not.toBe(null); + expect(elem).not.toBeNull(); expect(elem.outerHTML).toContain(``); }); } @@ -57,8 +59,8 @@ describe("Weather module: Weather Forecast", () => { const days = ["Fri", "Sat", "Sun", "Mon", "Tue"]; for (const [index, day] of days.entries()) { - it("should render day " + day, async () => { - await weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(1)`, day); + it(`should render day ${day}`, async () => { + await expect(weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(1)`, day)).resolves.toBe(true); }); } }); @@ -70,27 +72,49 @@ describe("Weather module: Weather Forecast", () => { it("should render custom table class", async () => { const elem = await helpers.waitForElement(".weather table.myTableClass"); - expect(elem).not.toBe(null); + expect(elem).not.toBeNull(); }); 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); + expect(table).not.toBeNull(); + expect(table.rows).not.toBeNull(); + expect(table.rows).toHaveLength(5); }); + + const precipitations = [undefined, "2.51 mm"]; + for (const [index, precipitation] of precipitations.entries()) { + if (precipitation) { + it(`should render precipitation amount ${precipitation}`, async () => { + await expect(weatherFunc.getText(`.weather table tr:nth-child(${index + 1}) td.precipitation-amount`, precipitation)).resolves.toBe(true); + }); + } + } }); - describe("Forecast weather units", () => { + describe("Forecast weather with imperial units", () => { beforeAll(async () => { await weatherFunc.startApp("tests/configs/modules/weather/forecastweather_units.js", {}); }); - const temperatures = ["75_9°", "69_8°", "73_2°", "74_1°", "69_1°"]; - for (const [index, temp] of temperatures.entries()) { - it("should render custom decimalSymbol = '_' for temp " + temp, async () => { - await weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(3)`, temp); - }); - } + describe("Temperature units", () => { + const temperatures = ["75_9°", "69_8°", "73_2°", "74_1°", "69_1°"]; + for (const [index, temp] of temperatures.entries()) { + it(`should render custom decimalSymbol = '_' for temp ${temp}`, async () => { + await expect(weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td:nth-child(3)`, temp)).resolves.toBe(true); + }); + } + }); + + describe("Precipitation units", () => { + const precipitations = [undefined, "0.10 in"]; + for (const [index, precipitation] of precipitations.entries()) { + if (precipitation) { + it(`should render precipitation amount ${precipitation}`, async () => { + await expect(weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td.precipitation-amount`, precipitation)).resolves.toBe(true); + }); + } + } + }); }); }); diff --git a/tests/e2e/modules/weather_hourly_spec.js b/tests/e2e/modules/weather_hourly_spec.js new file mode 100644 index 0000000000..f61cee0546 --- /dev/null +++ b/tests/e2e/modules/weather_hourly_spec.js @@ -0,0 +1,66 @@ +const helpers = require("../helpers/global-setup"); +const weatherFunc = require("../helpers/weather-functions"); +const { cleanupMockData } = require("../../utils/weather_mocker"); + +describe("Weather module: Weather Hourly Forecast", () => { + afterAll(async () => { + await helpers.stopApplication(); + await cleanupMockData(); + }); + + describe("Default configuration", () => { + beforeAll(async () => { + await weatherFunc.startApp("tests/configs/modules/weather/hourlyweather_default.js", {}); + }); + + const minTemps = ["7:00 pm", "8:00 pm", "9:00 pm", "10:00 pm", "11:00 pm"]; + for (const [index, hour] of minTemps.entries()) { + it(`should render forecast for hour ${hour}`, async () => { + await expect(weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td.day`, hour)).resolves.toBe(true); + }); + } + }); + + describe("Hourly weather options", () => { + beforeAll(async () => { + await weatherFunc.startApp("tests/configs/modules/weather/hourlyweather_options.js", {}); + }); + + describe("Hourly increments of 2", () => { + const minTemps = ["7:00 pm", "9:00 pm", "11:00 pm", "1:00 am", "3:00 am"]; + for (const [index, hour] of minTemps.entries()) { + it(`should render forecast for hour ${hour}`, async () => { + await expect(weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td.day`, hour)).resolves.toBe(true); + }); + } + }); + }); + + describe("Show precipitations", () => { + beforeAll(async () => { + await weatherFunc.startApp("tests/configs/modules/weather/hourlyweather_showPrecipitation.js", {}); + }); + + describe("Shows precipitation amount", () => { + const amounts = [undefined, undefined, undefined, "0.13 mm", "0.13 mm"]; + for (const [index, amount] of amounts.entries()) { + if (amount) { + it(`should render precipitation amount ${amount}`, async () => { + await expect(weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td.precipitation-amount`, amount)).resolves.toBe(true); + }); + } + } + }); + + describe("Shows precipitation probability", () => { + const propabilities = [undefined, undefined, "12 %", "36 %", "44 %"]; + for (const [index, pop] of propabilities.entries()) { + if (pop) { + it(`should render probability ${pop}`, async () => { + await expect(weatherFunc.getText(`.weather table.small tr:nth-child(${index + 1}) td.precipitation-prob`, pop)).resolves.toBe(true); + }); + } + } + }); + }); +}); diff --git a/tests/e2e/modules_display_spec.js b/tests/e2e/modules_display_spec.js index 15520d05c9..c8dba6e9f8 100644 --- a/tests/e2e/modules_display_spec.js +++ b/tests/e2e/modules_display_spec.js @@ -11,14 +11,14 @@ describe("Display of modules", () => { it("should show the test header", async () => { const elem = await helpers.waitForElement("#module_0_helloworld .module-header"); - expect(elem).not.toBe(null); + expect(elem).not.toBeNull(); // 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", async () => { const elem = await helpers.waitForElement("#module_1_helloworld .module-header"); - expect(elem).not.toBe(null); + expect(elem).not.toBeNull(); expect(elem.textContent).toBe("undefined"); }); }); diff --git a/tests/e2e/modules_empty_spec.js b/tests/e2e/modules_empty_spec.js index ddd08e821e..535e3141c8 100644 --- a/tests/e2e/modules_empty_spec.js +++ b/tests/e2e/modules_empty_spec.js @@ -9,15 +9,15 @@ describe("Check configuration without modules", () => { await helpers.stopApplication(); }); - it("Show the message MagicMirror² title", async () => { + it("shows the message MagicMirror² title", async () => { const elem = await helpers.waitForElement("#module_1_helloworld .module-content"); - expect(elem).not.toBe(null); + expect(elem).not.toBeNull(); expect(elem.textContent).toContain("MagicMirror²"); }); - it("Show the url of michael's website", async () => { + it("shows the url of michael's website", async () => { const elem = await helpers.waitForElement("#module_5_helloworld .module-content"); - expect(elem).not.toBe(null); + expect(elem).not.toBeNull(); expect(elem.textContent).toContain("www.michaelteeuw.nl"); }); }); diff --git a/tests/e2e/modules_position_spec.js b/tests/e2e/modules_position_spec.js index 606c95a2bc..0aa8379092 100644 --- a/tests/e2e/modules_position_spec.js +++ b/tests/e2e/modules_position_spec.js @@ -13,10 +13,10 @@ describe("Position of modules", () => { for (const position of positions) { const className = position.replace("_", "."); - it("should show text in " + position, async () => { - const elem = await helpers.waitForElement("." + className); - 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.toBeNull(); + expect(elem.textContent).toContain(`Text in ${position}`); }); } }); diff --git a/tests/e2e/port_spec.js b/tests/e2e/port_spec.js index 104b9373dc..f6900a3dd5 100644 --- a/tests/e2e/port_spec.js +++ b/tests/e2e/port_spec.js @@ -10,7 +10,7 @@ describe("port directive configuration", () => { }); it("should return 200", async () => { - const res = await helpers.fetch("http://localhost:8090"); + const res = await fetch("http://localhost:8090"); expect(res.status).toBe(200); }); }); @@ -24,7 +24,7 @@ describe("port directive configuration", () => { }); it("should return 200", async () => { - const res = await helpers.fetch("http://localhost:8100"); + const res = await fetch("http://localhost:8100"); expect(res.status).toBe(200); }); }); diff --git a/tests/e2e/serveronly_spec.js b/tests/e2e/serveronly_spec.js new file mode 100644 index 0000000000..c33a78d292 --- /dev/null +++ b/tests/e2e/serveronly_spec.js @@ -0,0 +1,26 @@ +const delay = (time) => { + return new Promise((resolve) => setTimeout(resolve, time)); +}; + +describe("App environment", () => { + let serverProcess; + beforeAll(async () => { + process.env.MM_CONFIG_FILE = "tests/configs/default.js"; + serverProcess = await require("node:child_process").spawn("npm", ["run", "server"], { env: process.env, detached: true }); + // we have to wait until the server is startet + await delay(2000); + }); + afterAll(async () => { + await process.kill(-serverProcess.pid); + }); + + it("get request from http://localhost:8080 should return 200", async () => { + const res = await fetch("http://localhost:8080"); + expect(res.status).toBe(200); + }); + + it("get request from http://localhost:8080/nothing should return 404", async () => { + const res = await fetch("http://localhost:8080/nothing"); + expect(res.status).toBe(404); + }); +}); diff --git a/tests/e2e/template_spec.js b/tests/e2e/template_spec.js new file mode 100644 index 0000000000..23005564ed --- /dev/null +++ b/tests/e2e/template_spec.js @@ -0,0 +1,21 @@ +const fs = require("node:fs"); +const helpers = require("./helpers/global-setup"); + +describe("templated config with port variable", () => { + beforeAll(async () => { + await helpers.startApplication("tests/configs/port_variable.js"); + }); + afterAll(async () => { + await helpers.stopApplication(); + try { + fs.unlinkSync("tests/configs/port_variable.js"); + } catch (err) { + // do nothing + } + }); + + it("should return 200", async () => { + const res = await fetch("http://localhost:8090"); + expect(res.status).toBe(200); + }); +}); diff --git a/tests/e2e/translations_spec.js b/tests/e2e/translations_spec.js index 4d2d1c1e9d..07a99e218c 100644 --- a/tests/e2e/translations_spec.js +++ b/tests/e2e/translations_spec.js @@ -1,10 +1,10 @@ -const fs = require("fs"); -const path = require("path"); -const translations = require("../../translations/translations.js"); +const fs = require("node:fs"); +const path = require("node:path"); const helmet = require("helmet"); const { JSDOM } = require("jsdom"); const express = require("express"); const sinon = require("sinon"); +const translations = require("../../translations/translations"); describe("Translations", () => { let server; @@ -21,8 +21,8 @@ describe("Translations", () => { server = app.listen(3000); }); - afterAll(() => { - server.close(); + afterAll(async () => { + await server.close(); }); it("should have a translation file in the specified path", () => { @@ -44,109 +44,110 @@ describe("Translations", () => { ); }); - it("should load translation file", (done) => { - dom.window.onload = async () => { - const { Translator, Module, config } = dom.window; - config.language = "en"; - Translator.load = sinon.stub().callsFake((_m, _f, _fb, callback) => callback()); + it("should load translation file", () => { + return new Promise((done) => { + dom.window.onload = async () => { + const { Translator, Module, config } = dom.window; + config.language = "en"; + Translator.load = sinon.stub().callsFake((_m, _f, _fb) => null); - Module.register("name", { getTranslations: () => translations }); - const MMM = Module.create("name"); + Module.register("name", { getTranslations: () => translations }); + const MMM = Module.create("name"); - const loaded = sinon.stub(); - MMM.loadTranslations(loaded); + await MMM.loadTranslations(); - expect(loaded.callCount).toBe(1); - expect(Translator.load.args.length).toBe(1); - expect(Translator.load.calledWith(MMM, "translations/en.json", false, sinon.match.func)).toBe(true); + expect(Translator.load.args).toHaveLength(1); + expect(Translator.load.calledWith(MMM, "translations/en.json", false)).toBe(true); - done(); - }; + done(); + }; + }); }); - it("should load translation + fallback file", (done) => { - dom.window.onload = async () => { - const { Translator, Module } = dom.window; - Translator.load = sinon.stub().callsFake((_m, _f, _fb, callback) => callback()); + it("should load translation + fallback file", () => { + return new Promise((done) => { + dom.window.onload = async () => { + const { Translator, Module } = dom.window; + Translator.load = sinon.stub().callsFake((_m, _f, _fb) => null); - Module.register("name", { getTranslations: () => translations }); - const MMM = Module.create("name"); + Module.register("name", { getTranslations: () => translations }); + const MMM = Module.create("name"); - const loaded = sinon.stub(); - MMM.loadTranslations(loaded); + await MMM.loadTranslations(); - expect(loaded.callCount).toBe(1); - expect(Translator.load.args.length).toBe(2); - expect(Translator.load.calledWith(MMM, "translations/de.json", false, sinon.match.func)).toBe(true); - expect(Translator.load.calledWith(MMM, "translations/en.json", true, sinon.match.func)).toBe(true); + expect(Translator.load.args).toHaveLength(2); + expect(Translator.load.calledWith(MMM, "translations/de.json", false)).toBe(true); + expect(Translator.load.calledWith(MMM, "translations/en.json", true)).toBe(true); - done(); - }; + done(); + }; + }); }); - it("should load translation fallback file", (done) => { - dom.window.onload = async () => { - const { Translator, Module, config } = dom.window; - config.language = "--"; - Translator.load = sinon.stub().callsFake((_m, _f, _fb, callback) => callback()); + it("should load translation fallback file", () => { + return new Promise((done) => { + dom.window.onload = async () => { + const { Translator, Module, config } = dom.window; + config.language = "--"; + Translator.load = sinon.stub().callsFake((_m, _f, _fb) => null); - Module.register("name", { getTranslations: () => translations }); - const MMM = Module.create("name"); + Module.register("name", { getTranslations: () => translations }); + const MMM = Module.create("name"); - const loaded = sinon.stub(); - MMM.loadTranslations(loaded); + await MMM.loadTranslations(); - expect(loaded.callCount).toBe(1); - expect(Translator.load.args.length).toBe(1); - expect(Translator.load.calledWith(MMM, "translations/en.json", true, sinon.match.func)).toBe(true); + expect(Translator.load.args).toHaveLength(1); + expect(Translator.load.calledWith(MMM, "translations/en.json", true)).toBe(true); - done(); - }; + done(); + }; + }); }); - it("should load no file", (done) => { - dom.window.onload = async () => { - const { Translator, Module } = dom.window; - Translator.load = sinon.stub(); + it("should load no file", () => { + return new Promise((done) => { + dom.window.onload = async () => { + const { Translator, Module } = dom.window; + Translator.load = sinon.stub(); - Module.register("name", {}); - const MMM = Module.create("name"); + Module.register("name", {}); + const MMM = Module.create("name"); - const loaded = sinon.stub(); - MMM.loadTranslations(loaded); + await MMM.loadTranslations(); - expect(loaded.callCount).toBe(1); - expect(Translator.load.callCount).toBe(0); + expect(Translator.load.callCount).toBe(0); - done(); - }; + done(); + }; + }); }); }); const mmm = { name: "TranslationTest", - file(file) { + file (file) { return `http://localhost:3000/${file}`; } }; describe("Parsing language files through the Translator class", () => { for (let language in translations) { - it(`should parse ${language}`, (done) => { - const dom = new JSDOM( - `\ + it(`should parse ${language}`, () => { + return new Promise((done) => { + const dom = new JSDOM( + `\ \ + beforeAll(() => { + return new Promise((done) => { + const dom = new JSDOM( + `\ \ + beforeAll(() => { + return new Promise((done) => { + const dom = new JSDOM( + `\ \ + beforeAll(() => { + return new Promise((done) => { + dom = new JSDOM( + `\ \ + it("should load core translations and fallback", () => { + return new Promise((done) => { + const dom = new JSDOM( + `\ \ + it("should load core fallback if language cannot be found", () => { + return new Promise((done) => { + const dom = new JSDOM( + `\ \ + it("should load core translations fallback", () => { + return new Promise((done) => { + const dom = new JSDOM( + `\ \ + it("should load core fallback if language cannot be found", () => { + return new Promise((done) => { + const dom = new JSDOM( + `\ \ + beforeAll(() => { + return new Promise((done) => { + const dom = new JSDOM( + `\