diff --git a/.eslintrc.js b/.eslintrc.js index 731a3f4f..5583f605 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -1,90 +1,90 @@ module.exports = { - extends: ['erb', 'plugin:typescript-sort-keys/recommended'], - ignorePatterns: ['.erb/*', 'server'], - parser: '@typescript-eslint/parser', - parserOptions: { - createDefaultProgram: true, - ecmaVersion: 12, + extends: ['erb', 'plugin:typescript-sort-keys/recommended'], + ignorePatterns: ['.erb/*', 'server'], parser: '@typescript-eslint/parser', - project: './tsconfig.json', - sourceType: 'module', - tsconfigRootDir: './', - }, - plugins: ['@typescript-eslint', 'import', 'sort-keys-fix'], - rules: { - '@typescript-eslint/naming-convention': 'off', - '@typescript-eslint/no-explicit-any': 'off', - '@typescript-eslint/no-non-null-assertion': 'off', - '@typescript-eslint/no-shadow': ['off'], - 'default-case': 'off', - 'import/extensions': 'off', - 'import/no-absolute-path': 'off', - // A temporary hack related to IDE not resolving correct package.json - 'import/no-extraneous-dependencies': 'off', - - 'import/no-unresolved': 'error', - 'import/order': [ - 'error', - { - alphabetize: { - caseInsensitive: true, - order: 'asc', - }, - groups: ['builtin', 'external', 'internal', ['parent', 'sibling']], - 'newlines-between': 'never', - pathGroups: [ - { - group: 'external', - pattern: 'react', - position: 'before', - }, - ], - pathGroupsExcludedImportTypes: ['react'], - }, - ], - 'import/prefer-default-export': 'off', - 'jsx-a11y/click-events-have-key-events': 'off', - 'jsx-a11y/interactive-supports-focus': 'off', - 'jsx-a11y/media-has-caption': 'off', - 'no-await-in-loop': 'off', - 'no-console': 'off', - 'no-nested-ternary': 'off', - 'no-restricted-syntax': 'off', - 'no-underscore-dangle': 'off', - 'prefer-destructuring': 'off', - 'react/jsx-props-no-spreading': 'off', - 'react/jsx-sort-props': [ - 'error', - { - callbacksLast: true, - ignoreCase: false, - noSortAlphabetically: false, - reservedFirst: true, - shorthandFirst: true, - shorthandLast: false, - }, - ], - 'react/no-array-index-key': 'off', - 'react/react-in-jsx-scope': 'off', - 'react/require-default-props': 'off', - 'sort-keys-fix/sort-keys-fix': 'warn', - }, - settings: { - 'import/parsers': { - '@typescript-eslint/parser': ['.ts', '.tsx'], - }, - 'import/resolver': { - // See https://github.com/benmosher/eslint-plugin-import/issues/1396#issuecomment-575727774 for line below - node: { - extensions: ['.js', '.jsx', '.ts', '.tsx'], - }, - typescript: { - alwaysTryTypes: true, + parserOptions: { + createDefaultProgram: true, + ecmaVersion: 12, + parser: '@typescript-eslint/parser', project: './tsconfig.json', - }, - webpack: { - config: require.resolve('./.erb/configs/webpack.config.eslint.ts'), - }, + sourceType: 'module', + tsconfigRootDir: './', + }, + plugins: ['@typescript-eslint', 'import', 'sort-keys-fix'], + rules: { + '@typescript-eslint/naming-convention': 'off', + '@typescript-eslint/no-explicit-any': 'off', + '@typescript-eslint/no-non-null-assertion': 'off', + '@typescript-eslint/no-shadow': ['off'], + 'default-case': 'off', + 'import/extensions': 'off', + 'import/no-absolute-path': 'off', + // A temporary hack related to IDE not resolving correct package.json + 'import/no-extraneous-dependencies': 'off', + + 'import/no-unresolved': 'error', + 'import/order': [ + 'error', + { + alphabetize: { + caseInsensitive: true, + order: 'asc', + }, + groups: ['builtin', 'external', 'internal', ['parent', 'sibling']], + 'newlines-between': 'never', + pathGroups: [ + { + group: 'external', + pattern: 'react', + position: 'before', + }, + ], + pathGroupsExcludedImportTypes: ['react'], + }, + ], + 'import/prefer-default-export': 'off', + 'jsx-a11y/click-events-have-key-events': 'off', + 'jsx-a11y/interactive-supports-focus': 'off', + 'jsx-a11y/media-has-caption': 'off', + 'no-await-in-loop': 'off', + 'no-console': 'off', + 'no-nested-ternary': 'off', + 'no-restricted-syntax': 'off', + 'no-underscore-dangle': 'off', + 'prefer-destructuring': 'off', + 'react/jsx-props-no-spreading': 'off', + 'react/jsx-sort-props': [ + 'error', + { + callbacksLast: true, + ignoreCase: false, + noSortAlphabetically: false, + reservedFirst: true, + shorthandFirst: true, + shorthandLast: false, + }, + ], + 'react/no-array-index-key': 'off', + 'react/react-in-jsx-scope': 'off', + 'react/require-default-props': 'off', + 'sort-keys-fix/sort-keys-fix': 'warn', + }, + settings: { + 'import/parsers': { + '@typescript-eslint/parser': ['.ts', '.tsx'], + }, + 'import/resolver': { + // See https://github.com/benmosher/eslint-plugin-import/issues/1396#issuecomment-575727774 for line below + node: { + extensions: ['.js', '.jsx', '.ts', '.tsx'], + }, + typescript: { + alwaysTryTypes: true, + project: './tsconfig.json', + }, + webpack: { + config: require.resolve('./.erb/configs/webpack.config.eslint.ts'), + }, + }, }, - }, }; diff --git a/.github/ISSUE_TEMPLATE/1-Bug_report.md b/.github/ISSUE_TEMPLATE/1-Bug_report.md index d0952ccd..8f2b5724 100644 --- a/.github/ISSUE_TEMPLATE/1-Bug_report.md +++ b/.github/ISSUE_TEMPLATE/1-Bug_report.md @@ -39,7 +39,7 @@ labels: 'bug' -- Application version (e.g. v0.1.0) : -- Operating System and version (e.g. Windows 10) : -- Server and version (e.g. Navidrome v0.48.0) : -- Node version (if developing locally) : +- Application version (e.g. v0.1.0) : +- Operating System and version (e.g. Windows 10) : +- Server and version (e.g. Navidrome v0.48.0) : +- Node version (if developing locally) : diff --git a/.github/config.yml b/.github/config.yml index 3708b464..0199c952 100644 --- a/.github/config.yml +++ b/.github/config.yml @@ -1,6 +1,6 @@ requiredHeaders: - - Prerequisites - - Expected Behavior - - Current Behavior - - Possible Solution - - Your Environment + - Prerequisites + - Expected Behavior + - Current Behavior + - Possible Solution + - Your Environment diff --git a/.github/stale.yml b/.github/stale.yml index 5e2b3ad8..9209da76 100644 --- a/.github/stale.yml +++ b/.github/stale.yml @@ -4,14 +4,14 @@ daysUntilStale: 60 daysUntilClose: 7 # Issues with these labels will never be considered stale exemptLabels: - - discussion - - security + - discussion + - security # Label to use when marking an issue as stale staleLabel: wontfix # Comment to post when marking an issue as stale. Set to `false` to disable markComment: > - This issue has been automatically marked as stale because it has not had - recent activity. It will be closed if no further activity occurs. Thank you - for your contributions. + This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions. + + # Comment to post when closing a stale issue. Set to `false` to disable closeComment: false diff --git a/.github/workflows/publish-linux.yml b/.github/workflows/publish-linux.yml index 5acf335f..4d2d0398 100644 --- a/.github/workflows/publish-linux.yml +++ b/.github/workflows/publish-linux.yml @@ -3,37 +3,37 @@ name: Publish Linux (Manual) on: workflow_dispatch jobs: - publish: - runs-on: ${{ matrix.os }} + publish: + runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [ubuntu-latest] + strategy: + matrix: + os: [ubuntu-latest] - steps: - - name: Checkout git repo - uses: actions/checkout@v1 + steps: + - name: Checkout git repo + uses: actions/checkout@v1 - - name: Install Node and NPM - uses: actions/setup-node@v1 - with: - node-version: 16 - cache: npm + - name: Install Node and NPM + uses: actions/setup-node@v1 + with: + node-version: 16 + cache: npm - - name: Install dependencies - run: | - npm install --legacy-peer-deps + - name: Install dependencies + run: | + npm install --legacy-peer-deps - - name: Publish releases - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - uses: nick-invision/retry@v2.8.2 - with: - timeout_minutes: 30 - max_attempts: 3 - retry_on: error - command: | - npm run postinstall - npm run build - npm exec electron-builder -- --publish always --linux - on_retry_command: npm cache clean --force + - name: Publish releases + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: nick-invision/retry@v2.8.2 + with: + timeout_minutes: 30 + max_attempts: 3 + retry_on: error + command: | + npm run postinstall + npm run build + npm exec electron-builder -- --publish always --linux + on_retry_command: npm cache clean --force diff --git a/.github/workflows/publish-macos.yml b/.github/workflows/publish-macos.yml index cff56d00..ede05887 100644 --- a/.github/workflows/publish-macos.yml +++ b/.github/workflows/publish-macos.yml @@ -3,37 +3,37 @@ name: Publish Windows and macOS (Manual) on: workflow_dispatch jobs: - publish: - runs-on: ${{ matrix.os }} + publish: + runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [macos-latest] + strategy: + matrix: + os: [macos-latest] - steps: - - name: Checkout git repo - uses: actions/checkout@v1 + steps: + - name: Checkout git repo + uses: actions/checkout@v1 - - name: Install Node and NPM - uses: actions/setup-node@v1 - with: - node-version: 16 - cache: npm + - name: Install Node and NPM + uses: actions/setup-node@v1 + with: + node-version: 16 + cache: npm - - name: Install dependencies - run: | - npm install --legacy-peer-deps + - name: Install dependencies + run: | + npm install --legacy-peer-deps - - name: Publish releases - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - uses: nick-invision/retry@v2.8.2 - with: - timeout_minutes: 30 - max_attempts: 3 - retry_on: error - command: | - npm run postinstall - npm run build - npm exec electron-builder -- --publish always --win --mac - on_retry_command: npm cache clean --force + - name: Publish releases + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: nick-invision/retry@v2.8.2 + with: + timeout_minutes: 30 + max_attempts: 3 + retry_on: error + command: | + npm run postinstall + npm run build + npm exec electron-builder -- --publish always --win --mac + on_retry_command: npm cache clean --force diff --git a/.github/workflows/publish-pr-comment.yml b/.github/workflows/publish-pr-comment.yml index 99e5ac76..b061a8aa 100644 --- a/.github/workflows/publish-pr-comment.yml +++ b/.github/workflows/publish-pr-comment.yml @@ -1,54 +1,54 @@ name: Comment on pull request on: - workflow_run: - workflows: ['Publish (PR)'] - types: [completed] + workflow_run: + workflows: ['Publish (PR)'] + types: [completed] jobs: - pr_comment: - if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' - runs-on: ubuntu-latest - steps: - - uses: actions/github-script@v6 - with: - # This snippet is public-domain, taken from - # https://github.com/oprypin/nightly.link/blob/master/.github/workflows/pr-comment.yml - script: | - async function upsertComment(owner, repo, issue_number, purpose, body) { - const {data: comments} = await github.rest.issues.listComments( - {owner, repo, issue_number}); - const marker = ``; - body = marker + "\n" + body; - const existing = comments.filter((c) => c.body.includes(marker)); - if (existing.length > 0) { - const last = existing[existing.length - 1]; - core.info(`Updating comment ${last.id}`); - await github.rest.issues.updateComment({ - owner, repo, - body, - comment_id: last.id, - }); - } else { - core.info(`Creating a comment in issue / PR #${issue_number}`); - await github.rest.issues.createComment({issue_number, body, owner, repo}); - } - } - const {owner, repo} = context.repo; - const run_id = ${{github.event.workflow_run.id}}; - const pull_requests = ${{ toJSON(github.event.workflow_run.pull_requests) }}; - if (!pull_requests.length) { - return core.error("This workflow doesn't match any pull requests!"); - } - const artifacts = await github.paginate( - github.rest.actions.listWorkflowRunArtifacts, {owner, repo, run_id}); - if (!artifacts.length) { - return core.error(`No artifacts found`); - } - let body = `Download the artifacts for this pull request:\n`; - for (const art of artifacts) { - body += `\n* [${art.name}.zip](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`; - } - core.info("Review thread message body:", body); - for (const pr of pull_requests) { - await upsertComment(owner, repo, pr.number, - "nightly-link", body); - } + pr_comment: + if: github.event.workflow_run.event == 'pull_request' && github.event.workflow_run.conclusion == 'success' + runs-on: ubuntu-latest + steps: + - uses: actions/github-script@v6 + with: + # This snippet is public-domain, taken from + # https://github.com/oprypin/nightly.link/blob/master/.github/workflows/pr-comment.yml + script: | + async function upsertComment(owner, repo, issue_number, purpose, body) { + const {data: comments} = await github.rest.issues.listComments( + {owner, repo, issue_number}); + const marker = ``; + body = marker + "\n" + body; + const existing = comments.filter((c) => c.body.includes(marker)); + if (existing.length > 0) { + const last = existing[existing.length - 1]; + core.info(`Updating comment ${last.id}`); + await github.rest.issues.updateComment({ + owner, repo, + body, + comment_id: last.id, + }); + } else { + core.info(`Creating a comment in issue / PR #${issue_number}`); + await github.rest.issues.createComment({issue_number, body, owner, repo}); + } + } + const {owner, repo} = context.repo; + const run_id = ${{github.event.workflow_run.id}}; + const pull_requests = ${{ toJSON(github.event.workflow_run.pull_requests) }}; + if (!pull_requests.length) { + return core.error("This workflow doesn't match any pull requests!"); + } + const artifacts = await github.paginate( + github.rest.actions.listWorkflowRunArtifacts, {owner, repo, run_id}); + if (!artifacts.length) { + return core.error(`No artifacts found`); + } + let body = `Download the artifacts for this pull request:\n`; + for (const art of artifacts) { + body += `\n* [${art.name}.zip](https://nightly.link/${owner}/${repo}/actions/artifacts/${art.id}.zip)`; + } + core.info("Review thread message body:", body); + for (const pr of pull_requests) { + await upsertComment(owner, repo, pr.number, + "nightly-link", body); + } diff --git a/.github/workflows/publish-pr.yml b/.github/workflows/publish-pr.yml index 0ea3bac4..12fc24c6 100644 --- a/.github/workflows/publish-pr.yml +++ b/.github/workflows/publish-pr.yml @@ -1,60 +1,60 @@ name: Publish (PR) on: - pull_request: - branches: - - development + pull_request: + branches: + - development jobs: - publish: - runs-on: ${{ matrix.os }} + publish: + runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [macos-latest] + strategy: + matrix: + os: [macos-latest] - steps: - - name: Checkout git repo - uses: actions/checkout@v3 + steps: + - name: Checkout git repo + uses: actions/checkout@v3 - - name: Install Node and NPM - uses: actions/setup-node@v3 - with: - node-version: 16 - cache: npm + - name: Install Node and NPM + uses: actions/setup-node@v3 + with: + node-version: 16 + cache: npm - - name: Install dependencies - run: | - npm install --legacy-peer-deps + - name: Install dependencies + run: | + npm install --legacy-peer-deps - - name: Build releases - uses: nick-invision/retry@v2.8.2 - with: - timeout_minutes: 30 - max_attempts: 3 - retry_on: error - command: | - npm run postinstall - npm run build - npm run package:pr - on_retry_command: npm cache clean --force + - name: Build releases + uses: nick-invision/retry@v2.8.2 + with: + timeout_minutes: 30 + max_attempts: 3 + retry_on: error + command: | + npm run postinstall + npm run build + npm run package:pr + on_retry_command: npm cache clean --force - - uses: actions/upload-artifact@v3 - with: - name: windows-binaries - path: | - release/build/*.exe + - uses: actions/upload-artifact@v3 + with: + name: windows-binaries + path: | + release/build/*.exe - - uses: actions/upload-artifact@v3 - with: - name: linux-binaries - path: | - release/build/*.AppImage - release/build/*.deb - release/build/*.rpm + - uses: actions/upload-artifact@v3 + with: + name: linux-binaries + path: | + release/build/*.AppImage + release/build/*.deb + release/build/*.rpm - - uses: actions/upload-artifact@v3 - with: - name: macos-binaries - path: | - release/build/*.dmg + - uses: actions/upload-artifact@v3 + with: + name: macos-binaries + path: | + release/build/*.dmg diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f1456df6..34e13e03 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -3,32 +3,32 @@ name: Test on: [push, pull_request] jobs: - release: - runs-on: ${{ matrix.os }} + release: + runs-on: ${{ matrix.os }} - strategy: - matrix: - os: [macos-latest, windows-latest, ubuntu-latest] + strategy: + matrix: + os: [macos-latest, windows-latest, ubuntu-latest] - steps: - - name: Check out Git repository - uses: actions/checkout@v1 + steps: + - name: Check out Git repository + uses: actions/checkout@v1 - - name: Install Node.js and NPM - uses: actions/setup-node@v2 - with: - node-version: 16 - cache: npm + - name: Install Node.js and NPM + uses: actions/setup-node@v2 + with: + node-version: 16 + cache: npm - - name: npm install - run: | - npm install --legacy-peer-deps + - name: npm install + run: | + npm install --legacy-peer-deps - - name: npm test - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - npm run package - npm run lint - npm exec tsc - npm test + - name: npm test + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + npm run lint + npm run package + npm exec tsc + npm test diff --git a/.stylelintrc.json b/.stylelintrc.json index e617469d..73ad2585 100644 --- a/.stylelintrc.json +++ b/.stylelintrc.json @@ -1,31 +1,28 @@ { - "processors": ["stylelint-processor-styled-components"], - "customSyntax": "postcss-scss", - "extends": [ - "stylelint-config-standard-scss", - "stylelint-config-styled-components", - "stylelint-config-rational-order" - ], - "rules": { - "color-function-notation": ["legacy"], - "declaration-empty-line-before": null, - "order/properties-order": [], - "plugin/rational-order": [ - true, - { - "border-in-box-model": false, - "empty-line-between-groups": false - } + "processors": ["stylelint-processor-styled-components"], + "customSyntax": "postcss-scss", + "extends": [ + "stylelint-config-standard-scss", + "stylelint-config-styled-components", + "stylelint-config-rational-order" ], - "string-quotes": "single", - "declaration-block-no-redundant-longhand-properties": null, - "selector-class-pattern": null, - "selector-type-case": ["lower", { "ignoreTypes": ["/^\\$\\w+/"] }], - "selector-type-no-unknown": [ - true, - { "ignoreTypes": ["/-styled-mixin/", "/^\\$\\w+/"] } - ], - "value-keyword-case": ["lower", { "ignoreKeywords": ["dummyValue"] }], - "declaration-colon-newline-after": null - } + "rules": { + "color-function-notation": ["legacy"], + "declaration-empty-line-before": null, + "order/properties-order": [], + "plugin/rational-order": [ + true, + { + "border-in-box-model": false, + "empty-line-between-groups": false + } + ], + "string-quotes": "single", + "declaration-block-no-redundant-longhand-properties": null, + "selector-class-pattern": null, + "selector-type-case": ["lower", { "ignoreTypes": ["/^\\$\\w+/"] }], + "selector-type-no-unknown": [true, { "ignoreTypes": ["/-styled-mixin/", "/^\\$\\w+/"] }], + "value-keyword-case": ["lower", { "ignoreKeywords": ["dummyValue"] }], + "declaration-colon-newline-after": null + } } diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 8c2398e2..30c60314 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,8 +1,8 @@ { - "recommendations": [ - "dbaeumer.vscode-eslint", - "EditorConfig.EditorConfig", - "stylelint.vscode-stylelint", - "esbenp.prettier-vscode" - ] + "recommendations": [ + "dbaeumer.vscode-eslint", + "EditorConfig.EditorConfig", + "stylelint.vscode-stylelint", + "esbenp.prettier-vscode" + ] } diff --git a/.vscode/launch.json b/.vscode/launch.json index acd2b9fb..9c06cf39 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -1,30 +1,28 @@ { - "version": "0.2.0", - "configurations": [ - { - "name": "Electron: Main", - "type": "node", - "request": "launch", - "protocol": "inspector", - "runtimeExecutable": "npm", - "runtimeArgs": [ - "run start:main --inspect=5858 --remote-debugging-port=9223" - ], - "preLaunchTask": "Start Webpack Dev" - }, - { - "name": "Electron: Renderer", - "type": "chrome", - "request": "attach", - "port": 9223, - "webRoot": "${workspaceFolder}", - "timeout": 15000 - } - ], - "compounds": [ - { - "name": "Electron: All", - "configurations": ["Electron: Main", "Electron: Renderer"] - } - ] + "version": "0.2.0", + "configurations": [ + { + "name": "Electron: Main", + "type": "node", + "request": "launch", + "protocol": "inspector", + "runtimeExecutable": "npm", + "runtimeArgs": ["run start:main --inspect=5858 --remote-debugging-port=9223"], + "preLaunchTask": "Start Webpack Dev" + }, + { + "name": "Electron: Renderer", + "type": "chrome", + "request": "attach", + "port": 9223, + "webRoot": "${workspaceFolder}", + "timeout": 15000 + } + ], + "compounds": [ + { + "name": "Electron: All", + "configurations": ["Electron: Main", "Electron: Renderer"] + } + ] } diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 42cb7401..e0c639bd 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,25 +1,25 @@ { - "version": "2.0.0", - "tasks": [ - { - "type": "npm", - "label": "Start Webpack Dev", - "script": "start:renderer", - "options": { - "cwd": "${workspaceFolder}" - }, - "isBackground": true, - "problemMatcher": { - "owner": "custom", - "pattern": { - "regexp": "____________" - }, - "background": { - "activeOnStart": true, - "beginsPattern": "Compiling\\.\\.\\.$", - "endsPattern": "(Compiled successfully|Failed to compile)\\.$" + "version": "2.0.0", + "tasks": [ + { + "type": "npm", + "label": "Start Webpack Dev", + "script": "start:renderer", + "options": { + "cwd": "${workspaceFolder}" + }, + "isBackground": true, + "problemMatcher": { + "owner": "custom", + "pattern": { + "regexp": "____________" + }, + "background": { + "activeOnStart": true, + "beginsPattern": "Compiling\\.\\.\\.$", + "endsPattern": "(Compiled successfully|Failed to compile)\\.$" + } + } } - } - } - ] + ] } diff --git a/assets/assets.d.ts b/assets/assets.d.ts index a0938fb1..cf652454 100644 --- a/assets/assets.d.ts +++ b/assets/assets.d.ts @@ -1,31 +1,31 @@ type Styles = Record; declare module '*.svg' { - const content: string; - export default content; + const content: string; + export default content; } declare module '*.png' { - const content: string; - export default content; + const content: string; + export default content; } declare module '*.jpg' { - const content: string; - export default content; + const content: string; + export default content; } declare module '*.scss' { - const content: Styles; - export default content; + const content: Styles; + export default content; } declare module '*.sass' { - const content: Styles; - export default content; + const content: Styles; + export default content; } declare module '*.css' { - const content: Styles; - export default content; + const content: Styles; + export default content; } diff --git a/package-lock.json b/package-lock.json index bed53283..60cc1759 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,41316 +1,41316 @@ { - "name": "feishin", - "version": "0.2.0", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "feishin", - "version": "0.2.0", - "hasInstallScript": true, - "license": "GPL-3.0", - "dependencies": { - "@ag-grid-community/client-side-row-model": "^28.2.1", - "@ag-grid-community/core": "^28.2.1", - "@ag-grid-community/infinite-row-model": "^28.2.1", - "@ag-grid-community/react": "^28.2.1", - "@ag-grid-community/styles": "^28.2.1", - "@emotion/react": "^11.10.4", - "@mantine/core": "^6.0.13", - "@mantine/dates": "^6.0.13", - "@mantine/form": "^6.0.13", - "@mantine/hooks": "^6.0.13", - "@mantine/modals": "^6.0.13", - "@mantine/notifications": "^6.0.13", - "@mantine/utils": "^6.0.13", - "@tanstack/react-query": "^4.29.5", - "@tanstack/react-query-devtools": "^4.29.6", - "@ts-rest/core": "^3.23.0", - "axios": "^1.4.0", - "cmdk": "^0.2.0", - "dayjs": "^1.11.6", - "electron-debug": "^3.2.0", - "electron-localshortcut": "^3.2.1", - "electron-log": "^4.4.6", - "electron-store": "^8.1.0", - "electron-updater": "^4.6.5", - "fast-average-color": "^9.3.0", - "format-duration": "^2.0.0", - "framer-motion": "^9.1.7", - "fuse.js": "^6.6.2", - "history": "^5.3.0", - "i18next": "^21.6.16", - "immer": "^9.0.21", - "is-electron": "^2.2.2", - "lodash": "^4.17.21", - "md5": "^2.3.0", - "memoize-one": "^6.0.0", - "nanoid": "^3.3.3", - "net": "^1.0.2", - "node-mpv": "github:jeffvli/Node-MPV", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-error-boundary": "^3.1.4", - "react-i18next": "^11.16.7", - "react-icons": "^4.8.0", - "react-player": "^2.11.0", - "react-router": "^6.5.0", - "react-router-dom": "^6.5.0", - "react-simple-img": "^3.0.0", - "react-virtualized-auto-sizer": "^1.0.17", - "react-window": "^1.8.9", - "react-window-infinite-loader": "^1.0.9", - "styled-components": "^5.3.11", - "swiper": "^9.3.1", - "zod": "^3.21.4", - "zustand": "^4.3.8" - }, - "devDependencies": { - "@electron/rebuild": "^3.2.10", - "@pmmmwh/react-refresh-webpack-plugin": "0.5.5", - "@stylelint/postcss-css-in-js": "^0.38.0", - "@teamsupercell/typings-for-css-modules-loader": "^2.5.1", - "@testing-library/jest-dom": "^5.16.4", - "@testing-library/react": "^13.0.0", - "@types/electron-localshortcut": "^3.1.0", - "@types/jest": "^27.4.1", - "@types/lodash": "^4.14.188", - "@types/md5": "^2.3.2", - "@types/node": "^17.0.23", - "@types/react": "^18.0.25", - "@types/react-dom": "^18.0.8", - "@types/react-test-renderer": "^17.0.1", - "@types/react-virtualized-auto-sizer": "^1.0.1", - "@types/react-window": "^1.8.5", - "@types/react-window-infinite-loader": "^1.0.6", - "@types/styled-components": "^5.1.26", - "@types/terser-webpack-plugin": "^5.0.4", - "@types/webpack-bundle-analyzer": "^4.4.1", - "@types/webpack-env": "^1.16.3", - "@typescript-eslint/eslint-plugin": "^5.47.0", - "@typescript-eslint/parser": "^5.47.0", - "browserslist-config-erb": "^0.0.3", - "chalk": "^4.1.2", - "concurrently": "^7.1.0", - "core-js": "^3.21.1", - "cross-env": "^7.0.3", - "css-loader": "^6.7.1", - "css-minimizer-webpack-plugin": "^3.4.1", - "detect-port": "^1.3.0", - "electron": "^22.3.1", - "electron-builder": "^24.0.0-alpha.13", - "electron-devtools-installer": "^3.2.0", - "electron-notarize": "^1.2.1", - "electronmon": "^2.0.2", - "eslint": "^8.30.0", - "eslint-config-airbnb-base": "^15.0.0", - "eslint-config-erb": "^4.0.3", - "eslint-import-resolver-typescript": "^2.7.1", - "eslint-import-resolver-webpack": "^0.13.2", - "eslint-plugin-compat": "^4.0.2", - "eslint-plugin-import": "^2.26.0", - "eslint-plugin-jest": "^26.1.3", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-promise": "^6.0.0", - "eslint-plugin-react": "^7.29.4", - "eslint-plugin-react-hooks": "^4.4.0", - "eslint-plugin-sort-keys-fix": "^1.1.2", - "eslint-plugin-typescript-sort-keys": "^2.1.0", - "file-loader": "^6.2.0", - "html-webpack-plugin": "^5.5.0", - "husky": "^7.0.4", - "i18next-parser": "^6.3.0", - "identity-obj-proxy": "^3.0.0", - "jest": "^27.5.1", - "lint-staged": "^12.3.7", - "mini-css-extract-plugin": "^2.6.0", - "postcss-scss": "^4.0.4", - "postcss-syntax": "^0.36.2", - "prettier": "^2.6.2", - "react-refresh": "^0.12.0", - "react-refresh-typescript": "^2.0.4", - "react-test-renderer": "^18.0.0", - "rimraf": "^3.0.2", - "sass": "^1.49.11", - "sass-loader": "^12.6.0", - "style-loader": "^3.3.1", - "stylelint": "^14.9.1", - "stylelint-config-rational-order": "^0.1.2", - "stylelint-config-standard-scss": "^4.0.0", - "stylelint-config-styled-components": "^0.1.1", - "stylelint-order": "^5.0.0", - "stylelint-processor-styled-components": "^1.10.0", - "terser-webpack-plugin": "^5.3.1", - "ts-jest": "^27.1.4", - "ts-loader": "^9.2.8", - "ts-node": "^10.7.0", - "tsconfig-paths-webpack-plugin": "^4.0.0", - "typescript": "^4.8.4", - "typescript-plugin-styled-components": "^2.0.0", - "url-loader": "^4.1.1", - "webpack": "^5.71.0", - "webpack-bundle-analyzer": "^4.5.0", - "webpack-cli": "^4.9.2", - "webpack-dev-server": "^4.8.0", - "webpack-merge": "^5.8.0" - } - }, - "node_modules/@ag-grid-community/client-side-row-model": { - "version": "28.2.1", - "resolved": "https://registry.npmjs.org/@ag-grid-community/client-side-row-model/-/client-side-row-model-28.2.1.tgz", - "integrity": "sha512-JLLNVNAtSbVjg/h0+JqNxbRGzHR9xl3YHO4kVt8Bu0UO1XQLfGLT8wkzqQTcEOiq0pEfFTee7/BGT3oHOQfUQg==", - "dependencies": { - "@ag-grid-community/core": "~28.2.1" - } - }, - "node_modules/@ag-grid-community/core": { - "version": "28.2.1", - "resolved": "https://registry.npmjs.org/@ag-grid-community/core/-/core-28.2.1.tgz", - "integrity": "sha512-qGhqZhY8KbPlr3cJBVkNjGKu+cOyFc8IGvPcvlm0pjNC9cdxO/ct9Sa1Dg+k3ACCEroMEt1apBvnoOgurpvewQ==" - }, - "node_modules/@ag-grid-community/infinite-row-model": { - "version": "28.2.1", - "resolved": "https://registry.npmjs.org/@ag-grid-community/infinite-row-model/-/infinite-row-model-28.2.1.tgz", - "integrity": "sha512-jvEvVNQ/USlQjGW0LbryR4/I1ZSgOBPn4tg45KWm3+R0jmDSfetI20D5t3UaSQHY6ZQMDVYxR3xSkorPFI3Vng==", - "dependencies": { - "@ag-grid-community/core": "~28.2.1" - } - }, - "node_modules/@ag-grid-community/react": { - "version": "28.2.1", - "resolved": "https://registry.npmjs.org/@ag-grid-community/react/-/react-28.2.1.tgz", - "integrity": "sha512-VWtiBMhvDKp//lIa2Ovzv+/gcQj6wnZDhngyPW5e97Sl+sIs6/UngHSTbbmhIb+wWUCIKmSRL1+R05PNnKjFTA==", - "dependencies": { - "prop-types": "^15.8.1" - }, - "peerDependencies": { - "@ag-grid-community/core": "~28.2.1", - "react": "^16.3.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.3.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@ag-grid-community/styles": { - "version": "28.2.1", - "resolved": "https://registry.npmjs.org/@ag-grid-community/styles/-/styles-28.2.1.tgz", - "integrity": "sha512-dy3Z46zTnzrwJOnH+tFvIvY9g/8qIi+b7XmbQlmATBr9zcNMk0wqWH1/9sNHs1fFW6m3Csvu4ctyzdr9mSw1YA==" - }, - "node_modules/@ampproject/remapping": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz", - "integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==", - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.0" - }, - "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==", - "dependencies": { - "@babel/highlight": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/compat-data": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", - "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz", - "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", - "dependencies": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.5", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-module-transforms": "^7.20.2", - "@babel/helpers": "^7.20.5", - "@babel/parser": "^7.20.5", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@babel/core/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@babel/generator": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz", - "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", - "dependencies": { - "@babel/types": "^7.20.5", - "@jridgewell/gen-mapping": "^0.3.2", - "jsesc": "^2.5.1" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-annotate-as-pure": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", - "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-compilation-targets": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", - "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", - "dependencies": { - "@babel/compat-data": "^7.20.0", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@babel/helper-compilation-targets/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "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==", - "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==", - "dependencies": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" - }, - "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==", - "dependencies": { - "@babel/types": "^7.18.6" - }, - "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==", - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-module-transforms": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", - "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", - "dependencies": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-plugin-utils": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", - "dependencies": { - "@babel/types": "^7.20.2" - }, - "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==", - "dependencies": { - "@babel/types": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", - "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==", - "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==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/helpers": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", - "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", - "dependencies": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5" - }, - "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==", - "dependencies": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/highlight/node_modules/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==", - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/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==", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/@babel/highlight/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" - }, - "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==", - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/@babel/highlight/node_modules/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==", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/highlight/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/parser": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", - "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==", - "bin": { - "parser": "bin/babel-parser.js" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@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, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@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, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@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, - "dependencies": { - "@babel/helper-plugin-utils": "^7.12.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@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, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@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, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "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==", - "dependencies": { - "@babel/helper-plugin-utils": "^7.18.6" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@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, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@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, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@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, - "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@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, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@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, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@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, - "dependencies": { - "@babel/helper-plugin-utils": "^7.8.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@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, - "dependencies": { - "@babel/helper-plugin-utils": "^7.14.5" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/plugin-syntax-typescript": { - "version": "7.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz", - "integrity": "sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==", - "dev": true, - "dependencies": { - "@babel/helper-plugin-utils": "^7.16.7" - }, - "engines": { - "node": ">=6.9.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/@babel/runtime": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz", - "integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==", - "dependencies": { - "regenerator-runtime": "^0.13.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/runtime-corejs3": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.17.9.tgz", - "integrity": "sha512-WxYHHUWF2uZ7Hp1K+D1xQgbgkGUfA+5UPOegEXGt2Y5SMog/rYCVaifLZDbw8UkNXozEqqrZTy6bglL7xTaCOw==", - "dev": true, - "dependencies": { - "core-js-pure": "^3.20.2", - "regenerator-runtime": "^0.13.4" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz", - "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", - "dependencies": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.5", - "@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.20.5", - "@babel/types": "^7.20.5", - "debug": "^4.1.0", - "globals": "^11.1.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@babel/traverse/node_modules/globals": { - "version": "11.12.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", - "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", - "engines": { - "node": ">=4" - } - }, - "node_modules/@babel/types": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", - "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", - "dependencies": { - "@babel/helper-string-parser": "^7.19.4", - "@babel/helper-validator-identifier": "^7.19.1", - "to-fast-properties": "^2.0.0" - }, - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/@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 - }, - "node_modules/@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-consumer": "0.8.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@csstools/selector-specificity": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.1.tgz", - "integrity": "sha512-aG20vknL4/YjQF9BSV7ts4EWm/yrjagAN7OWBNmlbEOUiu0llj4OGrFoOKK3g2vey4/p2omKCoHrWtPxSwV3HA==", - "dev": true, - "engines": { - "node": "^12 || ^14 || >=16" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/csstools" - }, - "peerDependencies": { - "postcss": "^8.3", - "postcss-selector-parser": "^6.0.10" - } - }, - "node_modules/@develar/schema-utils": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz", - "integrity": "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==", - "dev": true, - "dependencies": { - "ajv": "^6.12.0", - "ajv-keywords": "^3.4.1" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/@electron/asar": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.3.tgz", - "integrity": "sha512-wmOfE6szYyqZhRIiLH+eyZEp+bGcJI0OD/SCvSUrfBE0jvauyGYO2ZhpWxmNCcDojKu5DYrsVqT5BOCZZ01XIg==", - "dev": true, - "dependencies": { - "chromium-pickle-js": "^0.2.0", - "commander": "^5.0.0", - "glob": "^7.1.6", - "minimatch": "^3.0.4" - }, - "bin": { - "asar": "bin/asar.js" - }, - "engines": { - "node": ">=10.12.0" - }, - "optionalDependencies": { - "@types/glob": "^7.1.1" - } - }, - "node_modules/@electron/get": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.2.tgz", - "integrity": "sha512-eFZVFoRXb3GFGd7Ak7W4+6jBl9wBtiZ4AaYOse97ej6mKj5tkyO0dUnUChs1IhJZtx1BENo4/p4WUTXpi6vT+g==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "env-paths": "^2.2.0", - "fs-extra": "^8.1.0", - "got": "^11.8.5", - "progress": "^2.0.3", - "semver": "^6.2.0", - "sumchecker": "^3.0.1" - }, - "engines": { - "node": ">=12" - }, - "optionalDependencies": { - "global-agent": "^3.0.0" - } - }, - "node_modules/@electron/get/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/@electron/notarize": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-1.2.3.tgz", - "integrity": "sha512-9oRzT56rKh5bspk3KpAVF8lPKHYQrBnRwcgiOeR0hdilVEQmszDaAu0IPCPrwwzJN0ugNs0rRboTreHMt/6mBQ==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "fs-extra": "^9.0.1" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@electron/notarize/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@electron/notarize/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@electron/notarize/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@electron/osx-sign": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.0.4.tgz", - "integrity": "sha512-xfhdEcIOfAZg7scZ9RQPya1G1lWo8/zMCwUXAulq0SfY7ONIW+b9qGyKdMyuMctNYwllrIS+vmxfijSfjeh97g==", - "dev": true, - "dependencies": { - "compare-version": "^0.1.2", - "debug": "^4.3.4", - "fs-extra": "^10.0.0", - "isbinaryfile": "^4.0.8", - "minimist": "^1.2.6", - "plist": "^3.0.5" - }, - "bin": { - "electron-osx-flat": "bin/electron-osx-flat.js", - "electron-osx-sign": "bin/electron-osx-sign.js" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/@electron/osx-sign/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@electron/osx-sign/node_modules/isbinaryfile": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", - "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", - "dev": true, - "engines": { - "node": ">= 8.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/gjtorikian/" - } - }, - "node_modules/@electron/osx-sign/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@electron/osx-sign/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@electron/rebuild": { - "version": "3.2.10", - "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.2.10.tgz", - "integrity": "sha512-SUBM6Mwi3yZaDFQjZzfGKpYTtOp9m60glounwX6tfGeVc/ZOl4jbquktUcyy7gYSLDWFLtKkftkY2xgMJZLQgg==", - "dev": true, - "dependencies": { - "@malept/cross-spawn-promise": "^2.0.0", - "chalk": "^4.0.0", - "debug": "^4.1.1", - "detect-libc": "^2.0.1", - "fs-extra": "^10.0.0", - "got": "^11.7.0", - "lzma-native": "^8.0.5", - "node-abi": "^3.0.0", - "node-api-version": "^0.1.4", - "node-gyp": "^9.0.0", - "ora": "^5.1.0", - "semver": "^7.3.5", - "tar": "^6.0.5", - "yargs": "^17.0.1" - }, - "bin": { - "electron-rebuild": "lib/src/cli.js" - }, - "engines": { - "node": ">=12.13.0" - } - }, - "node_modules/@electron/rebuild/node_modules/@malept/cross-spawn-promise": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-2.0.0.tgz", - "integrity": "sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/malept" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" - } - ], - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "engines": { - "node": ">= 12.13.0" - } - }, - "node_modules/@electron/rebuild/node_modules/@npmcli/fs": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", - "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", - "dev": true, - "dependencies": { - "@gar/promisify": "^1.1.3", - "semver": "^7.3.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/@electron/rebuild/node_modules/@npmcli/move-file": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", - "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", - "deprecated": "This functionality has been moved to @npmcli/fs", - "dev": true, - "dependencies": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/@electron/rebuild/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/@electron/rebuild/node_modules/cacache": { - "version": "16.1.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", - "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", - "dev": true, - "dependencies": { - "@npmcli/fs": "^2.1.0", - "@npmcli/move-file": "^2.0.0", - "chownr": "^2.0.0", - "fs-minipass": "^2.1.0", - "glob": "^8.0.1", - "infer-owner": "^1.0.4", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "mkdirp": "^1.0.4", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^9.0.0", - "tar": "^6.1.11", - "unique-filename": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/@electron/rebuild/node_modules/cacache/node_modules/glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^5.0.1", - "once": "^1.3.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/@electron/rebuild/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, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@electron/rebuild/node_modules/detect-libc": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", - "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@electron/rebuild/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@electron/rebuild/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@electron/rebuild/node_modules/lru-cache": { - "version": "7.18.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.1.tgz", - "integrity": "sha512-8/HcIENyQnfUTCDizRu9rrDyG6XG/21M4X7/YEGZeD76ZJilFPAUVb/2zysFf7VVO1LEjCDFyHp8pMMvozIrvg==", - "dev": true, - "engines": { - "node": ">=12" - } - }, - "node_modules/@electron/rebuild/node_modules/make-fetch-happen": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", - "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", - "dev": true, - "dependencies": { - "agentkeepalive": "^4.2.1", - "cacache": "^16.1.0", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^2.0.3", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^9.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/@electron/rebuild/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@electron/rebuild/node_modules/minipass-fetch": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", - "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", - "dev": true, - "dependencies": { - "minipass": "^3.1.6", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - }, - "optionalDependencies": { - "encoding": "^0.1.13" - } - }, - "node_modules/@electron/rebuild/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@electron/rebuild/node_modules/node-gyp": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.3.1.tgz", - "integrity": "sha512-4Q16ZCqq3g8awk6UplT7AuxQ35XN4R/yf/+wSAwcBUAjg7l58RTactWaP8fIDTi0FzI7YcVLujwExakZlfWkXg==", - "dev": true, - "dependencies": { - "env-paths": "^2.2.0", - "glob": "^7.1.4", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^10.0.3", - "nopt": "^6.0.0", - "npmlog": "^6.0.0", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^2.0.2" - }, - "bin": { - "node-gyp": "bin/node-gyp.js" - }, - "engines": { - "node": "^12.13 || ^14.13 || >=16" - } - }, - "node_modules/@electron/rebuild/node_modules/nopt": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", - "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", - "dev": true, - "dependencies": { - "abbrev": "^1.0.0" - }, - "bin": { - "nopt": "bin/nopt.js" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/@electron/rebuild/node_modules/socks-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", - "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", - "dev": true, - "dependencies": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@electron/rebuild/node_modules/ssri": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", - "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", - "dev": true, - "dependencies": { - "minipass": "^3.1.1" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/@electron/rebuild/node_modules/unique-filename": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", - "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", - "dev": true, - "dependencies": { - "unique-slug": "^3.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/@electron/rebuild/node_modules/unique-slug": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", - "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "node_modules/@electron/rebuild/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@electron/rebuild/node_modules/yargs": { - "version": "17.7.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", - "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", - "dev": true, - "dependencies": { - "cliui": "^8.0.1", - "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.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@electron/rebuild/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, - "engines": { - "node": ">=12" - } - }, - "node_modules/@electron/universal": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-1.3.4.tgz", - "integrity": "sha512-BdhBgm2ZBnYyYRLRgOjM5VHkyFItsbggJ0MHycOjKWdFGYwK97ZFXH54dTvUWEfha81vfvwr5On6XBjt99uDcg==", - "dev": true, - "dependencies": { - "@electron/asar": "^3.2.1", - "@malept/cross-spawn-promise": "^1.1.0", - "debug": "^4.3.1", - "dir-compare": "^3.0.0", - "fs-extra": "^9.0.1", - "minimatch": "^3.0.4", - "plist": "^3.0.4" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/@electron/universal/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@electron/universal/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@electron/universal/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@emotion/babel-plugin": { - "version": "11.10.2", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.2.tgz", - "integrity": "sha512-xNQ57njWTFVfPAc3cjfuaPdsgLp5QOSuRsj9MA6ndEhH/AzuZM86qIQzt6rq+aGBwj3n5/TkLmU5lhAfdRmogA==", - "dependencies": { - "@babel/helper-module-imports": "^7.16.7", - "@babel/plugin-syntax-jsx": "^7.17.12", - "@babel/runtime": "^7.18.3", - "@emotion/hash": "^0.9.0", - "@emotion/memoize": "^0.8.0", - "@emotion/serialize": "^1.1.0", - "babel-plugin-macros": "^3.1.0", - "convert-source-map": "^1.5.0", - "escape-string-regexp": "^4.0.0", - "find-root": "^1.1.0", - "source-map": "^0.5.7", - "stylis": "4.0.13" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/@emotion/babel-plugin/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@emotion/cache": { - "version": "11.10.3", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.3.tgz", - "integrity": "sha512-Psmp/7ovAa8appWh3g51goxu/z3iVms7JXOreq136D8Bbn6dYraPnmL6mdM8GThEx9vwSn92Fz+mGSjBzN8UPQ==", - "dependencies": { - "@emotion/memoize": "^0.8.0", - "@emotion/sheet": "^1.2.0", - "@emotion/utils": "^1.2.0", - "@emotion/weak-memoize": "^0.3.0", - "stylis": "4.0.13" - } - }, - "node_modules/@emotion/hash": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz", - "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==" - }, - "node_modules/@emotion/is-prop-valid": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", - "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", - "dependencies": { - "@emotion/memoize": "^0.8.0" - } - }, - "node_modules/@emotion/memoize": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", - "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" - }, - "node_modules/@emotion/react": { - "version": "11.10.4", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.4.tgz", - "integrity": "sha512-j0AkMpr6BL8gldJZ6XQsQ8DnS9TxEQu1R+OGmDZiWjBAJtCcbt0tS3I/YffoqHXxH6MjgI7KdMbYKw3MEiU9eA==", - "dependencies": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.10.0", - "@emotion/cache": "^11.10.0", - "@emotion/serialize": "^1.1.0", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@emotion/utils": "^1.2.0", - "@emotion/weak-memoize": "^0.3.0", - "hoist-non-react-statics": "^3.3.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0", - "react": ">=16.8.0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@types/react": { - "optional": true - } - } - }, - "node_modules/@emotion/serialize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.0.tgz", - "integrity": "sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA==", - "dependencies": { - "@emotion/hash": "^0.9.0", - "@emotion/memoize": "^0.8.0", - "@emotion/unitless": "^0.8.0", - "@emotion/utils": "^1.2.0", - "csstype": "^3.0.2" - } - }, - "node_modules/@emotion/serialize/node_modules/@emotion/unitless": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", - "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" - }, - "node_modules/@emotion/sheet": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.0.tgz", - "integrity": "sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w==" - }, - "node_modules/@emotion/stylis": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", - "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" - }, - "node_modules/@emotion/unitless": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" - }, - "node_modules/@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz", - "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==", - "peerDependencies": { - "react": ">=16.8.0" - } - }, - "node_modules/@emotion/utils": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz", - "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==" - }, - "node_modules/@emotion/weak-memoize": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz", - "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==" - }, - "node_modules/@eslint/eslintrc": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.0.tgz", - "integrity": "sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A==", - "dev": true, - "dependencies": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.19.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": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@floating-ui/core": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.2.1.tgz", - "integrity": "sha512-LSqwPZkK3rYfD7GKoIeExXOyYx6Q1O4iqZWwIehDNuv3Dv425FIAE8PRwtAx1imEolFTHgBEcoFHm9MDnYgPCg==" - }, - "node_modules/@floating-ui/dom": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.2.1.tgz", - "integrity": "sha512-Rt45SmRiV8eU+xXSB9t0uMYiQ/ZWGE/jumse2o3i5RGlyvcbqOF4q+1qBnzLE2kZ5JGhq0iMkcGXUKbFe7MpTA==", - "dependencies": { - "@floating-ui/core": "^1.2.1" - } - }, - "node_modules/@floating-ui/react": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.19.2.tgz", - "integrity": "sha512-JyNk4A0Ezirq8FlXECvRtQOX/iBe5Ize0W/pLkrZjfHW9GUV7Xnq6zm6fyZuQzaHHqEnVizmvlA96e1/CkZv+w==", - "dependencies": { - "@floating-ui/react-dom": "^1.3.0", - "aria-hidden": "^1.1.3", - "tabbable": "^6.0.1" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/@floating-ui/react-dom": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-1.3.0.tgz", - "integrity": "sha512-htwHm67Ji5E/pROEAr7f8IKFShuiCKHwUC/UY4vC3I5jiSvGFAYnSYiZO5MlGmads+QqvUkR9ANHEguGrDv72g==", - "dependencies": { - "@floating-ui/dom": "^1.2.1" - }, - "peerDependencies": { - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/@gar/promisify": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "dev": true - }, - "node_modules/@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", - "dev": true, - "dependencies": { - "@humanwhocodes/object-schema": "^1.2.1", - "debug": "^4.1.1", - "minimatch": "^3.0.5" - }, - "engines": { - "node": ">=10.10.0" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">=12.22" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/nzakas" - } - }, - "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==", - "dev": true - }, - "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, - "dependencies": { - "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" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", - "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", - "dev": true, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", - "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", - "dev": true, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "dev": true, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", - "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", - "dev": true, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/@istanbuljs/load-nyc-config/node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/@jest/console": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", - "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/core": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", - "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", - "dev": true, - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/reporters": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^27.5.1", - "jest-config": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-resolve-dependencies": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "jest-watcher": "^27.5.1", - "micromatch": "^4.0.4", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/environment": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", - "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", - "dev": true, - "dependencies": { - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/fake-timers": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", - "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/globals": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", - "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/types": "^27.5.1", - "expect": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/reporters": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", - "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", - "dev": true, - "dependencies": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "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-haste-map": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/@jest/reporters/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jest/source-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", - "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", - "dev": true, - "dependencies": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9", - "source-map": "^0.6.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/source-map/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jest/test-result": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", - "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", - "dev": true, - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/test-sequencer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", - "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", - "dev": true, - "dependencies": { - "@jest/test-result": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-runtime": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/transform": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", - "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", - "dev": true, - "dependencies": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.5.1", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-util": "^27.5.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/transform/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/@jest/types/node_modules/@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", - "dev": true, - "dependencies": { - "@types/yargs-parser": "*" - } - }, - "node_modules/@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==", - "dependencies": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - }, - "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==", - "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==", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/source-map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", - "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", - "dev": true, - "dependencies": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "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==" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", - "dependencies": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "node_modules/@leichtgewicht/ip-codec": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz", - "integrity": "sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg==", - "dev": true - }, - "node_modules/@malept/cross-spawn-promise": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", - "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/malept" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" - } - ], - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@malept/flatpak-bundler": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz", - "integrity": "sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "fs-extra": "^9.0.0", - "lodash": "^4.17.15", - "tmp-promise": "^3.0.2" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@malept/flatpak-bundler/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@malept/flatpak-bundler/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/@malept/flatpak-bundler/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/@mantine/core": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@mantine/core/-/core-6.0.13.tgz", - "integrity": "sha512-FjVUGgat2qISV9WD1maVJa81y7H0JjKJ3m0cJj65PzgrXT20hzdEda7S3i4j+a8vUnx+836x5q/yS+RDHvoSlA==", - "dependencies": { - "@floating-ui/react": "^0.19.1", - "@mantine/styles": "6.0.13", - "@mantine/utils": "6.0.13", - "@radix-ui/react-scroll-area": "1.0.2", - "react-remove-scroll": "^2.5.5", - "react-textarea-autosize": "8.3.4" - }, - "peerDependencies": { - "@mantine/hooks": "6.0.13", - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/@mantine/dates": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@mantine/dates/-/dates-6.0.13.tgz", - "integrity": "sha512-sWStU+sgblTZAfuuFlwG3w3WCFYHVf1L+sG2WdlXOljd9WpQVem214HTh6staJ894+vIQESIvseWvq6FDyQAaQ==", - "dependencies": { - "@mantine/utils": "6.0.13" - }, - "peerDependencies": { - "@mantine/core": "6.0.13", - "@mantine/hooks": "6.0.13", - "dayjs": ">=1.0.0", - "react": ">=16.8.0" - } - }, - "node_modules/@mantine/form": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@mantine/form/-/form-6.0.13.tgz", - "integrity": "sha512-oR/bnnJEd6T42N5pUhXYZ5RaKC4EZozEFW2jHCWDKIAJDjIgGUQrLL/tCjclQ2NwtghaoCTz+9zu32CuXer7TA==", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "klona": "^2.0.5" - }, - "peerDependencies": { - "react": ">=16.8.0" - } - }, - "node_modules/@mantine/hooks": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-6.0.13.tgz", - "integrity": "sha512-fHuE3zXo5OP/Q1dMOTnegU6U+tI9GuhO2tgOz6szVuOxrrk0Hzuq1Na9NUSv27HShSRbAfQk+hvyIh+iVV7KXA==", - "peerDependencies": { - "react": ">=16.8.0" - } - }, - "node_modules/@mantine/modals": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@mantine/modals/-/modals-6.0.13.tgz", - "integrity": "sha512-R/FfH+vzk1iKxl/HDgUC0CXZI7zvQ79J+VUSw9eQcNWgSTx9IwrDbFeEtWC2SvVNaCYmMSxgadCbgjKsaeqzWA==", - "dependencies": { - "@mantine/utils": "6.0.13" - }, - "peerDependencies": { - "@mantine/core": "6.0.13", - "@mantine/hooks": "6.0.13", - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/@mantine/notifications": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@mantine/notifications/-/notifications-6.0.13.tgz", - "integrity": "sha512-d3BxNN7LEblvAsui0yGiI1q1Ji2OlhFLfe/cLdj7s5VMOtiKYRV14dICJxe4Jn/o+8Gg+UKw+aO/ZiQoT+BGIw==", - "dependencies": { - "@mantine/utils": "6.0.13", - "react-transition-group": "4.4.2" - }, - "peerDependencies": { - "@mantine/core": "6.0.13", - "@mantine/hooks": "6.0.13", - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/@mantine/styles": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@mantine/styles/-/styles-6.0.13.tgz", - "integrity": "sha512-+27oX8ObiBv8jHHDxXKjqe+7cfTJyaAV/Ie00T49EE4LuHuS6nL4vlXHmqamFtDCj2ypEWBV0sdXDev/DNAXSg==", - "dependencies": { - "clsx": "1.1.1", - "csstype": "3.0.9" - }, - "peerDependencies": { - "@emotion/react": ">=11.9.0", - "react": ">=16.8.0", - "react-dom": ">=16.8.0" - } - }, - "node_modules/@mantine/styles/node_modules/csstype": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.9.tgz", - "integrity": "sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw==" - }, - "node_modules/@mantine/utils": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@mantine/utils/-/utils-6.0.13.tgz", - "integrity": "sha512-iqIU9wurqAeccVbWjM0yr1JGne5VP+ob55M03QAXOEN4+ck93VDTjCkZJR2RFhDcs5q0twQFoOmU/gULR8aKIA==", - "peerDependencies": { - "react": ">=16.8.0" - } - }, - "node_modules/@mdn/browser-compat-data": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-4.1.15.tgz", - "integrity": "sha512-OZx2PxHtJDc9NOHGR3T0ZtX1WYl5qH/xmiH3sKSmcd3o+vPMG1kVUYbZrMxH3fVKpkkkrQpwETCIDRXcMXAWTw==", - "dev": true - }, - "node_modules/@mrmlnc/readdir-enhanced": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", - "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", - "dev": true, - "dependencies": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/@mrmlnc/readdir-enhanced/node_modules/glob-to-regexp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==", - "dev": true - }, - "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==", - "dev": true, - "dependencies": { - "@nodelib/fs.stat": "2.0.5", - "run-parallel": "^1.1.9" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@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==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@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==", - "dev": true, - "dependencies": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/@pmmmwh/react-refresh-webpack-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.5.tgz", - "integrity": "sha512-RbG7h6TuP6nFFYKJwbcToA1rjC1FyPg25NR2noAZ0vKI+la01KTSRPkuVPE+U88jXv7javx2JHglUcL1MHcshQ==", - "dev": true, - "dependencies": { - "ansi-html-community": "^0.0.8", - "common-path-prefix": "^3.0.0", - "core-js-pure": "^3.8.1", - "error-stack-parser": "^2.0.6", - "find-up": "^5.0.0", - "html-entities": "^2.1.0", - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">= 10.13" - }, - "peerDependencies": { - "@types/webpack": "4.x || 5.x", - "react-refresh": ">=0.10.0 <1.0.0", - "sockjs-client": "^1.4.0", - "type-fest": ">=0.17.0 <3.0.0", - "webpack": ">=4.43.0 <6.0.0", - "webpack-dev-server": "3.x || 4.x", - "webpack-hot-middleware": "2.x", - "webpack-plugin-serve": "0.x || 1.x" - }, - "peerDependenciesMeta": { - "@types/webpack": { - "optional": true - }, - "sockjs-client": { - "optional": true - }, - "type-fest": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - }, - "webpack-hot-middleware": { - "optional": true - }, - "webpack-plugin-serve": { - "optional": true - } - } - }, - "node_modules/@polka/url": { - "version": "1.0.0-next.21", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", - "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==", - "dev": true - }, - "node_modules/@radix-ui/number": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.0.tgz", - "integrity": "sha512-Ofwh/1HX69ZfJRiRBMTy7rgjAzHmwe4kW9C9Y99HTRUcYLUuVT0KESFj15rPjRgKJs20GPq8Bm5aEDJ8DuA3vA==", - "dependencies": { - "@babel/runtime": "^7.13.10" - } - }, - "node_modules/@radix-ui/primitive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.0.tgz", - "integrity": "sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==", - "dependencies": { - "@babel/runtime": "^7.13.10" - } - }, - "node_modules/@radix-ui/react-compose-refs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz", - "integrity": "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-context": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.0.tgz", - "integrity": "sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-dialog": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.0.tgz", - "integrity": "sha512-Yn9YU+QlHYLWwV1XfKiqnGVpWYWk6MeBVM6x/bcoyPvxgjQGoeT35482viLPctTMWoMw0PoHgqfSox7Ig+957Q==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.0", - "@radix-ui/react-compose-refs": "1.0.0", - "@radix-ui/react-context": "1.0.0", - "@radix-ui/react-dismissable-layer": "1.0.0", - "@radix-ui/react-focus-guards": "1.0.0", - "@radix-ui/react-focus-scope": "1.0.0", - "@radix-ui/react-id": "1.0.0", - "@radix-ui/react-portal": "1.0.0", - "@radix-ui/react-presence": "1.0.0", - "@radix-ui/react-primitive": "1.0.0", - "@radix-ui/react-slot": "1.0.0", - "@radix-ui/react-use-controllable-state": "1.0.0", - "aria-hidden": "^1.1.1", - "react-remove-scroll": "2.5.4" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-primitive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.0.tgz", - "integrity": "sha512-EyXe6mnRlHZ8b6f4ilTDrXmkLShICIuOTTj0GX4w1rp+wSxf3+TD05u1UOITC8VsJ2a9nwHvdXtOXEOl0Cw/zQ==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-slot": "1.0.0" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-slot": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.0.tgz", - "integrity": "sha512-3mrKauI/tWXo1Ll+gN5dHcxDPdm/Df1ufcDLCecn+pnCIVcdWE7CujXo8QaXOWRJyZyQWWbpB8eFwHzWXlv5mQ==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.0" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-dialog/node_modules/react-remove-scroll": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.4.tgz", - "integrity": "sha512-xGVKJJr0SJGQVirVFAUZ2k1QLyO6m+2fy0l8Qawbp5Jgrv3DeLalrfMNBFSlmz5kriGGzsVBtGVnf4pTKIhhWA==", - "dependencies": { - "react-remove-scroll-bar": "^2.3.3", - "react-style-singleton": "^2.2.1", - "tslib": "^2.1.0", - "use-callback-ref": "^1.3.0", - "use-sidecar": "^1.1.2" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-direction": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.0.tgz", - "integrity": "sha512-2HV05lGUgYcA6xgLQ4BKPDmtL+QbIZYH5fCOTAOOcJ5O0QbWS3i9lKaurLzliYUDhORI2Qr3pyjhJh44lKA3rQ==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.0.tgz", - "integrity": "sha512-n7kDRfx+LB1zLueRDvZ1Pd0bxdJWDUZNQ/GWoxDn2prnuJKRdxsjulejX/ePkOsLi2tTm6P24mDqlMSgQpsT6g==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.0", - "@radix-ui/react-compose-refs": "1.0.0", - "@radix-ui/react-primitive": "1.0.0", - "@radix-ui/react-use-callback-ref": "1.0.0", - "@radix-ui/react-use-escape-keydown": "1.0.0" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-dismissable-layer/node_modules/@radix-ui/react-primitive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.0.tgz", - "integrity": "sha512-EyXe6mnRlHZ8b6f4ilTDrXmkLShICIuOTTj0GX4w1rp+wSxf3+TD05u1UOITC8VsJ2a9nwHvdXtOXEOl0Cw/zQ==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-slot": "1.0.0" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-dismissable-layer/node_modules/@radix-ui/react-slot": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.0.tgz", - "integrity": "sha512-3mrKauI/tWXo1Ll+gN5dHcxDPdm/Df1ufcDLCecn+pnCIVcdWE7CujXo8QaXOWRJyZyQWWbpB8eFwHzWXlv5mQ==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.0" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-focus-guards": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.0.tgz", - "integrity": "sha512-UagjDk4ijOAnGu4WMUPj9ahi7/zJJqNZ9ZAiGPp7waUWJO0O1aWXi/udPphI0IUjvrhBsZJGSN66dR2dsueLWQ==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-focus-scope": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.0.tgz", - "integrity": "sha512-C4SWtsULLGf/2L4oGeIHlvWQx7Rf+7cX/vKOAD2dXW0A1b5QXwi3wWeaEgW+wn+SEVrraMUk05vLU9fZZz5HbQ==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.0", - "@radix-ui/react-primitive": "1.0.0", - "@radix-ui/react-use-callback-ref": "1.0.0" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-focus-scope/node_modules/@radix-ui/react-primitive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.0.tgz", - "integrity": "sha512-EyXe6mnRlHZ8b6f4ilTDrXmkLShICIuOTTj0GX4w1rp+wSxf3+TD05u1UOITC8VsJ2a9nwHvdXtOXEOl0Cw/zQ==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-slot": "1.0.0" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-focus-scope/node_modules/@radix-ui/react-slot": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.0.tgz", - "integrity": "sha512-3mrKauI/tWXo1Ll+gN5dHcxDPdm/Df1ufcDLCecn+pnCIVcdWE7CujXo8QaXOWRJyZyQWWbpB8eFwHzWXlv5mQ==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.0" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-id": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.0.tgz", - "integrity": "sha512-Q6iAB/U7Tq3NTolBBQbHTgclPmGWE3OlktGGqrClPozSw4vkQ1DfQAOtzgRPecKsMdJINE05iaoDUG8tRzCBjw==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-layout-effect": "1.0.0" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-portal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.0.tgz", - "integrity": "sha512-a8qyFO/Xb99d8wQdu4o7qnigNjTPG123uADNecz0eX4usnQEj7o+cG4ZX4zkqq98NYekT7UoEQIjxBNWIFuqTA==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-primitive": "1.0.0" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-portal/node_modules/@radix-ui/react-primitive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.0.tgz", - "integrity": "sha512-EyXe6mnRlHZ8b6f4ilTDrXmkLShICIuOTTj0GX4w1rp+wSxf3+TD05u1UOITC8VsJ2a9nwHvdXtOXEOl0Cw/zQ==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-slot": "1.0.0" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-portal/node_modules/@radix-ui/react-slot": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.0.tgz", - "integrity": "sha512-3mrKauI/tWXo1Ll+gN5dHcxDPdm/Df1ufcDLCecn+pnCIVcdWE7CujXo8QaXOWRJyZyQWWbpB8eFwHzWXlv5mQ==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.0" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-presence": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.0.tgz", - "integrity": "sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.0", - "@radix-ui/react-use-layout-effect": "1.0.0" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.1.tgz", - "integrity": "sha512-fHbmislWVkZaIdeF6GZxF0A/NH/3BjrGIYj+Ae6eTmTCr7EB0RQAAVEiqsXK6p3/JcRqVSBQoceZroj30Jj3XA==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-slot": "1.0.1" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-scroll-area": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.0.2.tgz", - "integrity": "sha512-k8VseTxI26kcKJaX0HPwkvlNBPTs56JRdYzcZ/vzrNUkDlvXBy8sMc7WvCpYzZkHgb+hd72VW9MqkqecGtuNgg==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/number": "1.0.0", - "@radix-ui/primitive": "1.0.0", - "@radix-ui/react-compose-refs": "1.0.0", - "@radix-ui/react-context": "1.0.0", - "@radix-ui/react-direction": "1.0.0", - "@radix-ui/react-presence": "1.0.0", - "@radix-ui/react-primitive": "1.0.1", - "@radix-ui/react-use-callback-ref": "1.0.0", - "@radix-ui/react-use-layout-effect": "1.0.0" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-slot": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.1.tgz", - "integrity": "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.0" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-use-callback-ref": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz", - "integrity": "sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-use-controllable-state": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.0.tgz", - "integrity": "sha512-FohDoZvk3mEXh9AWAVyRTYR4Sq7/gavuofglmiXB2g1aKyboUD4YtgWxKj8O5n+Uak52gXQ4wKz5IFST4vtJHg==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-callback-ref": "1.0.0" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-use-escape-keydown": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.0.tgz", - "integrity": "sha512-JwfBCUIfhXRxKExgIqGa4CQsiMemo1Xt0W/B4ei3fpzpvPENKpMKQ8mZSB6Acj3ebrAEgi2xiQvcI1PAAodvyg==", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-callback-ref": "1.0.0" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@radix-ui/react-use-layout-effect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.0.tgz", - "integrity": "sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ==", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, - "peerDependencies": { - "react": "^16.8 || ^17.0 || ^18.0" - } - }, - "node_modules/@remix-run/router": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.1.0.tgz", - "integrity": "sha512-rGl+jH/7x1KBCQScz9p54p0dtPLNeKGb3e0wD2H5/oZj41bwQUnXdzbj2TbUAFhvD7cp9EyEQA4dEgpUFa1O7Q==", - "engines": { - "node": ">=14" - } - }, - "node_modules/@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "dev": true, - "engines": { - "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==", - "dev": true, - "dependencies": { - "type-detect": "4.0.8" - } - }, - "node_modules/@sinonjs/fake-timers": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", - "dev": true, - "dependencies": { - "@sinonjs/commons": "^1.7.0" - } - }, - "node_modules/@stylelint/postcss-css-in-js": { - "version": "0.38.0", - "resolved": "https://registry.npmjs.org/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.38.0.tgz", - "integrity": "sha512-XOz5CAe49kS95p5yRd+DAIWDojTjfmyAQ4bbDlXMdbZTQ5t0ThjSLvWI6JI2uiS7MFurVBkZ6zUqcimzcLTBoQ==", - "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", - "dev": true, - "dependencies": { - "@babel/core": "^7.17.9" - }, - "peerDependencies": { - "postcss": ">=7.0.0", - "postcss-syntax": ">=0.36.2" - } - }, - "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==", - "dev": true, - "dependencies": { - "defer-to-connect": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@tanstack/match-sorter-utils": { - "version": "8.7.2", - "resolved": "https://registry.npmjs.org/@tanstack/match-sorter-utils/-/match-sorter-utils-8.7.2.tgz", - "integrity": "sha512-bptNeoexeDB947fWoCPwUchPSx5FA9gwzU0bkXz0du5pT8Ud2+1ob+xOgHj6EF3VN0kdXtLhwjPyhY7/dJglkg==", - "dependencies": { - "remove-accents": "0.4.2" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/kentcdodds" - } - }, - "node_modules/@tanstack/query-core": { - "version": "4.29.5", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.29.5.tgz", - "integrity": "sha512-xXIiyQ/4r9KfaJ3k6kejqcaqFXXBTzN2aOJ5H1J6aTJE9hl/nbgAdfF6oiIu0CD5xowejJEJ6bBg8TO7BN4NuQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - } - }, - "node_modules/@tanstack/react-query": { - "version": "4.29.5", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-4.29.5.tgz", - "integrity": "sha512-F87cibC3s3eG0Q90g2O+hqntpCrudKFnR8P24qkH9uccEhXErnJxBC/AAI4cJRV2bfMO8IeGZQYf3WyYgmSg0w==", - "dependencies": { - "@tanstack/query-core": "4.29.5", - "use-sync-external-store": "^1.2.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-native": "*" - }, - "peerDependenciesMeta": { - "react-dom": { - "optional": true - }, - "react-native": { - "optional": true - } - } - }, - "node_modules/@tanstack/react-query-devtools": { - "version": "4.29.6", - "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-4.29.6.tgz", - "integrity": "sha512-qpYI41a69MWmrllcGiSE1KlpmnwJY/w0yKMnmp6VXn7nVy0i5TMMAT4u8D48F1Ipv/BKIDI1lqxPAvB4MqryBg==", - "dependencies": { - "@tanstack/match-sorter-utils": "^8.7.0", - "superjson": "^1.10.0", - "use-sync-external-store": "^1.2.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - }, - "peerDependencies": { - "@tanstack/react-query": "4.29.5", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/@teamsupercell/typings-for-css-modules-loader": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@teamsupercell/typings-for-css-modules-loader/-/typings-for-css-modules-loader-2.5.2.tgz", - "integrity": "sha512-3sqH2B4itcm5XgV1IHENt4NOaW7bOC1CwJr63vrdKWWyKVxNxtBM+ABVhJZYFCCVAwNy7ulA64z6HyQqw96m4A==", - "dev": true, - "dependencies": { - "camelcase": "^5.3.1", - "loader-utils": "^1.4.2", - "schema-utils": "^2.0.1" - }, - "optionalDependencies": { - "prettier": "*" - } - }, - "node_modules/@teamsupercell/typings-for-css-modules-loader/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/@teamsupercell/typings-for-css-modules-loader/node_modules/loader-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", - "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", - "dev": true, - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/@teamsupercell/typings-for-css-modules-loader/node_modules/schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 8.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/@testing-library/dom": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.13.0.tgz", - "integrity": "sha512-9VHgfIatKNXQNaZTtLnalIy0jNZzY35a4S3oi08YAt9Hv1VsfZ/DfA45lM8D/UhtHBGJ4/lGwp0PZkVndRkoOQ==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^4.2.0", - "aria-query": "^5.0.0", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.4.4", - "pretty-format": "^27.0.2" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@testing-library/jest-dom": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.4.tgz", - "integrity": "sha512-Gy+IoFutbMQcky0k+bqqumXZ1cTGswLsFqmNLzNdSKkU9KGV2u9oXhukCbbJ9/LRPKiqwxEE8VpV/+YZlfkPUA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.9.2", - "@types/testing-library__jest-dom": "^5.9.1", - "aria-query": "^5.0.0", - "chalk": "^3.0.0", - "css": "^3.0.0", - "css.escape": "^1.5.1", - "dom-accessibility-api": "^0.5.6", - "lodash": "^4.17.15", - "redent": "^3.0.0" - }, - "engines": { - "node": ">=8", - "npm": ">=6", - "yarn": ">=1" - } - }, - "node_modules/@testing-library/jest-dom/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, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/@testing-library/react": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-13.0.0.tgz", - "integrity": "sha512-p0lYA1M7uoEmk2LnCbZLGmHJHyH59sAaZVXChTXlyhV/PRW9LoIh4mdf7tiXsO8BoNG+vN8UnFJff1hbZeXv+w==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.12.5", - "@testing-library/dom": "^8.5.0", - "@types/react-dom": "*" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.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==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/@ts-rest/core": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@ts-rest/core/-/core-3.23.0.tgz", - "integrity": "sha512-2vJwa682m9yS/xQPvPxZBluJfIZwNkt2HY9ER3UtGnu8Dijw+8iymSyIyjRLpFFWUyRnVp9IqrEi/d84bkNFIw==", - "peerDependencies": { - "zod": "^3.0.0" - }, - "peerDependenciesMeta": { - "zod": { - "optional": true - } - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", - "dev": true - }, - "node_modules/@types/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==", - "dev": true - }, - "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==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0", - "@types/babel__generator": "*", - "@types/babel__template": "*", - "@types/babel__traverse": "*" - } - }, - "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==", - "dev": true, - "dependencies": { - "@babel/types": "^7.0.0" - } - }, - "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==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.1.0", - "@babel/types": "^7.0.0" - } - }, - "node_modules/@types/babel__traverse": { - "version": "7.14.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", - "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", - "dev": true, - "dependencies": { - "@babel/types": "^7.3.0" - } - }, - "node_modules/@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", - "dev": true, - "dependencies": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "node_modules/@types/bonjour": { - "version": "3.5.10", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz", - "integrity": "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/cacheable-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", - "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", - "dev": true, - "dependencies": { - "@types/http-cache-semantics": "*", - "@types/keyv": "*", - "@types/node": "*", - "@types/responselike": "*" - } - }, - "node_modules/@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/connect-history-api-fallback": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz", - "integrity": "sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==", - "dev": true, - "dependencies": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "node_modules/@types/debug": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", - "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", - "dev": true, - "dependencies": { - "@types/ms": "*" - } - }, - "node_modules/@types/electron-localshortcut": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/electron-localshortcut/-/electron-localshortcut-3.1.0.tgz", - "integrity": "sha512-upKSXMxBPRdz5kmcXfdfn+hWH9PCAvwhyVozDXTIwwHQ1lUJcdSgGUfxOC1QBlnAPKPqcW/r4icWfMosKz8ibg==", - "dev": true, - "dependencies": { - "electron": "*" - } - }, - "node_modules/@types/eslint": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.2.tgz", - "integrity": "sha512-Z1nseZON+GEnFjJc04sv4NSALGjhFwy6K0HXt7qsn5ArfAKtb63dXNJHf+1YW6IpOIYRBGUbu3GwJdj8DGnCjA==", - "dev": true, - "dependencies": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "node_modules/@types/eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==", - "dev": true, - "dependencies": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "node_modules/@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", - "dev": true - }, - "node_modules/@types/express": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", - "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", - "dev": true, - "dependencies": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "node_modules/@types/express-serve-static-core": { - "version": "4.17.28", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", - "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", - "dev": true, - "dependencies": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "node_modules/@types/fs-extra": { - "version": "9.0.13", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", - "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "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, - "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==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/hoist-non-react-statics": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", - "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", - "dev": true, - "dependencies": { - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0" - } - }, - "node_modules/@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", - "dev": true - }, - "node_modules/@types/http-cache-semantics": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", - "dev": true - }, - "node_modules/@types/http-proxy": { - "version": "1.17.8", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.8.tgz", - "integrity": "sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "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 - }, - "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==", - "dev": true, - "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==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-report": "*" - } - }, - "node_modules/@types/jest": { - "version": "27.4.1", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", - "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", - "dev": true, - "dependencies": { - "jest-matcher-utils": "^27.0.0", - "pretty-format": "^27.0.0" - } - }, - "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 - }, - "node_modules/@types/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", - "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==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/lodash": { - "version": "4.14.188", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.188.tgz", - "integrity": "sha512-zmEmF5OIM3rb7SbLCFYoQhO4dGt2FRM9AMkxvA3LaADOF1n8in/zGJlWji9fmafLoNyz+FoL6FE0SLtGIArD7w==", - "dev": true - }, - "node_modules/@types/md5": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@types/md5/-/md5-2.3.2.tgz", - "integrity": "sha512-v+JFDu96+UYJ3/UWzB0mEglIS//MZXgRaJ4ubUPwOM0gvLc/kcQ3TWNYwENEK7/EcXGQVrW8h/XqednSjBd/Og==", - "dev": true - }, - "node_modules/@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", - "dev": true - }, - "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/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/ms": { - "version": "0.7.31", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", - "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==", - "dev": true - }, - "node_modules/@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==", - "dev": true - }, - "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 - }, - "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==" - }, - "node_modules/@types/plist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.2.tgz", - "integrity": "sha512-ULqvZNGMv0zRFvqn8/4LSPtnmN4MfhlPNtJCTpKuIIxGVGZ2rYWzFXrvEBoh9CVyqSE7D6YFRJ1hydLHI6kbWw==", - "dev": true, - "optional": true, - "dependencies": { - "@types/node": "*", - "xmlbuilder": ">=11.0.1" - } - }, - "node_modules/@types/prettier": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.3.tgz", - "integrity": "sha512-ymZk3LEC/fsut+/Q5qejp6R9O1rMxz3XaRHDV6kX8MrGAhOSPqVARbDi+EZvInBpw+BnCX3TD240byVkOfQsHg==", - "dev": true - }, - "node_modules/@types/prop-types": { - "version": "15.7.4", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", - "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==", - "devOptional": true - }, - "node_modules/@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true - }, - "node_modules/@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", - "dev": true - }, - "node_modules/@types/react": { - "version": "18.0.26", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.26.tgz", - "integrity": "sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==", - "devOptional": true, - "dependencies": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/react-dom": { - "version": "18.0.9", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.9.tgz", - "integrity": "sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==", - "dev": true, - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/@types/react-test-renderer": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-17.0.1.tgz", - "integrity": "sha512-3Fi2O6Zzq/f3QR9dRnlnHso9bMl7weKCviFmfF6B4LS1Uat6Hkm15k0ZAQuDz+UBq6B3+g+NM6IT2nr5QgPzCw==", - "dev": true, - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/@types/react-virtualized-auto-sizer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.1.tgz", - "integrity": "sha512-GH8sAnBEM5GV9LTeiz56r4ZhMOUSrP43tAQNSRVxNexDjcNKLCEtnxusAItg1owFUFE6k0NslV26gqVClVvong==", - "dev": true, - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/@types/react-window": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.5.tgz", - "integrity": "sha512-V9q3CvhC9Jk9bWBOysPGaWy/Z0lxYcTXLtLipkt2cnRj1JOSFNF7wqGpkScSXMgBwC+fnVRg/7shwgddBG5ICw==", - "dev": true, - "dependencies": { - "@types/react": "*" - } - }, - "node_modules/@types/react-window-infinite-loader": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/react-window-infinite-loader/-/react-window-infinite-loader-1.0.6.tgz", - "integrity": "sha512-V8g8sBDLVeJJAfEENJS7VXZK+DRJ+jzPNtk8jpj2G+obhf+iqGNUDGwNWCbBhLiD+KpHhf3kWQlKBRi0tAeU4Q==", - "dev": true, - "dependencies": { - "@types/react": "*", - "@types/react-window": "*" - } - }, - "node_modules/@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/retry": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz", - "integrity": "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==", - "dev": true - }, - "node_modules/@types/scheduler": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", - "devOptional": true - }, - "node_modules/@types/semver": { - "version": "7.3.13", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", - "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==" - }, - "node_modules/@types/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==", - "dev": true, - "dependencies": { - "@types/express": "*" - } - }, - "node_modules/@types/serve-static": { - "version": "1.13.10", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", - "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", - "dev": true, - "dependencies": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "node_modules/@types/sockjs": { - "version": "0.3.33", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz", - "integrity": "sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "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 - }, - "node_modules/@types/styled-components": { - "version": "5.1.26", - "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.26.tgz", - "integrity": "sha512-KuKJ9Z6xb93uJiIyxo/+ksS7yLjS1KzG6iv5i78dhVg/X3u5t1H7juRWqVmodIdz6wGVaIApo1u01kmFRdJHVw==", - "dev": true, - "dependencies": { - "@types/hoist-non-react-statics": "*", - "@types/react": "*", - "csstype": "^3.0.2" - } - }, - "node_modules/@types/symlink-or-copy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/symlink-or-copy/-/symlink-or-copy-1.2.0.tgz", - "integrity": "sha512-Lja2xYuuf2B3knEsga8ShbOdsfNOtzT73GyJmZyY7eGl2+ajOqrs8yM5ze0fsSoYwvA6bw7/Qr7OZ7PEEmYwWg==", - "dev": true - }, - "node_modules/@types/terser-webpack-plugin": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@types/terser-webpack-plugin/-/terser-webpack-plugin-5.2.0.tgz", - "integrity": "sha512-iHDR2pRfFjGyDqCALX2tgUgFtGoQf2AJhKpC2XD1IMBQVJF2bny6WChGRDKj9eaZJl4F2RmvBhxJNtVPj7aTRw==", - "deprecated": "This is a stub types definition. terser-webpack-plugin provides its own type definitions, so you do not need this installed.", - "dev": true, - "dependencies": { - "terser-webpack-plugin": "*" - } - }, - "node_modules/@types/testing-library__jest-dom": { - "version": "5.14.3", - "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.3.tgz", - "integrity": "sha512-oKZe+Mf4ioWlMuzVBaXQ9WDnEm1+umLx0InILg+yvZVBBDmzV5KfZyLrCvadtWcx8+916jLmHafcmqqffl+iIw==", - "dev": true, - "dependencies": { - "@types/jest": "*" - } - }, - "node_modules/@types/unist": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", - "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==", - "dev": true - }, - "node_modules/@types/verror": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.6.tgz", - "integrity": "sha512-NNm+gdePAX1VGvPcGZCDKQZKYSiAWigKhKaz5KF94hG6f2s8de9Ow5+7AbXoeKxL8gavZfk4UquSAygOF2duEQ==", - "dev": true, - "optional": true - }, - "node_modules/@types/vfile": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/vfile/-/vfile-3.0.2.tgz", - "integrity": "sha512-b3nLFGaGkJ9rzOcuXRfHkZMdjsawuDD0ENL9fzTophtBg8FJHSGbH7daXkEpcwy3v7Xol3pAvsmlYyFhR4pqJw==", - "dev": true, - "dependencies": { - "@types/node": "*", - "@types/unist": "*", - "@types/vfile-message": "*" - } - }, - "node_modules/@types/vfile-message": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/vfile-message/-/vfile-message-2.0.0.tgz", - "integrity": "sha512-GpTIuDpb9u4zIO165fUy9+fXcULdD8HFRNli04GehoMVbeNq7D6OBnqSmg3lxZnC+UvgUhEWKxdKiwYUkGltIw==", - "deprecated": "This is a stub types definition. vfile-message provides its own type definitions, so you do not need this installed.", - "dev": true, - "dependencies": { - "vfile-message": "*" - } - }, - "node_modules/@types/webpack-bundle-analyzer": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@types/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.4.1.tgz", - "integrity": "sha512-yQAj3l7bIYL+QRRlNJt6gyP+zrXZOlgaR4wsX0WY4yzZIbv41ZibREfZvuYjxY0iVtvQQlbhx0AeokkCuqUAQg==", - "dev": true, - "dependencies": { - "@types/node": "*", - "tapable": "^2.2.0", - "webpack": "^5" - } - }, - "node_modules/@types/webpack-env": { - "version": "1.16.3", - "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.16.3.tgz", - "integrity": "sha512-9gtOPPkfyNoEqCQgx4qJKkuNm/x0R2hKR7fdl7zvTJyHnIisuE/LfvXOsYWL0o3qq6uiBnKZNNNzi3l0y/X+xw==", - "dev": true - }, - "node_modules/@types/ws": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", - "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@types/yargs": { - "version": "17.0.24", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", - "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", - "dev": true, - "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 - }, - "node_modules/@types/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", - "dev": true, - "optional": true, - "dependencies": { - "@types/node": "*" - } - }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.47.1.tgz", - "integrity": "sha512-r4RZ2Jl9kcQN7K/dcOT+J7NAimbiis4sSM9spvWimsBvDegMhKLA5vri2jG19PmIPbDjPeWzfUPQ2hjEzA4Nmg==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "5.47.1", - "@typescript-eslint/type-utils": "5.47.1", - "@typescript-eslint/utils": "5.47.1", - "debug": "^4.3.4", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "regexpp": "^3.2.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", - "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - } - }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/scope-manager": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/types": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", - "dev": true, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/experimental-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==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/parser": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.47.1.tgz", - "integrity": "sha512-9Vb+KIv29r6GPu4EboWOnQM7T+UjpjXvjCPhNORlgm40a9Ia9bvaPJswvtae1gip2QEeVeGh6YquqAzEgoRAlw==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "5.47.1", - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/typescript-estree": "5.47.1", - "debug": "^4.3.4" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.1.tgz", - "integrity": "sha512-9hsFDsgUwrdOoW1D97Ewog7DYSHaq4WKuNs0LHF9RiCmqB0Z+XRR4Pf7u7u9z/8CciHuJ6yxNws1XznI3ddjEw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/visitor-keys": "5.47.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.47.1.tgz", - "integrity": "sha512-/UKOeo8ee80A7/GJA427oIrBi/Gd4osk/3auBUg4Rn9EahFpevVV1mUK8hjyQD5lHPqX397x6CwOk5WGh1E/1w==", - "dev": true, - "dependencies": { - "@typescript-eslint/typescript-estree": "5.47.1", - "@typescript-eslint/utils": "5.47.1", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/types": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", - "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.1.tgz", - "integrity": "sha512-4+ZhFSuISAvRi2xUszEj0xXbNTHceV9GbH9S8oAD2a/F9SW57aJNQVOCxG8GPfSWH/X4eOPdMEU2jYVuWKEpWA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/visitor-keys": "5.47.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/utils": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.47.1.tgz", - "integrity": "sha512-l90SdwqfmkuIVaREZ2ykEfCezepCLxzWMo5gVfcJsJCaT4jHT+QjgSkYhs5BMQmWqE9k3AtIfk4g211z/sTMVw==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.47.1", - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/typescript-estree": "5.47.1", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", - "semver": "^7.3.7" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.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/visitor-keys": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", - "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.47.1", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@webassemblyjs/ast": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", - "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", - "dev": true, - "dependencies": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" - } - }, - "node_modules/@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-buffer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", - "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", - "dev": true, - "dependencies": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true - }, - "node_modules/@webassemblyjs/helper-wasm-section": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", - "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6" - } - }, - "node_modules/@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "dev": true, - "dependencies": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "node_modules/@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", - "dev": true, - "dependencies": { - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true - }, - "node_modules/@webassemblyjs/wasm-edit": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", - "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-opt": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6", - "@webassemblyjs/wast-printer": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-gen": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", - "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-opt": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", - "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wasm-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", - "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "node_modules/@webassemblyjs/wast-printer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", - "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", - "dev": true, - "dependencies": { - "@webassemblyjs/ast": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "node_modules/@webpack-cli/configtest": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.1.tgz", - "integrity": "sha512-1FBc1f9G4P/AxMqIgfZgeOTuRnwZMten8E7zap5zgpPInnCrP8D4Q81+4CWIch8i/Nf7nXjP0v6CjjbHOrXhKg==", - "dev": true, - "peerDependencies": { - "webpack": "4.x.x || 5.x.x", - "webpack-cli": "4.x.x" - } - }, - "node_modules/@webpack-cli/info": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.4.1.tgz", - "integrity": "sha512-PKVGmazEq3oAo46Q63tpMr4HipI3OPfP7LiNOEJg963RMgT0rqheag28NCML0o3GIzA3DmxP1ZIAv9oTX1CUIA==", - "dev": true, - "dependencies": { - "envinfo": "^7.7.3" - }, - "peerDependencies": { - "webpack-cli": "4.x.x" - } - }, - "node_modules/@webpack-cli/serve": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.1.tgz", - "integrity": "sha512-gNGTiTrjEVQ0OcVnzsRSqTxaBSr+dmTfm+qJsCDluky8uhdLWep7Gcr62QsAKHTMxjCS/8nEITsmFAhfIx+QSw==", - "dev": true, - "peerDependencies": { - "webpack-cli": "4.x.x" - }, - "peerDependenciesMeta": { - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "node_modules/@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "node_modules/7zip-bin": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.1.1.tgz", - "integrity": "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ==", - "dev": true - }, - "node_modules/abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", - "dev": true - }, - "node_modules/abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "dev": true - }, - "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==", - "dev": true, - "dependencies": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "dependencies": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - } - }, - "node_modules/acorn-globals/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "dev": true, - "peerDependencies": { - "acorn": "^8" - } - }, - "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==", - "dev": true, - "peerDependencies": { - "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/address": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", - "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", - "dev": true, - "engines": { - "node": ">= 0.12.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, - "dependencies": { - "debug": "4" - }, - "engines": { - "node": ">= 6.0.0" - } - }, - "node_modules/agentkeepalive": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz", - "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==", - "dev": true, - "dependencies": { - "debug": "^4.1.0", - "depd": "^1.1.2", - "humanize-ms": "^1.2.1" - }, - "engines": { - "node": ">= 8.0.0" - } - }, - "node_modules/aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "dependencies": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "dependencies": { - "ajv": "^8.0.0" - }, - "peerDependencies": { - "ajv": "^8.0.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/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==" - }, - "node_modules/ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "peerDependencies": { - "ajv": "^6.9.1" - } - }, - "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, - "dependencies": { - "type-fest": "^0.21.3" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-escapes/node_modules/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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ansi-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "dev": true, - "engines": [ - "node >= 0.8.0" - ], - "bin": { - "ansi-html": "bin/ansi-html" - } - }, - "node_modules/ansi-regex": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", - "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "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, - "dependencies": { - "normalize-path": "^3.0.0", - "picomatch": "^2.0.4" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/app-builder-bin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-4.0.0.tgz", - "integrity": "sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA==", - "dev": true - }, - "node_modules/app-builder-lib": { - "version": "24.0.0-alpha.13", - "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-24.0.0-alpha.13.tgz", - "integrity": "sha512-fQa3zDl948PS+EvDaAtPTM3UvrXKns9TEQ7dR3BYWJbpIs7s0e1FxlwVLrINYGLv7hxdLkhbJ0ewPxKyj/ahpQ==", - "dev": true, - "dependencies": { - "@develar/schema-utils": "~2.6.5", - "@electron/notarize": "^1.2.3", - "@electron/osx-sign": "^1.0.4", - "@electron/rebuild": "^3.2.10", - "@electron/universal": "1.3.4", - "@malept/flatpak-bundler": "^0.4.0", - "7zip-bin": "~5.1.1", - "async-exit-hook": "^2.0.1", - "bluebird-lst": "^1.0.9", - "builder-util": "24.0.0-alpha.13", - "builder-util-runtime": "9.2.0-alpha.3", - "chromium-pickle-js": "^0.2.0", - "debug": "^4.3.4", - "ejs": "^3.1.8", - "electron-publish": "24.0.0-alpha.13", - "form-data": "^4.0.0", - "fs-extra": "^10.1.0", - "hosted-git-info": "^4.1.0", - "is-ci": "^3.0.0", - "isbinaryfile": "^5.0.0", - "js-yaml": "^4.1.0", - "lazy-val": "^1.0.5", - "minimatch": "^5.1.1", - "read-config-file": "6.3.2", - "sanitize-filename": "^1.6.3", - "semver": "^7.3.8", - "tar": "^6.1.12", - "temp-file": "^3.4.0" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/app-builder-lib/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/app-builder-lib/node_modules/builder-util-runtime": { - "version": "9.2.0-alpha.3", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.0-alpha.3.tgz", - "integrity": "sha512-1pOggEqknxVyhdASumips0/RaMaXwSCQMzwhk2jeOGOotBQuOHQHVy25kH5OaeXSFx9L7PckZHXjwZauD72zRw==", - "dev": true, - "dependencies": { - "debug": "^4.3.4", - "sax": "^1.2.4" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/app-builder-lib/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/app-builder-lib/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/app-builder-lib/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/app-builder-lib/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/append-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", - "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", - "dev": true, - "dependencies": { - "buffer-equal": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "dev": true - }, - "node_modules/are-we-there-yet": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz", - "integrity": "sha512-0GWpv50YSOcLXaN6/FAKY3vfRbllXWV2xvfA/oKJF8pzFhWXPV+yjhJXDBbjscDYowv7Yw1A3uigpzn5iEGTyw==", - "dev": true, - "dependencies": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" - } - }, - "node_modules/are-we-there-yet/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "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==" - }, - "node_modules/aria-hidden": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.2.tgz", - "integrity": "sha512-6y/ogyDTk/7YAe91T3E2PR1ALVKyM2QbTio5HwM+N1Q6CMlCKhvClyIjkckBswa0f2xJhjsfzIGa1yVSe1UMVA==", - "dependencies": { - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", - "react": "^16.9.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/aria-query": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.0.0.tgz", - "integrity": "sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg==", - "dev": true, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-find": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-find/-/array-find-1.0.0.tgz", - "integrity": "sha1-bI4obRHtdoMn+OYuzuhzU8o+eLg=", - "dev": true - }, - "node_modules/array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", - "dev": true - }, - "node_modules/array-includes": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", - "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", - "is-string": "^1.0.7" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/array.prototype.flat": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", - "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/array.prototype.tosorted": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz", - "integrity": "sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.1.3" - } - }, - "node_modules/arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, - "optional": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/ast-metadata-inferer": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.7.0.tgz", - "integrity": "sha512-OkMLzd8xelb3gmnp6ToFvvsHLtS6CbagTkFQvQ+ZYFe3/AIl9iKikNR9G7pY3GfOR/2Xc222hwBjzI7HLkE76Q==", - "dev": true, - "dependencies": { - "@mdn/browser-compat-data": "^3.3.14" - } - }, - "node_modules/ast-metadata-inferer/node_modules/@mdn/browser-compat-data": { - "version": "3.3.14", - "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-3.3.14.tgz", - "integrity": "sha512-n2RC9d6XatVbWFdHLimzzUJxJ1KY8LdjqrW6YvGPiRmsHkhOUx74/Ct10x5Yo7bC/Jvqx7cDEW8IMPv/+vwEzA==", - "dev": true - }, - "node_modules/ast-types-flow": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", - "dev": true - }, - "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", - "dev": true - }, - "node_modules/async-exit-hook": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", - "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", - "dev": true, - "engines": { - "node": ">=0.12.0" - } - }, - "node_modules/asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "node_modules/at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true, - "bin": { - "atob": "bin/atob.js" - }, - "engines": { - "node": ">= 4.5.0" - } - }, - "node_modules/atomically": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz", - "integrity": "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==", - "engines": { - "node": ">=10.12.0" - } - }, - "node_modules/autoprefixer": { - "version": "9.8.8", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz", - "integrity": "sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==", - "dev": true, - "dependencies": { - "browserslist": "^4.12.0", - "caniuse-lite": "^1.0.30001109", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "picocolors": "^0.2.1", - "postcss": "^7.0.32", - "postcss-value-parser": "^4.1.0" - }, - "bin": { - "autoprefixer": "bin/autoprefixer" - }, - "funding": { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/autoprefixer" - } - }, - "node_modules/autoprefixer/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "node_modules/autoprefixer/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/autoprefixer/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/axe-core": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.6.1.tgz", - "integrity": "sha512-lCZN5XRuOnpG4bpMq8v0khrWtUOn+i8lZSb6wHZH56ZfbIEv6XwJV84AAueh9/zi7qPVJ/E4yz6fmsiyOmXR4w==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/axios": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", - "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", - "dependencies": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "node_modules/axobject-query": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", - "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", - "dev": true - }, - "node_modules/babel-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", - "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", - "dev": true, - "dependencies": { - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.8.0" - } - }, - "node_modules/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, - "dependencies": { - "@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" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/babel-plugin-jest-hoist": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", - "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", - "dev": true, - "dependencies": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/babel-plugin-macros": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", - "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", - "dependencies": { - "@babel/runtime": "^7.12.5", - "cosmiconfig": "^7.0.0", - "resolve": "^1.19.0" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - } - }, - "node_modules/babel-plugin-styled-components": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.7.tgz", - "integrity": "sha512-i7YhvPgVqRKfoQ66toiZ06jPNA3p6ierpfUuEWxNF+fV27Uv5gxBkf8KZLHUCc1nFA9j6+80pYoIpqCeyW3/bA==", - "dependencies": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-module-imports": "^7.16.0", - "babel-plugin-syntax-jsx": "^6.18.0", - "lodash": "^4.17.11", - "picomatch": "^2.3.0" - }, - "peerDependencies": { - "styled-components": ">= 2" - } - }, - "node_modules/babel-plugin-syntax-jsx": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", - "integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==" - }, - "node_modules/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, - "dependencies": { - "@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" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/babel-preset-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", - "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", - "dev": true, - "dependencies": { - "babel-plugin-jest-hoist": "^27.5.1", - "babel-preset-current-node-syntax": "^1.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": "^7.0.0" - } - }, - "node_modules/bail": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", - "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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==", - "dev": true - }, - "node_modules/base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "dependencies": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", - "dev": true - }, - "node_modules/big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, - "node_modules/bl/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "node_modules/bluebird-lst": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.9.tgz", - "integrity": "sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw==", - "dev": true, - "dependencies": { - "bluebird": "^3.5.5" - } - }, - "node_modules/body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", - "dev": true, - "dependencies": { - "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.10.3", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "node_modules/body-parser/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/body-parser/node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/body-parser/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==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/body-parser/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/bonjour-service": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.0.11.tgz", - "integrity": "sha512-drMprzr2rDTCtgEE3VgdA9uUFaUHF+jXduwYSThHJnKMYM+FhI9Z3ph+TX3xy0LtgYHae6CHYPJ/2UnK8nQHcA==", - "dev": true, - "dependencies": { - "array-flatten": "^2.1.2", - "dns-equal": "^1.0.0", - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.4" - } - }, - "node_modules/boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", - "dev": true - }, - "node_modules/boolean": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", - "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", - "dev": true, - "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==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "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, - "dependencies": { - "fill-range": "^7.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/broccoli-node-api": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/broccoli-node-api/-/broccoli-node-api-1.7.0.tgz", - "integrity": "sha512-QIqLSVJWJUVOhclmkmypJJH9u9s/aWH4+FH6Q6Ju5l+Io4dtwqdPUNmDfw40o6sxhbZHhqGujDJuHTML1wG8Yw==", - "dev": true - }, - "node_modules/broccoli-node-info": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/broccoli-node-info/-/broccoli-node-info-2.2.0.tgz", - "integrity": "sha512-VabSGRpKIzpmC+r+tJueCE5h8k6vON7EIMMWu6d/FyPdtijwLQ7QvzShEw+m3mHoDzUaj/kiZsDYrS8X2adsBg==", - "dev": true, - "engines": { - "node": "8.* || >= 10.*" - } - }, - "node_modules/broccoli-output-wrapper": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/broccoli-output-wrapper/-/broccoli-output-wrapper-3.2.5.tgz", - "integrity": "sha512-bQAtwjSrF4Nu0CK0JOy5OZqw9t5U0zzv2555EA/cF8/a8SLDTIetk9UgrtMVw7qKLKdSpOZ2liZNeZZDaKgayw==", - "dev": true, - "dependencies": { - "fs-extra": "^8.1.0", - "heimdalljs-logger": "^0.1.10", - "symlink-or-copy": "^1.2.0" - }, - "engines": { - "node": "10.* || >= 12.*" - } - }, - "node_modules/broccoli-plugin": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/broccoli-plugin/-/broccoli-plugin-4.0.7.tgz", - "integrity": "sha512-a4zUsWtA1uns1K7p9rExYVYG99rdKeGRymW0qOCNkvDPHQxVi3yVyJHhQbM3EZwdt2E0mnhr5e0c/bPpJ7p3Wg==", - "dev": true, - "dependencies": { - "broccoli-node-api": "^1.7.0", - "broccoli-output-wrapper": "^3.2.5", - "fs-merger": "^3.2.1", - "promise-map-series": "^0.3.0", - "quick-temp": "^0.1.8", - "rimraf": "^3.0.2", - "symlink-or-copy": "^1.3.1" - }, - "engines": { - "node": "10.* || >= 12.*" - } - }, - "node_modules/browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "node_modules/browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "dependencies": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" - }, - "bin": { - "browserslist": "cli.js" - }, - "engines": { - "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" - } - }, - "node_modules/browserslist-config-erb": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/browserslist-config-erb/-/browserslist-config-erb-0.0.3.tgz", - "integrity": "sha512-y47DryCY92lxkKyRVMlaZvXAolIY7U33q9e4CS0MdWeJkoAht7OzsrkfdZFCBOP3H5q1EVUxS0L7VVsKM6gZCQ==", - "dev": true, - "peerDependencies": { - "electron": ">=12.0.0" - } - }, - "node_modules/bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "dependencies": { - "fast-json-stable-stringify": "2.x" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/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, - "dependencies": { - "node-int64": "^0.4.0" - } - }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "node_modules/buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true, - "engines": { - "node": "*" - } - }, - "node_modules/buffer-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", - "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/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==", - "dev": true - }, - "node_modules/builder-util": { - "version": "24.0.0-alpha.13", - "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-24.0.0-alpha.13.tgz", - "integrity": "sha512-S8u+ETQ9GV4hJdrxJgVh2V0Cp14WiTrXRy7NsRSlM+DXaNtCIO3VNJSlEg4Btn1cJLUhfo1Fse8FIryV3gRj0Q==", - "dev": true, - "dependencies": { - "@types/debug": "^4.1.6", - "@types/fs-extra": "^9.0.11", - "7zip-bin": "~5.1.1", - "app-builder-bin": "4.0.0", - "bluebird-lst": "^1.0.9", - "builder-util-runtime": "9.2.0-alpha.3", - "chalk": "^4.1.2", - "cross-spawn": "^7.0.3", - "debug": "^4.3.4", - "fs-extra": "^10.1.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.1", - "is-ci": "^3.0.0", - "js-yaml": "^4.1.0", - "source-map-support": "^0.5.19", - "stat-mode": "^1.0.0", - "temp-file": "^3.4.0" - } - }, - "node_modules/builder-util-runtime": { - "version": "8.9.2", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.9.2.tgz", - "integrity": "sha512-rhuKm5vh7E0aAmT6i8aoSfEjxzdYEFX7zDApK+eNgOhjofnWb74d9SRJv0H/8nsgOkos0TZ4zxW0P8J4N7xQ2A==", - "dependencies": { - "debug": "^4.3.2", - "sax": "^1.2.4" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/builder-util/node_modules/builder-util-runtime": { - "version": "9.2.0-alpha.3", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.0-alpha.3.tgz", - "integrity": "sha512-1pOggEqknxVyhdASumips0/RaMaXwSCQMzwhk2jeOGOotBQuOHQHVy25kH5OaeXSFx9L7PckZHXjwZauD72zRw==", - "dev": true, - "dependencies": { - "debug": "^4.3.4", - "sax": "^1.2.4" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/builder-util/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/builder-util/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/builder-util/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "dependencies": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">=10.6.0" - } - }, - "node_modules/cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", - "dev": true, - "dependencies": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/call-me-maybe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", - "integrity": "sha512-wCyFsDQkKPwwF8BDwOiWNx/9K45L/hvggQiDbve+viMNMQnWhrlYIuBk09offfwCRtCO9P6XwUttufzU11WCVw==", - "dev": true - }, - "node_modules/caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", - "dev": true, - "dependencies": { - "callsites": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/caller-callsite/node_modules/callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", - "dev": true, - "dependencies": { - "caller-callsite": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", - "engines": { - "node": ">=6" - } - }, - "node_modules/camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "dev": true, - "dependencies": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "node_modules/camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true, - "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/camelcase-keys/node_modules/quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/camelize": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", - "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dev": true, - "dependencies": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "node_modules/caniuse-lite": { - "version": "1.0.30001439", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz", - "integrity": "sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/caniuse-lite" - } - ] - }, - "node_modules/ccount": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", - "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/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, - "engines": { - "node": ">=10" - } - }, - "node_modules/character-entities": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-html4": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz", - "integrity": "sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-entities-legacy": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", - "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/character-reference-invalid": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", - "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", - "engines": { - "node": "*" - } - }, - "node_modules/cheerio": { - "version": "1.0.0-rc.10", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz", - "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==", - "dev": true, - "dependencies": { - "cheerio-select": "^1.5.0", - "dom-serializer": "^1.3.2", - "domhandler": "^4.2.0", - "htmlparser2": "^6.1.0", - "parse5": "^6.0.1", - "parse5-htmlparser2-tree-adapter": "^6.0.1", - "tslib": "^2.2.0" - }, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/cheeriojs/cheerio?sponsor=1" - } - }, - "node_modules/cheerio-select": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.6.0.tgz", - "integrity": "sha512-eq0GdBvxVFbqWgmCm7M3XGs1I8oLy/nExUnh6oLqmBditPO9AqQJrkslDpMun/hZ0yyTs8L0m85OHp4ho6Qm9g==", - "dev": true, - "dependencies": { - "css-select": "^4.3.0", - "css-what": "^6.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.3.1", - "domutils": "^2.8.0" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://paulmillr.com/funding/" - } - ], - "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": ">= 8.10.0" - }, - "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==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/chromium-pickle-js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", - "integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==", - "dev": true - }, - "node_modules/ci-info": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", - "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", - "dev": true - }, - "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 - }, - "node_modules/class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/class-utils/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clean-css": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.0.tgz", - "integrity": "sha512-YYuuxv4H/iNb1Z/5IbMRoxgrzjWGhOEFfd+groZ5dMCVkpENiMZmwspdrzBo9286JjM1gZJPAyL7ZIdzuvu2AQ==", - "dev": true, - "dependencies": { - "source-map": "~0.6.0" - }, - "engines": { - "node": ">= 10.0" - } - }, - "node_modules/clean-css/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "dependencies": { - "restore-cursor": "^3.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/cli-spinners": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", - "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", - "dev": true, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", - "dev": true, - "dependencies": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "node_modules/clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/clone-regexp": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz", - "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==", - "dev": true, - "dependencies": { - "is-regexp": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, - "dependencies": { - "mimic-response": "^1.0.0" - } - }, - "node_modules/clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", - "dev": true - }, - "node_modules/cloneable-readable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", - "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "process-nextick-args": "^2.0.0", - "readable-stream": "^2.3.5" - } - }, - "node_modules/clsx": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz", - "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==", - "engines": { - "node": ">=6" - } - }, - "node_modules/cmdk": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-0.2.0.tgz", - "integrity": "sha512-JQpKvEOb86SnvMZbYaFKYhvzFntWBeSZdyii0rZPhKJj9uwJBxu4DaVYDrRN7r3mPop56oPhRw+JYWTKs66TYw==", - "dependencies": { - "@radix-ui/react-dialog": "1.0.0", - "command-score": "0.1.2" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true, - "engines": { - "iojs": ">= 1.0.0", - "node": ">= 0.12.0" - } - }, - "node_modules/collapse-white-space": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", - "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "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 - }, - "node_modules/collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", - "dev": true, - "dependencies": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dev": true, - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "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==", - "dev": true - }, - "node_modules/color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true, - "bin": { - "color-support": "bin.js" - } - }, - "node_modules/colord": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.2.tgz", - "integrity": "sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ==", - "dev": true - }, - "node_modules/colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", - "dev": true - }, - "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==", - "dependencies": { - "delayed-stream": "~1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/command-score": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/command-score/-/command-score-0.1.2.tgz", - "integrity": "sha512-VtDvQpIJBvBatnONUsPzXYFVKQQAhuf3XTNOAsdBxCNO/QCtUUd8LSgjn0GVarBkCad6aJCZfXgrjYbl/KRr7w==" - }, - "node_modules/commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", - "dev": true - }, - "node_modules/compare-version": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", - "integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "node_modules/compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dev": true, - "dependencies": { - "mime-db": ">= 1.43.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dev": true, - "dependencies": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/compression/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/compression/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "node_modules/concurrently": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.1.0.tgz", - "integrity": "sha512-Bz0tMlYKZRUDqJlNiF/OImojMB9ruKUz6GCfmhFnSapXgPe+3xzY4byqoKG9tUZ7L2PGEUjfLPOLfIX3labnmw==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "date-fns": "^2.16.1", - "lodash": "^4.17.21", - "rxjs": "^6.6.3", - "spawn-command": "^0.0.2-1", - "supports-color": "^8.1.0", - "tree-kill": "^1.2.2", - "yargs": "^16.2.0" - }, - "bin": { - "concurrently": "dist/bin/concurrently.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.0 || >=16.0.0" - } - }, - "node_modules/concurrently/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/conf": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/conf/-/conf-10.2.0.tgz", - "integrity": "sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==", - "dependencies": { - "ajv": "^8.6.3", - "ajv-formats": "^2.1.1", - "atomically": "^1.7.0", - "debounce-fn": "^4.0.0", - "dot-prop": "^6.0.1", - "env-paths": "^2.2.1", - "json-schema-typed": "^7.0.3", - "onetime": "^5.1.2", - "pkg-up": "^3.1.0", - "semver": "^7.3.5" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/conf/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/conf/node_modules/dot-prop": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", - "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/conf/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==" - }, - "node_modules/config-file-ts": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/config-file-ts/-/config-file-ts-0.2.4.tgz", - "integrity": "sha512-cKSW0BfrSaAUnxpgvpXPLaaW/umg4bqg4k3GO1JqlRfpx+d5W0GDXznCMkWotJQek5Mmz1MJVChQnz3IVaeMZQ==", - "dev": true, - "dependencies": { - "glob": "^7.1.6", - "typescript": "^4.0.2" - } - }, - "node_modules/confusing-browser-globals": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", - "dev": true - }, - "node_modules/connect-history-api-fallback": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", - "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true - }, - "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==", - "dev": true, - "dependencies": { - "safe-buffer": "5.2.1" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/content-disposition/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==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/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==", - "dev": true, - "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==", - "dependencies": { - "safe-buffer": "~5.1.1" - } - }, - "node_modules/cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true - }, - "node_modules/copy-anything": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.2.tgz", - "integrity": "sha512-CzATjGXzUQ0EvuvgOCI6A4BGOo2bcVx8B+eC2nF862iv9fopnPQwlrbACakNCHRIJbCSBj+J/9JeDf60k64MkA==", - "dependencies": { - "is-what": "^4.1.6" - }, - "engines": { - "node": ">=12.13" - }, - "funding": { - "url": "https://github.com/sponsors/mesqueeb" - } - }, - "node_modules/copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/core-js": { - "version": "3.21.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.21.1.tgz", - "integrity": "sha512-FRq5b/VMrWlrmCzwRrpDYNxyHP9BcAZC+xHJaqTgIE5091ZV1NTmyh0sGOg5XqpnHvR0svdy0sv1gWA1zmhxig==", - "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", - "dev": true, - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "node_modules/core-js-pure": { - "version": "3.21.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.21.1.tgz", - "integrity": "sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ==", - "deprecated": "core-js-pure@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js-pure.", - "dev": true, - "hasInstallScript": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/core-js" - } - }, - "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==", - "dev": true - }, - "node_modules/cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", - "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" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "optional": true, - "dependencies": { - "buffer": "^5.1.0" - } - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "node_modules/cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", - "dev": true, - "dependencies": { - "cross-spawn": "^7.0.1" - }, - "bin": { - "cross-env": "src/bin/cross-env.js", - "cross-env-shell": "src/bin/cross-env-shell.js" - }, - "engines": { - "node": ">=10.14", - "npm": ">=6", - "yarn": ">=1" - } - }, - "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==", - "dev": true, - "dependencies": { - "path-key": "^3.1.0", - "shebang-command": "^2.0.0", - "which": "^2.0.1" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/crypt": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", - "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", - "engines": { - "node": "*" - } - }, - "node_modules/css": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", - "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.4", - "source-map": "^0.6.1", - "source-map-resolve": "^0.6.0" - } - }, - "node_modules/css-color-keywords": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", - "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", - "engines": { - "node": ">=4" - } - }, - "node_modules/css-declaration-sorter": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.2.2.tgz", - "integrity": "sha512-Ufadglr88ZLsrvS11gjeu/40Lw74D9Am/Jpr3LlYm5Q4ZP5KdlUhG+6u2EjyXeZcxmZ2h1ebCKngDjolpeLHpg==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >=14" - }, - "peerDependencies": { - "postcss": "^8.0.9" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">=12.22" - } - }, - "node_modules/css-loader": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.1.tgz", - "integrity": "sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw==", - "dev": true, - "dependencies": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.7", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.0", - "postcss-modules-scope": "^3.0.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.3.5" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/css-minimizer-webpack-plugin": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz", - "integrity": "sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==", - "dev": true, - "dependencies": { - "cssnano": "^5.0.6", - "jest-worker": "^27.0.2", - "postcss": "^8.3.5", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "@parcel/css": { - "optional": true - }, - "clean-css": { - "optional": true - }, - "csso": { - "optional": true - }, - "esbuild": { - "optional": true - } - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": 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" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/css-minimizer-webpack-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/css-minimizer-webpack-plugin/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/css-minimizer-webpack-plugin/node_modules/schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/css-minimizer-webpack-plugin/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css-to-react-native": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz", - "integrity": "sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==", - "dependencies": { - "camelize": "^1.0.0", - "css-color-keywords": "^1.0.0", - "postcss-value-parser": "^4.0.2" - } - }, - "node_modules/css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dev": true, - "dependencies": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/css-tree/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "dev": true, - "engines": { - "node": ">= 6" - }, - "funding": { - "url": "https://github.com/sponsors/fb55" - } - }, - "node_modules/css.escape": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=", - "dev": true - }, - "node_modules/css/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/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, - "bin": { - "cssesc": "bin/cssesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/cssnano": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.7.tgz", - "integrity": "sha512-pVsUV6LcTXif7lvKKW9ZrmX+rGRzxkEdJuVJcp5ftUjWITgwam5LMZOgaTvUrWPkcORBey6he7JKb4XAJvrpKg==", - "dev": true, - "dependencies": { - "cssnano-preset-default": "^5.2.7", - "lilconfig": "^2.0.3", - "yaml": "^1.10.2" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/cssnano" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/cssnano-preset-default": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.7.tgz", - "integrity": "sha512-JiKP38ymZQK+zVKevphPzNSGHSlTI+AOwlasoSRtSVMUU285O7/6uZyd5NbW92ZHp41m0sSHe6JoZosakj63uA==", - "dev": true, - "dependencies": { - "css-declaration-sorter": "^6.2.2", - "cssnano-utils": "^3.1.0", - "postcss-calc": "^8.2.3", - "postcss-colormin": "^5.3.0", - "postcss-convert-values": "^5.1.0", - "postcss-discard-comments": "^5.1.1", - "postcss-discard-duplicates": "^5.1.0", - "postcss-discard-empty": "^5.1.1", - "postcss-discard-overridden": "^5.1.0", - "postcss-merge-longhand": "^5.1.4", - "postcss-merge-rules": "^5.1.1", - "postcss-minify-font-values": "^5.1.0", - "postcss-minify-gradients": "^5.1.1", - "postcss-minify-params": "^5.1.2", - "postcss-minify-selectors": "^5.2.0", - "postcss-normalize-charset": "^5.1.0", - "postcss-normalize-display-values": "^5.1.0", - "postcss-normalize-positions": "^5.1.0", - "postcss-normalize-repeat-style": "^5.1.0", - "postcss-normalize-string": "^5.1.0", - "postcss-normalize-timing-functions": "^5.1.0", - "postcss-normalize-unicode": "^5.1.0", - "postcss-normalize-url": "^5.1.0", - "postcss-normalize-whitespace": "^5.1.1", - "postcss-ordered-values": "^5.1.1", - "postcss-reduce-initial": "^5.1.0", - "postcss-reduce-transforms": "^5.1.0", - "postcss-svgo": "^5.1.0", - "postcss-unique-selectors": "^5.1.1" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/cssnano-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", - "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "dev": true, - "dependencies": { - "css-tree": "^1.1.2" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "dev": true - }, - "node_modules/cssstyle": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", - "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", - "dev": true, - "dependencies": { - "cssom": "~0.3.6" - }, - "engines": { - "node": ">=8" - } - }, - "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/csstype": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz", - "integrity": "sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==" - }, - "node_modules/currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==", - "dev": true, - "dependencies": { - "array-find-index": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/damerau-levenshtein": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", - "dev": true - }, - "node_modules/data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "dependencies": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/date-fns": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz", - "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==", - "dev": true, - "engines": { - "node": ">=0.11" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/date-fns" - } - }, - "node_modules/dayjs": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.6.tgz", - "integrity": "sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ==" - }, - "node_modules/de-indent": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", - "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=", - "dev": true - }, - "node_modules/debounce-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-4.0.0.tgz", - "integrity": "sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==", - "dependencies": { - "mimic-fn": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/debounce-fn/node_modules/mimic-fn": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", - "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", - "engines": { - "node": ">=8" - } - }, - "node_modules/debug": { - "version": "4.3.4", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", - "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, - "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, - "engines": { - "node": ">=0.10.0" - } - }, - "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, - "dependencies": { - "decamelize": "^1.1.0", - "map-obj": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/decimal.js": { - "version": "10.3.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", - "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", - "dev": true - }, - "node_modules/decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/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==", - "dev": 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": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", - "dev": 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==", - "dev": true - }, - "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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", - "dev": true, - "dependencies": { - "execa": "^5.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "node_modules/defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", - "dev": true, - "dependencies": { - "clone": "^1.0.2" - } - }, - "node_modules/defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", - "dev": true, - "dependencies": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true - }, - "node_modules/depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true, - "engines": { - "node": ">= 0.8", - "npm": "1.2.8000 || >= 1.4.16" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/detect-node": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", - "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", - "dev": true - }, - "node_modules/detect-node-es": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", - "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" - }, - "node_modules/detect-port": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz", - "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==", - "dev": true, - "dependencies": { - "address": "^1.0.1", - "debug": "^2.6.0" - }, - "bin": { - "detect": "bin/detect-port", - "detect-port": "bin/detect-port" - }, - "engines": { - "node": ">= 4.2.1" - } - }, - "node_modules/detect-port/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/detect-port/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", - "dev": true, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/dir-compare": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-3.3.0.tgz", - "integrity": "sha512-J7/et3WlGUCxjdnD3HAAzQ6nsnc0WL6DD7WcwJb7c39iH1+AWfg+9OqzJNaI6PkBwBvm1mhZNL9iY/nRiZXlPg==", - "dev": true, - "dependencies": { - "buffer-equal": "^1.0.0", - "minimatch": "^3.0.4" - } - }, - "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, - "dependencies": { - "path-type": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dmg-builder": { - "version": "24.0.0-alpha.13", - "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-24.0.0-alpha.13.tgz", - "integrity": "sha512-+2tnaKVKEboVjXeR+CcoOPy/cnTKY+QVPw4sgS2Z50/GO5tjKAttQJ7ZoCl7BUIqBuP9P7ZvCG7mUzhZKHofgQ==", - "dev": true, - "dependencies": { - "app-builder-lib": "24.0.0-alpha.13", - "builder-util": "24.0.0-alpha.13", - "builder-util-runtime": "9.2.0-alpha.3", - "fs-extra": "^10.1.0", - "iconv-lite": "^0.6.2", - "js-yaml": "^4.1.0" - }, - "optionalDependencies": { - "dmg-license": "^1.0.11" - } - }, - "node_modules/dmg-builder/node_modules/builder-util-runtime": { - "version": "9.2.0-alpha.3", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.0-alpha.3.tgz", - "integrity": "sha512-1pOggEqknxVyhdASumips0/RaMaXwSCQMzwhk2jeOGOotBQuOHQHVy25kH5OaeXSFx9L7PckZHXjwZauD72zRw==", - "dev": true, - "dependencies": { - "debug": "^4.3.4", - "sax": "^1.2.4" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/dmg-builder/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/dmg-builder/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/dmg-builder/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/dmg-license": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.11.tgz", - "integrity": "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "@types/plist": "^3.0.1", - "@types/verror": "^1.10.3", - "ajv": "^6.10.0", - "crc": "^3.8.0", - "iconv-corefoundation": "^1.1.7", - "plist": "^3.0.4", - "smart-buffer": "^4.0.2", - "verror": "^1.10.0" - }, - "bin": { - "dmg-license": "bin/dmg-license.js" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", - "dev": true - }, - "node_modules/dns-packet": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.0.tgz", - "integrity": "sha512-rza3UH1LwdHh9qyPXp8lkwpjSNk/AMD3dPytUoRoqnypDUhY0xvbdmVhWOfxO68frEfV9BU8V12Ez7ZsHGZpCQ==", - "dev": true, - "dependencies": { - "@leichtgewicht/ip-codec": "^2.0.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/dom-accessibility-api": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.13.tgz", - "integrity": "sha512-R305kwb5CcMDIpSHUnLyIAp7SrSPBx6F0VfQFB3M75xVMHhXJJIdePYgbPPh1o57vCHNu5QztokWUPsLjWzFqw==", - "dev": true - }, - "node_modules/dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dev": true, - "dependencies": { - "utila": "~0.4" - } - }, - "node_modules/dom-helpers": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", - "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", - "dependencies": { - "@babel/runtime": "^7.8.7", - "csstype": "^3.0.2" - } - }, - "node_modules/dom-serializer": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", - "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", - "dev": true, - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - }, - "funding": { - "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" - } - }, - "node_modules/domelementtype": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", - "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dev": true, - "dependencies": { - "webidl-conversions": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/domexception/node_modules/webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dev": true, - "dependencies": { - "domelementtype": "^2.2.0" - }, - "engines": { - "node": ">= 4" - }, - "funding": { - "url": "https://github.com/fb55/domhandler?sponsor=1" - } - }, - "node_modules/domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dev": true, - "dependencies": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - }, - "funding": { - "url": "https://github.com/fb55/domutils?sponsor=1" - } - }, - "node_modules/dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dev": true, - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, - "dependencies": { - "is-obj": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/dotenv": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz", - "integrity": "sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/dotenv-expand": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", - "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", - "dev": true - }, - "node_modules/duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true - }, - "node_modules/duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, - "node_modules/ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "node_modules/ejs": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", - "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", - "dev": true, - "dependencies": { - "jake": "^10.8.5" - }, - "bin": { - "ejs": "bin/cli.js" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/electron": { - "version": "22.3.1", - "resolved": "https://registry.npmjs.org/electron/-/electron-22.3.1.tgz", - "integrity": "sha512-iDltL9j12bINK3aOp8ZoGq4NFBFjJhw1AYHelbWj93XUCAIT4fdA+PRsq0aaTHg3bthLLlLRvIZVgNsZPqWcqg==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@electron/get": "^2.0.0", - "@types/node": "^16.11.26", - "extract-zip": "^2.0.1" - }, - "bin": { - "electron": "cli.js" - }, - "engines": { - "node": ">= 12.20.55" - } - }, - "node_modules/electron-builder": { - "version": "24.0.0-alpha.13", - "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-24.0.0-alpha.13.tgz", - "integrity": "sha512-YLDlzySvfBZKoCp4hNf4cx849vrew+3jxfNx5malT2PGd3y2GPYKCEvFc15AGShmah2Pt0gGoVQRot/dC6Nb9g==", - "dev": true, - "dependencies": { - "@types/yargs": "^17.0.16", - "app-builder-lib": "24.0.0-alpha.13", - "builder-util": "24.0.0-alpha.13", - "builder-util-runtime": "9.2.0-alpha.3", - "chalk": "^4.1.2", - "dmg-builder": "24.0.0-alpha.13", - "fs-extra": "^10.1.0", - "is-ci": "^3.0.0", - "lazy-val": "^1.0.5", - "read-config-file": "6.3.2", - "simple-update-notifier": "^1.1.0", - "yargs": "^17.6.2" - }, - "bin": { - "electron-builder": "cli.js", - "install-app-deps": "install-app-deps.js" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/electron-builder/node_modules/builder-util-runtime": { - "version": "9.2.0-alpha.3", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.0-alpha.3.tgz", - "integrity": "sha512-1pOggEqknxVyhdASumips0/RaMaXwSCQMzwhk2jeOGOotBQuOHQHVy25kH5OaeXSFx9L7PckZHXjwZauD72zRw==", - "dev": true, - "dependencies": { - "debug": "^4.3.4", - "sax": "^1.2.4" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/electron-builder/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, - "dependencies": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.1", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/electron-builder/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/electron-builder/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/electron-builder/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/electron-builder/node_modules/yargs": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", - "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", - "dev": true, - "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.1.1" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/electron-builder/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, - "engines": { - "node": ">=12" - } - }, - "node_modules/electron-debug": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/electron-debug/-/electron-debug-3.2.0.tgz", - "integrity": "sha512-7xZh+LfUvJ52M9rn6N+tPuDw6oRAjxUj9SoxAZfJ0hVCXhZCsdkrSt7TgXOiWiEOBgEV8qwUIO/ScxllsPS7ow==", - "dependencies": { - "electron-is-dev": "^1.1.0", - "electron-localshortcut": "^3.1.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/electron-devtools-installer": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/electron-devtools-installer/-/electron-devtools-installer-3.2.0.tgz", - "integrity": "sha512-t3UczsYugm4OAbqvdImMCImIMVdFzJAHgbwHpkl5jmfu1izVgUcP/mnrPqJIpEeCK1uZGpt+yHgWEN+9EwoYhQ==", - "dev": true, - "dependencies": { - "rimraf": "^3.0.2", - "semver": "^7.2.1", - "tslib": "^2.1.0", - "unzip-crx-3": "^0.2.0" - } - }, - "node_modules/electron-is-accelerator": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/electron-is-accelerator/-/electron-is-accelerator-0.1.2.tgz", - "integrity": "sha1-UJ5RDCala1Xhf4Y6SwThEYRqsns=" - }, - "node_modules/electron-is-dev": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-1.2.0.tgz", - "integrity": "sha512-R1oD5gMBPS7PVU8gJwH6CtT0e6VSoD0+SzSnYpNm+dBkcijgA+K7VAMHDfnRq/lkKPZArpzplTW6jfiMYosdzw==" - }, - "node_modules/electron-localshortcut": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/electron-localshortcut/-/electron-localshortcut-3.2.1.tgz", - "integrity": "sha512-DWvhKv36GsdXKnaFFhEiK8kZZA+24/yFLgtTwJJHc7AFgDjNRIBJZ/jq62Y/dWv9E4ypYwrVWN2bVrCYw1uv7Q==", - "dependencies": { - "debug": "^4.0.1", - "electron-is-accelerator": "^0.1.0", - "keyboardevent-from-electron-accelerator": "^2.0.0", - "keyboardevents-areequal": "^0.2.1" - } - }, - "node_modules/electron-log": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/electron-log/-/electron-log-4.4.6.tgz", - "integrity": "sha512-nirYgRdY+F+vclr8ijdwy2vW03IzFpDHTaKNWu76dEN21Y76+smcES5knS7cgHUUB0qNLOi8vZO36taakjbSXA==" - }, - "node_modules/electron-notarize": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-1.2.1.tgz", - "integrity": "sha512-u/ECWhIrhkSQpZM4cJzVZ5TsmkaqrRo5LDC/KMbGF0sPkm53Ng59+M0zp8QVaql0obfJy9vlVT+4iOkAi2UDlA==", - "deprecated": "Please use @electron/notarize moving forward. There is no API change, just a package name change", - "dev": true, - "dependencies": { - "debug": "^4.1.1", - "fs-extra": "^9.0.1" - }, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/electron-notarize/node_modules/fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "dependencies": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/electron-notarize/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/electron-notarize/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/electron-publish": { - "version": "24.0.0-alpha.13", - "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-24.0.0-alpha.13.tgz", - "integrity": "sha512-ur3XrX/8vLfZV+UisnbFvinX2ETD+Jdq8mUqG1sKlgITsQdjjjt8vKLiBgE71YhgDqFylpmFeWF8MJT91sSPnQ==", - "dev": true, - "dependencies": { - "@types/fs-extra": "^9.0.11", - "builder-util": "24.0.0-alpha.13", - "builder-util-runtime": "9.2.0-alpha.3", - "chalk": "^4.1.2", - "fs-extra": "^10.1.0", - "lazy-val": "^1.0.5", - "mime": "^2.5.2" - } - }, - "node_modules/electron-publish/node_modules/builder-util-runtime": { - "version": "9.2.0-alpha.3", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.0-alpha.3.tgz", - "integrity": "sha512-1pOggEqknxVyhdASumips0/RaMaXwSCQMzwhk2jeOGOotBQuOHQHVy25kH5OaeXSFx9L7PckZHXjwZauD72zRw==", - "dev": true, - "dependencies": { - "debug": "^4.3.4", - "sax": "^1.2.4" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/electron-publish/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/electron-publish/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/electron-publish/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/electron-store": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-8.1.0.tgz", - "integrity": "sha512-2clHg/juMjOH0GT9cQ6qtmIvK183B39ZXR0bUoPwKwYHJsEF3quqyDzMFUAu+0OP8ijmN2CbPRAelhNbWUbzwA==", - "dependencies": { - "conf": "^10.2.0", - "type-fest": "^2.17.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/electron-store/node_modules/type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", - "engines": { - "node": ">=12.20" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" - }, - "node_modules/electron-updater": { - "version": "4.6.5", - "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-4.6.5.tgz", - "integrity": "sha512-kdTly8O9mSZfm9fslc1mnCY+mYOeaYRy7ERa2Fed240u01BKll3aiupzkd07qKw69KvhBSzuHroIW3mF0D8DWA==", - "dependencies": { - "@types/semver": "^7.3.6", - "builder-util-runtime": "8.9.2", - "fs-extra": "^10.0.0", - "js-yaml": "^4.1.0", - "lazy-val": "^1.0.5", - "lodash.escaperegexp": "^4.1.2", - "lodash.isequal": "^4.5.0", - "semver": "^7.3.5" - } - }, - "node_modules/electron-updater/node_modules/fs-extra": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", - "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/electron-updater/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/electron-updater/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/electron/node_modules/@types/node": { - "version": "16.18.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.13.tgz", - "integrity": "sha512-l0/3XZ153UTlNOnZK8xSNoJlQda9/WnYgiTdcKKPJSZjdjI9MU+A9oMXOesAWLSnqAaaJhj3qfQsU07Dr8OUwg==", - "dev": true - }, - "node_modules/electronmon": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/electronmon/-/electronmon-2.0.2.tgz", - "integrity": "sha512-Yw1CXEp5HJT9P6Sns3UP3Krwm5eb2JKqTRAVczKdsUa+U/dMTgONwKIHkPbKSSmtyTV+5JwobxkhFPiRgegObA==", - "dev": true, - "dependencies": { - "chalk": "^3.0.0", - "import-from": "^3.0.0", - "runtime-required": "^1.1.0", - "watchboy": "^0.4.3" - }, - "bin": { - "electronmon": "bin/cli.js" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/electronmon/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, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/emittery?sponsor=1" - } - }, - "node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "dev": true, - "optional": true, - "dependencies": { - "iconv-lite": "^0.6.2" - } - }, - "node_modules/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==", - "dev": true, - "dependencies": { - "once": "^1.4.0" - } - }, - "node_modules/enhanced-resolve": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz", - "integrity": "sha1-TW5omzcl+GCQknzMhs2fFjW4ni4=", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.2.0", - "tapable": "^0.1.8" - }, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/enhanced-resolve/node_modules/tapable": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.1.10.tgz", - "integrity": "sha1-KcNXB8K3DlDQdIK10gLo7URtr9Q=", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/ensure-posix-path": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ensure-posix-path/-/ensure-posix-path-1.1.1.tgz", - "integrity": "sha512-VWU0/zXzVbeJNXvME/5EmLuEj2TauvoaTz6aFYK1Z92JCBlDlZ3Gu0tuGR42kpW1754ywTs+QB0g5TP0oj9Zaw==", - "dev": true - }, - "node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/env-paths": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", - "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", - "engines": { - "node": ">=6" - } - }, - "node_modules/envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", - "dev": true, - "bin": { - "envinfo": "dist/cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eol": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/eol/-/eol-0.9.1.tgz", - "integrity": "sha512-Ds/TEoZjwggRoz/Q2O7SE3i4Jm66mqTDfmdHdq/7DKVk3bro9Q8h6WdXKdPqFLMoqxrDK5SVRzHVPOS6uuGtrg==", - "dev": true - }, - "node_modules/err-code": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "dev": true - }, - "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==", - "dependencies": { - "is-arrayish": "^0.2.1" - } - }, - "node_modules/error-stack-parser": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.7.tgz", - "integrity": "sha512-chLOW0ZGRf4s8raLrDxa5sdkvPec5YdvwbFnqJme4rk0rFajP8mPtrDL1+I+CwrQDCjswDA5sREX7jYQDQs9vA==", - "dev": true, - "dependencies": { - "stackframe": "^1.1.1" - } - }, - "node_modules/es-abstract": { - "version": "1.20.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.5.tgz", - "integrity": "sha512-7h8MM2EQhsCA7pU/Nv78qOXFpD8Rhqd12gYiSJVkrH9+e8VuA8JlPJK/hQjjlLv6pJvx/z1iRFKzYb0XT/RuAQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.3", - "get-symbol-description": "^1.0.0", - "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.2", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "safe-regex-test": "^1.0.0", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "unbox-primitive": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-module-lexer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.2.1.tgz", - "integrity": "sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg==", - "dev": true - }, - "node_modules/es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", - "dev": true, - "dependencies": { - "has": "^1.0.3" - } - }, - "node_modules/es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "dependencies": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true, - "optional": true - }, - "node_modules/escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", - "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": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "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==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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, - "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" - }, - "engines": { - "node": ">=6.0" - }, - "optionalDependencies": { - "source-map": "~0.6.1" - } - }, - "node_modules/escodegen/node_modules/levn": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", - "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/node_modules/optionator": { - "version": "0.8.3", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", - "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", - "dev": true, - "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" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "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": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/escodegen/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, - "optional": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "dependencies": { - "prelude-ls": "~1.1.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/eslint": { - "version": "8.30.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.30.0.tgz", - "integrity": "sha512-MGADB39QqYuzEGov+F/qb18r4i7DohCDOfatHaxI2iGlPuC65bwG2gxgO+7DkyL38dRFaRH7RaRAgU6JKL9rMQ==", - "dev": true, - "dependencies": { - "@eslint/eslintrc": "^1.4.0", - "@humanwhocodes/config-array": "^0.11.8", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "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.19.0", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "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" - }, - "bin": { - "eslint": "bin/eslint.js" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/eslint-config-airbnb-base": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", - "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", - "dev": true, - "dependencies": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.5", - "semver": "^6.3.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "peerDependencies": { - "eslint": "^7.32.0 || ^8.2.0", - "eslint-plugin-import": "^2.25.2" - } - }, - "node_modules/eslint-config-airbnb-base/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-config-erb": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-config-erb/-/eslint-config-erb-4.0.3.tgz", - "integrity": "sha512-qZeiUSQanpCKKazkLzIvVaoM9NZcNvqhO7gYZ2jaEpBmadCu1aOzzvMMtjsoxaDytRQt6mt+uXjWGyJNqUYusw==", - "dev": true, - "dependencies": { - "@typescript-eslint/eslint-plugin": "^4.29.2", - "@typescript-eslint/parser": "^4.29.3", - "eslint-config-airbnb": "^18.2.1", - "eslint-config-airbnb-typescript": "^13.0.0", - "eslint-config-prettier": "^8.3.0", - "eslint-import-resolver-webpack": "^0.13.1", - "eslint-plugin-compat": "^3.13.0", - "eslint-plugin-import": "^2.24.1", - "eslint-plugin-jest": "^24.4.0", - "eslint-plugin-jsx-a11y": "6.4.1", - "eslint-plugin-prettier": "^3.4.1", - "eslint-plugin-promise": "^5.1.0", - "eslint-plugin-react": "^7.24.0", - "eslint-plugin-react-hooks": "^4.2.0" - }, - "peerDependencies": { - "eslint": ">=7", - "jest": ">=26.0.1", - "react": ">=16.13.1" - } - }, - "node_modules/eslint-config-erb/node_modules/@mdn/browser-compat-data": { - "version": "3.3.14", - "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-3.3.14.tgz", - "integrity": "sha512-n2RC9d6XatVbWFdHLimzzUJxJ1KY8LdjqrW6YvGPiRmsHkhOUx74/Ct10x5Yo7bC/Jvqx7cDEW8IMPv/+vwEzA==", - "dev": true - }, - "node_modules/eslint-config-erb/node_modules/@typescript-eslint/eslint-plugin": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", - "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", - "dev": true, - "dependencies": { - "@typescript-eslint/experimental-utils": "4.33.0", - "@typescript-eslint/scope-manager": "4.33.0", - "debug": "^4.3.1", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.1.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^4.0.0", - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/eslint-config-erb/node_modules/@typescript-eslint/parser": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", - "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", - "dev": true, - "dependencies": { - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "debug": "^4.3.1" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/eslint-config-erb/node_modules/@typescript-eslint/scope-manager": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-config-erb/node_modules/@typescript-eslint/types": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", - "dev": true, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-config-erb/node_modules/@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/eslint-config-erb/node_modules/@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-config-erb/node_modules/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.2", - "@babel/runtime-corejs3": "^7.10.2" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/eslint-config-erb/node_modules/eslint-config-airbnb": { - "version": "18.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-18.2.1.tgz", - "integrity": "sha512-glZNDEZ36VdlZWoxn/bUR1r/sdFKPd1mHPbqUtkctgNG4yT2DLLtJ3D+yCV+jzZCc2V1nBVkmdknOJBZ5Hc0fg==", - "dev": true, - "dependencies": { - "eslint-config-airbnb-base": "^14.2.1", - "object.assign": "^4.1.2", - "object.entries": "^1.1.2" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "eslint": "^5.16.0 || ^6.8.0 || ^7.2.0", - "eslint-plugin-import": "^2.22.1", - "eslint-plugin-jsx-a11y": "^6.4.1", - "eslint-plugin-react": "^7.21.5", - "eslint-plugin-react-hooks": "^4 || ^3 || ^2.3.0 || ^1.7.0" - } - }, - "node_modules/eslint-config-erb/node_modules/eslint-config-airbnb-typescript": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-13.0.1.tgz", - "integrity": "sha512-n7fGBDNV3xSKbWDUES2FfsNAJhuqADcwzshX6ci6qoszUnH6p4dzrLnSFqYkw5Sn7M+aarp2BTf7JDOK88M+bg==", - "dev": true, - "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^4.4.1", - "@typescript-eslint/parser": "^4.4.1" - } - }, - "node_modules/eslint-config-erb/node_modules/eslint-config-airbnb/node_modules/eslint-config-airbnb-base": { - "version": "14.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz", - "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==", - "dev": true, - "dependencies": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.2" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "eslint": "^5.16.0 || ^6.8.0 || ^7.2.0", - "eslint-plugin-import": "^2.22.1" - } - }, - "node_modules/eslint-config-erb/node_modules/eslint-plugin-compat": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-3.13.0.tgz", - "integrity": "sha512-cv8IYMuTXm7PIjMVDN2y4k/KVnKZmoNGHNq27/9dLstOLydKblieIv+oe2BN2WthuXnFNhaNvv3N1Bvl4dbIGA==", - "dev": true, - "dependencies": { - "@mdn/browser-compat-data": "^3.3.14", - "ast-metadata-inferer": "^0.7.0", - "browserslist": "^4.16.8", - "caniuse-lite": "^1.0.30001251", - "core-js": "^3.16.2", - "find-up": "^5.0.0", - "lodash.memoize": "4.1.2", - "semver": "7.3.5" - }, - "engines": { - "node": ">=9.x" - }, - "peerDependencies": { - "eslint": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" - } - }, - "node_modules/eslint-config-erb/node_modules/eslint-plugin-jest": { - "version": "24.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.7.0.tgz", - "integrity": "sha512-wUxdF2bAZiYSKBclsUMrYHH6WxiBreNjyDxbRv345TIvPeoCEgPNEn3Sa+ZrSqsf1Dl9SqqSREXMHExlMMu1DA==", - "dev": true, - "dependencies": { - "@typescript-eslint/experimental-utils": "^4.0.1" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@typescript-eslint/eslint-plugin": ">= 4", - "eslint": ">=5" - }, - "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { - "optional": true - } - } - }, - "node_modules/eslint-config-erb/node_modules/eslint-plugin-jsx-a11y": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.4.1.tgz", - "integrity": "sha512-0rGPJBbwHoGNPU73/QCLP/vveMlM1b1Z9PponxO87jfr6tuH5ligXbDT6nHSSzBC8ovX2Z+BQu7Bk5D/Xgq9zg==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.11.2", - "aria-query": "^4.2.2", - "array-includes": "^3.1.1", - "ast-types-flow": "^0.0.7", - "axe-core": "^4.0.2", - "axobject-query": "^2.2.0", - "damerau-levenshtein": "^1.0.6", - "emoji-regex": "^9.0.0", - "has": "^1.0.3", - "jsx-ast-utils": "^3.1.0", - "language-tags": "^1.0.5" - }, - "engines": { - "node": ">=4.0" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7" - } - }, - "node_modules/eslint-config-erb/node_modules/eslint-plugin-promise": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.2.0.tgz", - "integrity": "sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw==", - "dev": true, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "peerDependencies": { - "eslint": "^7.0.0" - } - }, - "node_modules/eslint-config-erb/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==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint-config-erb/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/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, - "bin": { - "eslint-config-prettier": "bin/cli.js" - }, - "peerDependencies": { - "eslint": ">=7.0.0" - } - }, - "node_modules/eslint-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "resolve": "^1.20.0" - } - }, - "node_modules/eslint-import-resolver-node/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-import-resolver-typescript": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-2.7.1.tgz", - "integrity": "sha512-00UbgGwV8bSgUv34igBDbTOtKhqoRMy9bFjNehT40bXg6585PNIct8HhXZ0SybqB9rWtXj9crcku8ndDn/gIqQ==", - "dev": true, - "dependencies": { - "debug": "^4.3.4", - "glob": "^7.2.0", - "is-glob": "^4.0.3", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "*", - "eslint-plugin-import": "*" - } - }, - "node_modules/eslint-import-resolver-webpack": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-webpack/-/eslint-import-resolver-webpack-0.13.2.tgz", - "integrity": "sha512-XodIPyg1OgE2h5BDErz3WJoK7lawxKTJNhgPNafRST6csC/MZC+L5P6kKqsZGRInpbgc02s/WZMrb4uGJzcuRg==", - "dev": true, - "dependencies": { - "array-find": "^1.0.0", - "debug": "^3.2.7", - "enhanced-resolve": "^0.9.1", - "find-root": "^1.1.0", - "has": "^1.0.3", - "interpret": "^1.4.0", - "is-core-module": "^2.7.0", - "is-regex": "^1.1.4", - "lodash": "^4.17.21", - "resolve": "^1.20.0", - "semver": "^5.7.1" - }, - "engines": { - "node": ">= 6" - }, - "peerDependencies": { - "eslint-plugin-import": ">=1.4.0", - "webpack": ">=1.11.0" - } - }, - "node_modules/eslint-import-resolver-webpack/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-import-resolver-webpack/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/eslint-module-utils": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", - "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", - "dev": true, - "dependencies": { - "debug": "^3.2.7", - "find-up": "^2.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/eslint-module-utils/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-module-utils/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-plugin-compat": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-4.0.2.tgz", - "integrity": "sha512-xqvoO54CLTVaEYGMzhu35Wzwk/As7rCvz/2dqwnFiWi0OJccEtGIn+5qq3zqIu9nboXlpdBN579fZcItC73Ycg==", - "dev": true, - "dependencies": { - "@mdn/browser-compat-data": "^4.1.5", - "ast-metadata-inferer": "^0.7.0", - "browserslist": "^4.16.8", - "caniuse-lite": "^1.0.30001304", - "core-js": "^3.16.2", - "find-up": "^5.0.0", - "lodash.memoize": "4.1.2", - "semver": "7.3.5" - }, - "engines": { - "node": ">=9.x" - }, - "peerDependencies": { - "eslint": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/eslint-plugin-compat/node_modules/semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" - } - }, - "node_modules/eslint-plugin-import/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-import/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/eslint-plugin-jest": { - "version": "26.1.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.1.3.tgz", - "integrity": "sha512-Pju+T7MFpo5VFhFlwrkK/9jRUu18r2iugvgyrWOnnGRaVTFFmFXp+xFJpHyqmjjLmGJPKLeEFLVTAxezkApcpQ==", - "dev": true, - "dependencies": { - "@typescript-eslint/utils": "^5.10.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "@typescript-eslint/eslint-plugin": "^5.0.0", - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - }, - "peerDependenciesMeta": { - "@typescript-eslint/eslint-plugin": { - "optional": true - }, - "jest": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-jsx-a11y": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz", - "integrity": "sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.18.9", - "aria-query": "^4.2.2", - "array-includes": "^3.1.5", - "ast-types-flow": "^0.0.7", - "axe-core": "^4.4.3", - "axobject-query": "^2.2.0", - "damerau-levenshtein": "^1.0.8", - "emoji-regex": "^9.2.2", - "has": "^1.0.3", - "jsx-ast-utils": "^3.3.2", - "language-tags": "^1.0.5", - "minimatch": "^3.1.2", - "semver": "^6.3.0" - }, - "engines": { - "node": ">=4.0" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" - } - }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.10.2", - "@babel/runtime-corejs3": "^7.10.2" - }, - "engines": { - "node": ">=6.0" - } - }, - "node_modules/eslint-plugin-jsx-a11y/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-prettier": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", - "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", - "dev": true, - "dependencies": { - "prettier-linter-helpers": "^1.0.0" - }, - "engines": { - "node": ">=6.0.0" - }, - "peerDependencies": { - "eslint": ">=5.0.0", - "prettier": ">=1.13.0" - }, - "peerDependenciesMeta": { - "eslint-config-prettier": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-promise": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", - "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "peerDependencies": { - "eslint": "^7.0.0 || ^8.0.0" - } - }, - "node_modules/eslint-plugin-react": { - "version": "7.31.11", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.11.tgz", - "integrity": "sha512-TTvq5JsT5v56wPa9OYHzsrOlHzKZKjV+aLgS+55NJP/cuzdiQPC7PfYoUjMoxlffKtvijpk7vA/jmuqRb9nohw==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.6", - "array.prototype.flatmap": "^1.3.1", - "array.prototype.tosorted": "^1.1.1", - "doctrine": "^2.1.0", - "estraverse": "^5.3.0", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.1.2", - "object.entries": "^1.1.6", - "object.fromentries": "^2.0.6", - "object.hasown": "^1.1.2", - "object.values": "^1.1.6", - "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.3", - "semver": "^6.3.0", - "string.prototype.matchall": "^4.0.8" - }, - "engines": { - "node": ">=4" - }, - "peerDependencies": { - "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" - } - }, - "node_modules/eslint-plugin-react-hooks": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", - "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", - "dev": true, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" - } - }, - "node_modules/eslint-plugin-react/node_modules/doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "dependencies": { - "esutils": "^2.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-react/node_modules/resolve": { - "version": "2.0.0-next.3", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", - "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", - "dev": true, - "dependencies": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/eslint-plugin-react/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/eslint-plugin-sort-keys-fix": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-sort-keys-fix/-/eslint-plugin-sort-keys-fix-1.1.2.tgz", - "integrity": "sha512-DNPHFGCA0/hZIsfODbeLZqaGY/+q3vgtshF85r+YWDNCQ2apd9PNs/zL6ttKm0nD1IFwvxyg3YOTI7FHl4unrw==", - "dev": true, - "dependencies": { - "espree": "^6.1.2", - "esutils": "^2.0.2", - "natural-compare": "^1.4.0", - "requireindex": "~1.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/eslint-plugin-sort-keys-fix/node_modules/acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/eslint-plugin-sort-keys-fix/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/eslint-plugin-sort-keys-fix/node_modules/espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", - "dev": true, - "dependencies": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/eslint-plugin-typescript-sort-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-typescript-sort-keys/-/eslint-plugin-typescript-sort-keys-2.1.0.tgz", - "integrity": "sha512-ET7ABypdz19m47QnKynzNfWPi4CTNQ5jQQC1X5d0gojIwblkbGiCa5IilsqzBTmqxZ0yXDqKBO/GBkBFQCOFsg==", - "dev": true, - "dependencies": { - "@typescript-eslint/experimental-utils": "^5.0.0", - "json-schema": "^0.4.0", - "natural-compare-lite": "^1.4.0" - }, - "engines": { - "node": "10 - 12 || >= 13.9" - }, - "peerDependencies": { - "@typescript-eslint/parser": "^1 || ^2 || ^3 || ^4 || ^5", - "eslint": "^5 || ^6 || ^7 || ^8", - "typescript": "^3 || ^4" - } - }, - "node_modules/eslint-plugin-typescript-sort-keys/node_modules/@typescript-eslint/experimental-utils": { - "version": "5.25.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.25.0.tgz", - "integrity": "sha512-YTe9rmslCh1xAvNa3X+uZe4L2lsyb8V3WIeK9z46nNiPswk/V/0SGLJSfo8W9Hj4R7ak7bolazXGn3DErmb8QA==", - "dev": true, - "dependencies": { - "@typescript-eslint/utils": "5.25.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/eslint-plugin-typescript-sort-keys/node_modules/@typescript-eslint/scope-manager": { - "version": "5.25.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.25.0.tgz", - "integrity": "sha512-p4SKTFWj+2VpreUZ5xMQsBMDdQ9XdRvODKXN4EksyBjFp2YvQdLkyHqOffakYZPuWJUDNu3jVXtHALDyTv3cww==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.25.0", - "@typescript-eslint/visitor-keys": "5.25.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-plugin-typescript-sort-keys/node_modules/@typescript-eslint/types": { - "version": "5.25.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.25.0.tgz", - "integrity": "sha512-7fWqfxr0KNHj75PFqlGX24gWjdV/FDBABXL5dyvBOWHpACGyveok8Uj4ipPX/1fGU63fBkzSIycEje4XsOxUFA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/eslint-plugin-typescript-sort-keys/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.25.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.25.0.tgz", - "integrity": "sha512-MrPODKDych/oWs/71LCnuO7NyR681HuBly2uLnX3r5i4ME7q/yBqC4hW33kmxtuauLTM0OuBOhhkFaxCCOjEEw==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.25.0", - "@typescript-eslint/visitor-keys": "5.25.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/eslint-plugin-typescript-sort-keys/node_modules/@typescript-eslint/utils": { - "version": "5.25.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.25.0.tgz", - "integrity": "sha512-qNC9bhnz/n9Kba3yI6HQgQdBLuxDoMgdjzdhSInZh6NaDnFpTUlwNGxplUFWfY260Ya0TRPvkg9dd57qxrJI9g==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.25.0", - "@typescript-eslint/types": "5.25.0", - "@typescript-eslint/typescript-estree": "5.25.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" - } - }, - "node_modules/eslint-plugin-typescript-sort-keys/node_modules/@typescript-eslint/visitor-keys": { - "version": "5.25.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.25.0.tgz", - "integrity": "sha512-yd26vFgMsC4h2dgX4+LR+GeicSKIfUvZREFLf3DDjZPtqgLx5AJZr6TetMNwFP9hcKreTTeztQYBTNbNoOycwA==", - "dev": true, - "dependencies": { - "@typescript-eslint/types": "5.25.0", - "eslint-visitor-keys": "^3.3.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "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/eslint-scope/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" - } - }, - "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==", - "dev": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" - } - }, - "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/eslint/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==", - "dev": true, - "dependencies": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - } - }, - "node_modules/espree": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", - "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", - "dev": true, - "dependencies": { - "acorn": "^8.8.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" - }, - "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==", - "dev": true, - "bin": { - "esparse": "bin/esparse.js", - "esvalidate": "bin/esvalidate.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/esquery": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", - "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", - "dev": true, - "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==", - "dev": true, - "dependencies": { - "estraverse": "^5.2.0" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/estraverse": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", - "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", - "dev": true, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - }, - "node_modules/events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true, - "engines": { - "node": ">=0.8.x" - } - }, - "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", - "dev": true, - "dependencies": { - "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" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/execa?sponsor=1" - } - }, - "node_modules/execa/node_modules/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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/execall": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz", - "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==", - "dev": true, - "dependencies": { - "clone-regexp": "^2.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", - "dev": true, - "dependencies": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/expand-brackets/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/expand-brackets/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/expect": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", - "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/express": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.0.tgz", - "integrity": "sha512-EJEXxiTQJS3lIPrU1AE2vRuT7X7E+0KBbpm5GSoK524yl0K8X+er8zS2P14E64eqsVNoWbMCT7MpmQ+ErAhgRg==", - "dev": true, - "dependencies": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.0", - "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.10.3", - "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" - }, - "engines": { - "node": ">= 0.10.0" - } - }, - "node_modules/express/node_modules/array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true - }, - "node_modules/express/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/express/node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/express/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/express/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==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/express/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "node_modules/extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "dependencies": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "dependencies": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extglob/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "dependencies": { - "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/extsprintf": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", - "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==", - "dev": true, - "engines": [ - "node >=0.6.0" - ], - "optional": true - }, - "node_modules/fast-average-color": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/fast-average-color/-/fast-average-color-9.3.0.tgz", - "integrity": "sha512-FlPROSqDMOnoBgkFhWMHJODPvpS0Od0WDpedcKq4U/t0JVapGAkblNwxOr75qT+ZNd0dQM4qlgqrtnXbCJ8cNg==", - "engines": { - "node": ">= 12" - } - }, - "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==" - }, - "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 - }, - "node_modules/fast-fifo": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.1.0.tgz", - "integrity": "sha512-Kl29QoNbNvn4nhDsLYjyIAaIqaJB6rBx5p3sL9VjaefJ+eMFBWVZiaoguaoZfzEKr5RhAti0UgM8703akGPJ6g==", - "dev": true - }, - "node_modules/fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", - "dev": true, - "dependencies": { - "@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" - }, - "engines": { - "node": ">=8.6.0" - } - }, - "node_modules/fast-glob/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==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "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==", - "dev": true - }, - "node_modules/fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "node_modules/fastest-levenshtein": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", - "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", - "dev": true - }, - "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==", - "dev": true, - "dependencies": { - "reusify": "^1.0.4" - } - }, - "node_modules/faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "dev": true, - "dependencies": { - "websocket-driver": ">=0.5.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", - "dev": true, - "dependencies": { - "bser": "2.1.1" - } - }, - "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==", - "dev": true, - "dependencies": { - "pend": "~1.2.0" - } - }, - "node_modules/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==", - "dev": true, - "dependencies": { - "flat-cache": "^3.0.4" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/file-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", - "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", - "dev": true, - "dependencies": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "dev": true, - "dependencies": { - "minimatch": "^5.0.1" - } - }, - "node_modules/filelist/node_modules/brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "dependencies": { - "balanced-match": "^1.0.0" - } - }, - "node_modules/filelist/node_modules/minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "dependencies": { - "brace-expansion": "^2.0.1" - }, - "engines": { - "node": ">=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, - "dependencies": { - "to-regex-range": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/finalhandler": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", - "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", - "dev": true, - "dependencies": { - "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" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/finalhandler/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/finalhandler/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/finalhandler/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" - }, - "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==", - "dev": true, - "dependencies": { - "locate-path": "^6.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/flat-cache": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", - "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", - "dev": true, - "dependencies": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - } - }, - "node_modules/flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", - "dev": true - }, - "node_modules/flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, - "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==", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/form-data": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", - "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/format-duration": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/format-duration/-/format-duration-2.0.0.tgz", - "integrity": "sha512-ARqJ9qXm71pw3SGAY7bibf8lRLvltOXLjWjzzR3UrUjHu1zdeYpA/Z+u+ltdhrfRa440OjEsHNzdmuZViqqQWQ==" - }, - "node_modules/forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", - "dev": true, - "dependencies": { - "map-cache": "^0.2.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/framer-motion": { - "version": "9.1.7", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-9.1.7.tgz", - "integrity": "sha512-nKxBkIO4IPkMEqcBbbATxsVjwPYShKl051yhBv9628iAH6JLeHD0siBHxkL62oQzMC1+GNX73XtPjgP753ufuw==", - "dependencies": { - "tslib": "^2.4.0" - }, - "optionalDependencies": { - "@emotion/is-prop-valid": "^0.8.2" - }, - "peerDependencies": { - "react": "^18.0.0", - "react-dom": "^18.0.0" - } - }, - "node_modules/framer-motion/node_modules/@emotion/is-prop-valid": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", - "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", - "optional": true, - "dependencies": { - "@emotion/memoize": "0.7.4" - } - }, - "node_modules/framer-motion/node_modules/@emotion/memoize": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", - "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", - "optional": true - }, - "node_modules/fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/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==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - }, - "engines": { - "node": ">=6 <7 || >=8" - } - }, - "node_modules/fs-merger": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/fs-merger/-/fs-merger-3.2.1.tgz", - "integrity": "sha512-AN6sX12liy0JE7C2evclwoo0aCG3PFulLjrTLsJpWh/2mM+DinhpSGqYLbHBBbIW1PLRNcFhJG8Axtz8mQW3ug==", - "dev": true, - "dependencies": { - "broccoli-node-api": "^1.7.0", - "broccoli-node-info": "^2.1.0", - "fs-extra": "^8.0.1", - "fs-tree-diff": "^2.0.1", - "walk-sync": "^2.2.0" - } - }, - "node_modules/fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/fs-mkdirp-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", - "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.11", - "through2": "^2.0.3" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/fs-mkdirp-stream/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/fs-monkey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", - "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", - "dev": true - }, - "node_modules/fs-tree-diff": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fs-tree-diff/-/fs-tree-diff-2.0.1.tgz", - "integrity": "sha512-x+CfAZ/lJHQqwlD64pYM5QxWjzWhSjroaVsr8PW831zOApL55qPibed0c+xebaLWVr2BnHFoHdrwOv8pzt8R5A==", - "dev": true, - "dependencies": { - "@types/symlink-or-copy": "^1.2.0", - "heimdalljs-logger": "^0.1.7", - "object-assign": "^4.1.0", - "path-posix": "^1.0.0", - "symlink-or-copy": "^1.1.8" - }, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "node_modules/function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "node_modules/function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "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==", - "dev": true, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/fuse.js": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-6.6.2.tgz", - "integrity": "sha512-cJaJkxCCxC8qIIcPBF9yGxY0W/tVZS3uEISDxhYIdtk8OL93pe+6Zj7LjCqVV4dzbqcriOZ+kQ/NE4RXZHsIGA==", - "engines": { - "node": ">=10" - } - }, - "node_modules/gauge": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", - "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", - "dev": true, - "dependencies": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16.0.0" - } - }, - "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==", - "engines": { - "node": ">=6.9.0" - } - }, - "node_modules/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, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "node_modules/get-intrinsic": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", - "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", - "dev": true, - "dependencies": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-nonce": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", - "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", - "engines": { - "node": ">=6" - } - }, - "node_modules/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, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/get-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "dependencies": { - "pump": "^3.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "dependencies": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - }, - "engines": { - "node": "*" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/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==", - "dev": true, - "dependencies": { - "is-glob": "^4.0.3" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/glob-stream": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", - "integrity": "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==", - "dev": true, - "dependencies": { - "extend": "^3.0.0", - "glob": "^7.1.1", - "glob-parent": "^3.1.0", - "is-negated-glob": "^1.0.0", - "ordered-read-streams": "^1.0.0", - "pumpify": "^1.3.5", - "readable-stream": "^2.1.5", - "remove-trailing-separator": "^1.0.1", - "to-absolute-glob": "^2.0.0", - "unique-stream": "^2.0.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/glob-stream/node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", - "dev": true, - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "node_modules/glob-stream/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, - "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==", - "dev": true, - "optional": true, - "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" - }, - "engines": { - "node": ">=10.0" - } - }, - "node_modules/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, - "dependencies": { - "global-prefix": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/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, - "dependencies": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/global-prefix/node_modules/which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "which": "bin/which" - } - }, - "node_modules/globals": { - "version": "13.19.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", - "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", - "dev": true, - "dependencies": { - "type-fest": "^0.20.2" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globalthis": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", - "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", - "dev": true, - "optional": true, - "dependencies": { - "define-properties": "^1.1.3" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/globby": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", - "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", - "dev": true, - "dependencies": { - "array-union": "^2.1.0", - "dir-glob": "^3.0.1", - "fast-glob": "^3.2.9", - "ignore": "^5.2.0", - "merge2": "^1.4.1", - "slash": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/globjoin": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", - "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", - "dev": true - }, - "node_modules/gonzales-pe": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", - "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==", - "dev": true, - "dependencies": { - "minimist": "^1.2.5" - }, - "bin": { - "gonzales": "bin/gonzales.js" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/got": { - "version": "11.8.6", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", - "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", - "dev": true, - "dependencies": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.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": ">=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==" - }, - "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==", - "dev": true - }, - "node_modules/gulp-sort": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/gulp-sort/-/gulp-sort-2.0.0.tgz", - "integrity": "sha1-xnYqLx8N4KP8WVohWZ0/rI26Gso=", - "dev": true, - "dependencies": { - "through2": "^2.0.1" - } - }, - "node_modules/gulp-sort/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/gzip-size": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", - "dev": true, - "dependencies": { - "duplexer": "^0.1.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", - "dev": true - }, - "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" - } - }, - "node_modules/harmony-reflect": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", - "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==", - "dev": true - }, - "node_modules/has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dependencies": { - "function-bind": "^1.1.1" - }, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/has-bigints": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", - "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", - "dev": true, - "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==", - "dev": true, - "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==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true - }, - "node_modules/has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", - "dev": true, - "dependencies": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/has-values/node_modules/kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "bin": { - "he": "bin/he" - } - }, - "node_modules/heimdalljs": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/heimdalljs/-/heimdalljs-0.2.6.tgz", - "integrity": "sha512-o9bd30+5vLBvBtzCPwwGqpry2+n0Hi6H1+qwt6y+0kwRHGGF8TFIhJPmnuM0xO97zaKrDZMwO/V56fAnn8m/tA==", - "dev": true, - "dependencies": { - "rsvp": "~3.2.1" - } - }, - "node_modules/heimdalljs-logger": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/heimdalljs-logger/-/heimdalljs-logger-0.1.10.tgz", - "integrity": "sha512-pO++cJbhIufVI/fmB/u2Yty3KJD0TqNPecehFae0/eps0hkZ3b4Zc/PezUMOpYuHFQbA7FxHZxa305EhmjLj4g==", - "dev": true, - "dependencies": { - "debug": "^2.2.0", - "heimdalljs": "^0.2.6" - } - }, - "node_modules/heimdalljs-logger/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/heimdalljs-logger/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/heimdalljs/node_modules/rsvp": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.2.1.tgz", - "integrity": "sha1-B8tKXfJa3Z6Cbrxn3Mn9idsn2Eo=", - "dev": true - }, - "node_modules/history": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz", - "integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==", - "dependencies": { - "@babel/runtime": "^7.7.6" - } - }, - "node_modules/hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "dependencies": { - "react-is": "^16.7.0" - } - }, - "node_modules/hoist-non-react-statics/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "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, - "dependencies": { - "lru-cache": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", - "dev": true, - "dependencies": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "node_modules/html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "dependencies": { - "whatwg-encoding": "^1.0.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/html-entities": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", - "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==", - "dev": true - }, - "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==" - }, - "node_modules/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", - "dev": true, - "dependencies": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "bin": { - "html-minifier-terser": "cli.js" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/html-minifier-terser/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/html-parse-stringify": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", - "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", - "dependencies": { - "void-elements": "3.1.0" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/html-webpack-plugin": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz", - "integrity": "sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==", - "dev": true, - "dependencies": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/html-webpack-plugin" - }, - "peerDependencies": { - "webpack": "^5.20.0" - } - }, - "node_modules/htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "dev": true, - "funding": [ - "https://github.com/fb55/htmlparser2?sponsor=1", - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ], - "dependencies": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, - "node_modules/http-cache-semantics": { - "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==", - "dev": true - }, - "node_modules/http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", - "dev": 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==", - "dev": true, - "dependencies": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-errors/node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-errors/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/http-parser-js": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.6.tgz", - "integrity": "sha512-vDlkRPDJn93swjcjqMSaGSPABbIarsr1TLAui/gLDXzV5VsJNdXNzMYDyNBLQkjWQCJ1uizu8T2oDMhmGt0PRA==", - "dev": true - }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dev": true, - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "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, - "dependencies": { - "@tootallnate/once": "2", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/http-proxy-middleware": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.4.tgz", - "integrity": "sha512-m/4FxX17SUvz4lJ5WPXOHDUuCwIqXLfLHs1s0uZ3oYjhoXlx9csYxaOa0ElDEJ+h8Q4iJ1s+lTMbiCa4EXIJqg==", - "dev": true, - "dependencies": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "@types/express": "^4.17.13" - }, - "peerDependenciesMeta": { - "@types/express": { - "optional": true - } - } - }, - "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==", - "dev": 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, - "dependencies": { - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/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, - "engines": { - "node": ">=10.17.0" - } - }, - "node_modules/humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", - "dev": true, - "dependencies": { - "ms": "^2.0.0" - } - }, - "node_modules/husky": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.4.tgz", - "integrity": "sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==", - "dev": true, - "bin": { - "husky": "lib/bin.js" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/typicode" - } - }, - "node_modules/i18next": { - "version": "21.6.16", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-21.6.16.tgz", - "integrity": "sha512-xJlzrVxG9CyAGsbMP1aKuiNr1Ed2m36KiTB7hjGMG2Zo4idfw3p9THUEu+GjBwIgEZ7F11ZbCzJcfv4uyfKNuw==", - "funding": [ - { - "type": "individual", - "url": "https://locize.com" - }, - { - "type": "individual", - "url": "https://locize.com/i18next.html" - }, - { - "type": "individual", - "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" - } - ], - "dependencies": { - "@babel/runtime": "^7.17.2" - } - }, - "node_modules/i18next-parser": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/i18next-parser/-/i18next-parser-6.6.0.tgz", - "integrity": "sha512-yA3W6PL+7epCyUFTpUDdztKArfpeGMWRUOnB/4FZRodfXkjCIBcBg728h6b/lrBTbva4OlFjVgv1kCXbvZVRWQ==", - "dev": true, - "dependencies": { - "@babel/runtime": "^7.15.4", - "broccoli-plugin": "^4.0.7", - "cheerio": "^1.0.0-rc.2", - "colors": "1.4.0", - "commander": "~9.4.1", - "concat-stream": "~2.0.0", - "eol": "^0.9.1", - "fs-extra": "^10.0.0", - "gulp-sort": "^2.0.0", - "i18next": "^21.2.0", - "js-yaml": "4.1.0", - "rsvp": "^4.8.2", - "sort-keys": "^5.0.0", - "through2": "~4.0.2", - "typescript": "^4.2.4", - "vinyl": "~3.0.0", - "vinyl-fs": "^3.0.2", - "vue-template-compiler": "^2.6.11" - }, - "bin": { - "i18next": "bin/cli.js" - }, - "engines": { - "node": "^14.13.1 || >=16.0.0 || >=18.0.0", - "npm": ">=6", - "yarn": ">=1" - } - }, - "node_modules/i18next-parser/node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/i18next-parser/node_modules/colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true, - "engines": { - "node": ">=0.1.90" - } - }, - "node_modules/i18next-parser/node_modules/commander": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", - "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", - "dev": true, - "engines": { - "node": "^12.20.0 || >=14" - } - }, - "node_modules/i18next-parser/node_modules/concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "dev": true, - "engines": [ - "node >= 6.0" - ], - "dependencies": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - } - }, - "node_modules/i18next-parser/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/i18next-parser/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/i18next-parser/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/i18next-parser/node_modules/replace-ext": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", - "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/i18next-parser/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/i18next-parser/node_modules/vinyl": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", - "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", - "dev": true, - "dependencies": { - "clone": "^2.1.2", - "clone-stats": "^1.0.0", - "remove-trailing-separator": "^1.1.0", - "replace-ext": "^2.0.0", - "teex": "^1.0.1" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/iconv-corefoundation": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz", - "integrity": "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==", - "dev": true, - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "cli-truncate": "^2.1.0", - "node-addon-api": "^1.6.3" - }, - "engines": { - "node": "^8.11.2 || >=10" - } - }, - "node_modules/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==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/identity-obj-proxy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", - "integrity": "sha1-lNK9qWCERT7zb7xarsN+D3nx/BQ=", - "dev": true, - "dependencies": { - "harmony-reflect": "^1.4.6" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", - "dev": true - }, - "node_modules/immer": { - "version": "9.0.21", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", - "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/immer" - } - }, - "node_modules/immutable": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz", - "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==", - "dev": true - }, - "node_modules/import-fresh": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", - "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", - "dependencies": { - "parent-module": "^1.0.0", - "resolve-from": "^4.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/import-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/import-from/-/import-from-3.0.0.tgz", - "integrity": "sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ==", - "dev": true, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/import-from/node_modules/resolve-from": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", - "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/import-local": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", - "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", - "dev": true, - "dependencies": { - "pkg-dir": "^4.2.0", - "resolve-cwd": "^3.0.0" - }, - "bin": { - "import-local-fixture": "fixtures/cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true, - "engines": { - "node": ">=0.8.19" - } - }, - "node_modules/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, - "engines": { - "node": ">=8" - } - }, - "node_modules/indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==", - "dev": true - }, - "node_modules/infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "node_modules/inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "dependencies": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "node_modules/inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "node_modules/internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "dependencies": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "dependencies": { - "loose-envify": "^1.0.0" - } - }, - "node_modules/ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - }, - "node_modules/ipaddr.js": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz", - "integrity": "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "dev": true, - "dependencies": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-alphabetical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-alphanumeric": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz", - "integrity": "sha512-ZmRL7++ZkcMOfDuWZuMJyIVLr2keE1o/DeNWh1EmgqGhUcV+9BIVsx0BcSBOHTZqzjs4+dISzr2KAeBEWGgXeA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-alphanumerical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", - "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", - "dev": true, - "dependencies": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "node_modules/is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "dependencies": { - "has-bigints": "^1.0.1" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "dev": true, - "dependencies": { - "binary-extensions": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "node_modules/is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-ci": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", - "dev": true, - "dependencies": { - "ci-info": "^3.2.0" - }, - "bin": { - "is-ci": "bin.js" - } - }, - "node_modules/is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "dependencies": { - "has": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-decimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true, - "bin": { - "is-docker": "cli.js" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-electron": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-electron/-/is-electron-2.2.2.tgz", - "integrity": "sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg==" - }, - "node_modules/is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "dependencies": { - "is-plain-object": "^2.0.4" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "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, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-glob": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", - "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-hexadecimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-lambda": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=", - "dev": true - }, - "node_modules/is-negated-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", - "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true, - "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, - "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==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", - "engines": { - "node": ">=8" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/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 - }, - "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==", - "dev": true, - "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-regexp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz", - "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "dev": true, - "dependencies": { - "is-unc-path": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "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==", - "dev": true, - "dependencies": { - "has-tostringtag": "^1.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-supported-regexp-flag": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-supported-regexp-flag/-/is-supported-regexp-flag-1.0.1.tgz", - "integrity": "sha512-3vcJecUUrpgCqc/ca0aWeNu64UGgxcvO60K/Fkr1N6RSvfGCTU60UKN68JDmKokgba0rFFJs12EnzOQa14ubKQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dev": true, - "dependencies": { - "has-symbols": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "node_modules/is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "dev": true, - "dependencies": { - "unc-path-regex": "^0.1.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, - "node_modules/is-valid-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", - "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/is-what": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.7.tgz", - "integrity": "sha512-DBVOQNiPKnGMxRMLIYSwERAS5MVY1B7xYiGnpgctsOFvVDz9f9PFXXxMcTOHuoqYp4NK9qFYQaIC1NRRxLMpBQ==", - "engines": { - "node": ">=12.13" - }, - "funding": { - "url": "https://github.com/sponsors/mesqueeb" - } - }, - "node_modules/is-whitespace-character": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", - "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/is-word-character": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", - "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "dependencies": { - "is-docker": "^2.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "node_modules/isbinaryfile": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.0.tgz", - "integrity": "sha512-UDdnyGvMajJUWCkib7Cei/dvyJrrvo4FIrsvSFWdPpXSUorzXrDJ0S+X5Q4ZlasfPjca4yqCNNsjbCeiy8FFeg==", - "dev": true, - "engines": { - "node": ">= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/gjtorikian/" - } - }, - "node_modules/isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "node_modules/isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/istanbul-lib-instrument": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", - "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", - "dev": true, - "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/istanbul-lib-instrument/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/istanbul-lib-report": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", - "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", - "dev": true, - "dependencies": { - "istanbul-lib-coverage": "^3.0.0", - "make-dir": "^3.0.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/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, - "dependencies": { - "debug": "^4.1.1", - "istanbul-lib-coverage": "^3.0.0", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/istanbul-lib-source-maps/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/istanbul-reports": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", - "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", - "dev": true, - "dependencies": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/jake": { - "version": "10.8.5", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", - "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", - "dev": true, - "dependencies": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.1", - "minimatch": "^3.0.4" - }, - "bin": { - "jake": "bin/cli.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", - "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", - "dev": true, - "dependencies": { - "@jest/core": "^27.5.1", - "import-local": "^3.0.2", - "jest-cli": "^27.5.1" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-changed-files": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", - "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "execa": "^5.0.0", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-circus": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", - "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-cli": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", - "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", - "dev": true, - "dependencies": { - "@jest/core": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - }, - "bin": { - "jest": "bin/jest.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" - }, - "peerDependenciesMeta": { - "node-notifier": { - "optional": true - } - } - }, - "node_modules/jest-config": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", - "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", - "dev": true, - "dependencies": { - "@babel/core": "^7.8.0", - "@jest/test-sequencer": "^27.5.1", - "@jest/types": "^27.5.1", - "babel-jest": "^27.5.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.9", - "jest-circus": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-jasmine2": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "ts-node": ">=9.0.0" - }, - "peerDependenciesMeta": { - "ts-node": { - "optional": true - } - } - }, - "node_modules/jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-docblock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", - "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", - "dev": true, - "dependencies": { - "detect-newline": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-each": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", - "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-jsdom": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", - "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1", - "jsdom": "^16.6.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-environment-node": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", - "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-haste-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", - "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^27.5.1", - "jest-serializer": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "micromatch": "^4.0.4", - "walker": "^1.0.7" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "optionalDependencies": { - "fsevents": "^2.3.2" - } - }, - "node_modules/jest-jasmine2": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", - "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-leak-detector": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", - "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", - "dev": true, - "dependencies": { - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", - "dev": true, - "dependencies": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dev": true, - "dependencies": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-pnp-resolver": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", - "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", - "dev": true, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "jest-resolve": "*" - }, - "peerDependenciesMeta": { - "jest-resolve": { - "optional": true - } - } - }, - "node_modules/jest-regex-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", - "dev": true, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", - "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-resolve-dependencies": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", - "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-snapshot": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runner": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", - "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", - "dev": true, - "dependencies": { - "@jest/console": "^27.5.1", - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-leak-detector": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-runtime": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", - "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", - "dev": true, - "dependencies": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/globals": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-serializer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", - "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", - "dev": true, - "dependencies": { - "@types/node": "*", - "graceful-fs": "^4.2.9" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-snapshot": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", - "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", - "dev": true, - "dependencies": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^27.5.1", - "semver": "^7.3.2" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-validate": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", - "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", - "dev": true, - "dependencies": { - "@jest/types": "^27.5.1", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "leven": "^3.1.0", - "pretty-format": "^27.5.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/jest-watcher": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", - "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", - "dev": true, - "dependencies": { - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^27.5.1", - "string-length": "^4.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "node_modules/jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, - "dependencies": { - "@types/node": "*", - "merge-stream": "^2.0.0", - "supports-color": "^8.0.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/jest-worker/node_modules/supports-color": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", - "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/js-sdsl": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", - "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, - "node_modules/js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "node_modules/js-yaml": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", - "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", - "dependencies": { - "argparse": "^2.0.1" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "dependencies": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "canvas": "^2.5.0" - }, - "peerDependenciesMeta": { - "canvas": { - "optional": true - } - } - }, - "node_modules/jsdom/node_modules/@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/jsdom/node_modules/form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "dependencies": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/jsdom/node_modules/http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "dependencies": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", - "bin": { - "jsesc": "bin/jsesc" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "node_modules/json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "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==" - }, - "node_modules/json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "dev": true - }, - "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "node_modules/json-schema-typed": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-7.0.3.tgz", - "integrity": "sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==" - }, - "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": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "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==", - "dev": true, - "optional": true - }, - "node_modules/json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", - "bin": { - "json5": "lib/cli.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/jsx-ast-utils": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", - "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==", - "dev": true, - "dependencies": { - "array-includes": "^3.1.5", - "object.assign": "^4.1.3" - }, - "engines": { - "node": ">=4.0" - } - }, - "node_modules/jszip": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.9.1.tgz", - "integrity": "sha512-H9A60xPqJ1CuC4Ka6qxzXZeU8aNmgOeP5IFqwJbQQwtu2EUYxota3LdsiZWplF7Wgd9tkAd0mdu36nceSaPuYw==", - "dev": true, - "dependencies": { - "lie": "~3.3.0", - "pako": "~1.0.2", - "readable-stream": "~2.3.6", - "set-immediate-shim": "~1.0.1" - } - }, - "node_modules/keyboardevent-from-electron-accelerator": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/keyboardevent-from-electron-accelerator/-/keyboardevent-from-electron-accelerator-2.0.0.tgz", - "integrity": "sha512-iQcmNA0M4ETMNi0kG/q0h/43wZk7rMeKYrXP7sqKIJbHkTU8Koowgzv+ieR/vWJbOwxx5nDC3UnudZ0aLSu4VA==" - }, - "node_modules/keyboardevents-areequal": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/keyboardevents-areequal/-/keyboardevents-areequal-0.2.2.tgz", - "integrity": "sha512-Nv+Kr33T0mEjxR500q+I6IWisOQ0lK1GGOncV0kWE6n4KFmpcu7RUX5/2B0EUtX51Cb0HjZ9VJsSY3u4cBa0kw==" - }, - "node_modules/keyv": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", - "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", - "dev": true, - "dependencies": { - "json-buffer": "3.0.1" - } - }, - "node_modules/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/kleur": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", - "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/klona": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz", - "integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==", - "engines": { - "node": ">= 8" - } - }, - "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 - }, - "node_modules/language-subtag-registry": { - "version": "0.3.21", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz", - "integrity": "sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg==", - "dev": true - }, - "node_modules/language-tags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", - "integrity": "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=", - "dev": true, - "dependencies": { - "language-subtag-registry": "~0.3.2" - } - }, - "node_modules/lazy-val": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz", - "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==" - }, - "node_modules/lazystream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", - "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", - "dev": true, - "dependencies": { - "readable-stream": "^2.0.5" - }, - "engines": { - "node": ">= 0.6.3" - } - }, - "node_modules/lead": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", - "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", - "dev": true, - "dependencies": { - "flush-write-stream": "^1.0.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "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, - "engines": { - "node": ">=6" - } - }, - "node_modules/levn": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", - "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/lie": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", - "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", - "dev": true, - "dependencies": { - "immediate": "~3.0.5" - } - }, - "node_modules/lilconfig": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.5.tgz", - "integrity": "sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "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==" - }, - "node_modules/lint-staged": { - "version": "12.3.7", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-12.3.7.tgz", - "integrity": "sha512-/S4D726e2GIsDVWIk1XGvheCaDm1SJRQp8efamZFWJxQMVEbOwSysp7xb49Oo73KYCdy97mIWinhlxcoNqIfIQ==", - "dev": true, - "dependencies": { - "cli-truncate": "^3.1.0", - "colorette": "^2.0.16", - "commander": "^8.3.0", - "debug": "^4.3.3", - "execa": "^5.1.1", - "lilconfig": "2.0.4", - "listr2": "^4.0.1", - "micromatch": "^4.0.4", - "normalize-path": "^3.0.0", - "object-inspect": "^1.12.0", - "pidtree": "^0.5.0", - "string-argv": "^0.3.1", - "supports-color": "^9.2.1", - "yaml": "^1.10.2" - }, - "bin": { - "lint-staged": "bin/lint-staged.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/lint-staged" - } - }, - "node_modules/lint-staged/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, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/lint-staged/node_modules/ansi-styles": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.1.0.tgz", - "integrity": "sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/lint-staged/node_modules/cli-truncate": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", - "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", - "dev": true, - "dependencies": { - "slice-ansi": "^5.0.0", - "string-width": "^5.0.0" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lint-staged/node_modules/commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/lint-staged/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, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lint-staged/node_modules/lilconfig": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.4.tgz", - "integrity": "sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "node_modules/lint-staged/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, - "dependencies": { - "ansi-styles": "^6.0.0", - "is-fullwidth-code-point": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/slice-ansi?sponsor=1" - } - }, - "node_modules/lint-staged/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/lint-staged/node_modules/strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/lint-staged/node_modules/supports-color": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.2.2.tgz", - "integrity": "sha512-XC6g/Kgux+rJXmwokjm9ECpD6k/smUoS5LKlUCcsYr4IY3rW0XyAympon2RmxGrlnZURMpg5T18gWDP9CsHXFA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/supports-color?sponsor=1" - } - }, - "node_modules/listr2": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.5.tgz", - "integrity": "sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA==", - "dev": true, - "dependencies": { - "cli-truncate": "^2.1.0", - "colorette": "^2.0.16", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rfdc": "^1.3.0", - "rxjs": "^7.5.5", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" - }, - "engines": { - "node": ">=12" - }, - "peerDependencies": { - "enquirer": ">= 2.3.0 < 3" - }, - "peerDependenciesMeta": { - "enquirer": { - "optional": true - } - } - }, - "node_modules/listr2/node_modules/rxjs": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", - "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", - "dev": true, - "dependencies": { - "tslib": "^2.1.0" - } - }, - "node_modules/load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/load-json-file/node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/load-json-file/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/load-script": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz", - "integrity": "sha1-BJGTngvuVkPuSUp+PaPSuscMbKQ=" - }, - "node_modules/loader-runner": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", - "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", - "dev": true, - "engines": { - "node": ">=6.11.5" - } - }, - "node_modules/loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "dev": true, - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - }, - "engines": { - "node": ">=8.9.0" - } - }, - "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==", - "dev": true, - "dependencies": { - "p-locate": "^5.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "node_modules/lodash.escaperegexp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", - "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=" - }, - "node_modules/lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" - }, - "node_modules/lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", - "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==", - "dev": true - }, - "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/lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", - "dev": true - }, - "node_modules/log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/log-update/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, - "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/log-update/node_modules/wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/longest-streak": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", - "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ==", - "dev": true, - "dependencies": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dev": true, - "dependencies": { - "tslib": "^2.0.3" - } - }, - "node_modules/lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/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==", - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/lz-string": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", - "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=", - "dev": true, - "bin": { - "lz-string": "bin/bin.js" - } - }, - "node_modules/lzma-native": { - "version": "8.0.6", - "resolved": "https://registry.npmjs.org/lzma-native/-/lzma-native-8.0.6.tgz", - "integrity": "sha512-09xfg67mkL2Lz20PrrDeNYZxzeW7ADtpYFbwSQh9U8+76RIzx5QsJBMy8qikv3hbUPfpy6hqwxt6FcGK81g9AA==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "node-addon-api": "^3.1.0", - "node-gyp-build": "^4.2.1", - "readable-stream": "^3.6.0" - }, - "bin": { - "lzmajs": "bin/lzmajs" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/lzma-native/node_modules/node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", - "dev": true - }, - "node_modules/lzma-native/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "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==", - "dev": true, - "dependencies": { - "semver": "^6.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/make-dir/node_modules/semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "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" - } - }, - "node_modules/map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", - "dev": true, - "dependencies": { - "object-visit": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/markdown-escapes": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", - "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/markdown-table": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", - "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", - "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==", - "dev": true, - "optional": true, - "dependencies": { - "escape-string-regexp": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/matcher-collection": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/matcher-collection/-/matcher-collection-2.0.1.tgz", - "integrity": "sha512-daE62nS2ZQsDg9raM0IlZzLmI2u+7ZapXBwdoeBUKAYERPDDIc0qNqA8E0Rp2D+gspKR7BgIFP52GeujaGXWeQ==", - "dev": true, - "dependencies": { - "@types/minimatch": "^3.0.3", - "minimatch": "^3.0.2" - }, - "engines": { - "node": "6.* || 8.* || >= 10.*" - } - }, - "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, - "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" - } - }, - "node_modules/mdast-util-compact": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.4.tgz", - "integrity": "sha512-3YDMQHI5vRiS2uygEFYaqckibpJtKq5Sj2c8JioeOQBU6INpKbdWzfyLqFFnDwEcEnRFIdMsguzs5pC1Jp4Isg==", - "dev": true, - "dependencies": { - "unist-util-visit": "^1.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "dev": true - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/memfs": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.1.tgz", - "integrity": "sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==", - "dev": true, - "dependencies": { - "fs-monkey": "1.0.3" - }, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/memoize-one": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", - "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" - }, - "node_modules/memory-fs": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz", - "integrity": "sha1-8rslNovBIeORwlIN6Slpyu4KApA=", - "dev": true - }, - "node_modules/meow": { - "version": "9.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", - "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", - "dev": true, - "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" - }, - "engines": { - "node": ">=10" - }, - "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==", - "dev": true, - "engines": { - "node": ">=10" - }, - "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": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true - }, - "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==", - "dev": true, - "engines": { - "node": ">= 8" - } - }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/micromatch": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", - "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", - "dev": true, - "dependencies": { - "braces": "^3.0.2", - "picomatch": "^2.3.1" - }, - "engines": { - "node": ">=8.6" - } - }, - "node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "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==", - "engines": { - "node": ">= 0.6" - } - }, - "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==", - "dependencies": { - "mime-db": "1.52.0" - }, - "engines": { - "node": ">= 0.6" - } - }, - "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==", - "engines": { - "node": ">=6" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/mini-css-extract-plugin": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.0.tgz", - "integrity": "sha512-ndG8nxCEnAemsg4FSgS+yNyHKgkTB4nPKqCOgh65j3/30qqC5RaSQQXMm++Y6sb6E1zRSxPkztj9fqxhS1Eo6w==", - "dev": true, - "dependencies": { - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/mini-css-extract-plugin/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": 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" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/mini-css-extract-plugin/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/mini-css-extract-plugin/node_modules/schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "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, - "dependencies": { - "brace-expansion": "^1.1.7" - }, - "engines": { - "node": "*" - } - }, - "node_modules/minimist": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", - "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", - "dev": 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==", - "dev": true, - "dependencies": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0", - "kind-of": "^6.0.3" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/minimist-options/node_modules/is-plain-obj": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", - "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/minipass": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", - "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", - "dev": true, - "dependencies": { - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minipass-sized": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", - "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "dependencies": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "dependencies": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "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==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/mktemp": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/mktemp/-/mktemp-0.4.0.tgz", - "integrity": "sha1-bQUVYRyKjITkhKogABKbmOmB/ws=", - "dev": true, - "engines": { - "node": ">0.9" - } - }, - "node_modules/mrmime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.0.tgz", - "integrity": "sha512-a70zx7zFfVO7XpnQ2IX1Myh9yY4UYvfld/dikWRnsXxbyvMcfz+u6UfgNAtH+k2QqtJuzVpv6eLTx1G2+WKZbQ==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "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/multicast-dns": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.4.tgz", - "integrity": "sha512-XkCYOU+rr2Ft3LI6w4ye51M3VK31qJXFIxu0XLw169PtKG0Zx47OrXeVW/GCYOfpC9s1yyyf1S+L8/4LY0J9Zw==", - "dev": true, - "dependencies": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - }, - "bin": { - "multicast-dns": "cli.js" - } - }, - "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", - "bin": { - "nanoid": "bin/nanoid.cjs" - }, - "engines": { - "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" - } - }, - "node_modules/nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "node_modules/natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha1-F7CVgZiJef3a/gIB6TG6kzyWy7Q=", - "dev": true - }, - "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==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/neo-async": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", - "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", - "dev": true - }, - "node_modules/net": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/net/-/net-1.0.2.tgz", - "integrity": "sha512-kbhcj2SVVR4caaVnGLJKmlk2+f+oLkjqdKeQlmUtz6nGzOpbcobwVIeSURNgraV/v3tlmGIX82OcPCl0K6RbHQ==" - }, - "node_modules/no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dev": true, - "dependencies": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node_modules/node-abi": { - "version": "3.33.0", - "resolved": "https://registry.yarnpkg.com/node-abi/-/node-abi-3.33.0.tgz#8b23a0cec84e1c5f5411836de6a9b84bccf26e7f", - "integrity": "sha512-7GGVawqyHF4pfd0YFybhv/eM9JwTtPqx0mAanQ146O3FlSh3pA24zf9IRQTOsfTSqXTNzPSP5iagAJ94jjuVog==", - "dev": true, - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/node-addon-api": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", - "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", - "dev": true, - "optional": true - }, - "node_modules/node-api-version": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.1.4.tgz", - "integrity": "sha512-KGXihXdUChwJAOHO53bv9/vXcLmdUsZ6jIptbvYvkpKfth+r7jw44JkVxQFA3kX5nQjzjmGu1uAu/xNNLNlI5g==", - "dev": true, - "dependencies": { - "semver": "^7.3.5" - } - }, - "node_modules/node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", - "dev": true, - "engines": { - "node": ">= 6.13.0" - } - }, - "node_modules/node-gyp-build": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz", - "integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==", - "dev": true, - "bin": { - "node-gyp-build": "bin.js", - "node-gyp-build-optional": "optional.js", - "node-gyp-build-test": "build-test.js" - } - }, - "node_modules/node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", - "dev": true - }, - "node_modules/node-mpv": { - "version": "2.0.0-beta.3", - "resolved": "git+ssh://git@github.com/jeffvli/Node-MPV.git#c7f84d7966b82e5916c3b4bb47cac667bb895c22" - }, - "node_modules/node-releases": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", - "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==" - }, - "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, - "dependencies": { - "hosted-git-info": "^4.0.1", - "is-core-module": "^2.5.0", - "semver": "^7.3.4", - "validate-npm-package-license": "^3.0.1" - }, - "engines": { - "node": ">=10" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/normalize-selector": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz", - "integrity": "sha512-dxvWdI8gw6eAvk9BlPffgEoGfM7AdijoCwOEJge3e3ulT2XLgmU7KvvxprOaCu05Q1uGRHmOhHe1r6emZoKyFw==", - "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==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/now-and-later": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", - "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", - "dev": true, - "dependencies": { - "once": "^1.3.2" - }, - "engines": { - "node": ">= 0.10" - } - }, - "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, - "dependencies": { - "path-key": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/npmlog": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.1.tgz", - "integrity": "sha512-BTHDvY6nrRHuRfyjt1MAufLxYdVXZfd099H4+i1f0lPywNQyI4foeNXJRObB/uy+TYqUW0vAD9gbdSOXPst7Eg==", - "dev": true, - "dependencies": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.0", - "set-blocking": "^2.0.0" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" - } - }, - "node_modules/nth-check": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", - "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", - "dev": true, - "dependencies": { - "boolbase": "^1.0.0" - }, - "funding": { - "url": "https://github.com/fb55/nth-check?sponsor=1" - } - }, - "node_modules/num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==", - "dev": true - }, - "node_modules/nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", - "dev": true - }, - "node_modules/object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", - "dev": true, - "dependencies": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object-copy/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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==", - "dev": true, - "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==", - "dev": true, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", - "dev": true, - "dependencies": { - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.entries": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", - "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/object.fromentries": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", - "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.hasown": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", - "integrity": "sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==", - "dev": true, - "dependencies": { - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "dev": true, - "dependencies": { - "isobject": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/object.values": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", - "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": true - }, - "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==", - "dev": true, - "dependencies": { - "ee-first": "1.1.1" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "dependencies": { - "wrappy": "1" - } - }, - "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "dependencies": { - "mimic-fn": "^2.1.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/open": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", - "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", - "dev": true, - "dependencies": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", - "dev": true, - "bin": { - "opener": "bin/opener-bin.js" - } - }, - "node_modules/optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "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" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "dev": true, - "dependencies": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/ordered-read-streams": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", - "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", - "dev": true, - "dependencies": { - "readable-stream": "^2.0.1" - } - }, - "node_modules/p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "dependencies": { - "yocto-queue": "^0.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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==", - "dev": true, - "dependencies": { - "p-limit": "^3.0.2" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "dependencies": { - "aggregate-error": "^3.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-retry": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.1.tgz", - "integrity": "sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA==", - "dev": true, - "dependencies": { - "@types/retry": "^0.12.0", - "retry": "^0.13.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/p-retry/node_modules/retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "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==", - "engines": { - "node": ">=6" - } - }, - "node_modules/pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "node_modules/param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "dev": true, - "dependencies": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "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==", - "dependencies": { - "callsites": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/parse-entities": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", - "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==", - "dev": true, - "dependencies": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" - } - }, - "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==", - "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" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true - }, - "node_modules/parse5-htmlparser2-tree-adapter": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", - "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", - "dev": true, - "dependencies": { - "parse5": "^6.0.1" - } - }, - "node_modules/parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dev": true, - "dependencies": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "node_modules/pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": 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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "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": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true, - "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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "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==" - }, - "node_modules/path-posix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-posix/-/path-posix-1.0.0.tgz", - "integrity": "sha1-BrJhE/Vr6rBCVFojv6iAA8ysJg8=", - "dev": true - }, - "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": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", - "dev": true - }, - "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==", - "engines": { - "node": ">=8" - } - }, - "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==", - "dev": true - }, - "node_modules/picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" - }, - "node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" - } - }, - "node_modules/pidtree": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.5.0.tgz", - "integrity": "sha512-9nxspIM7OpZuhBxPg73Zvyq7j1QMPMPsGKTqRc2XOaFQauDvoNz9fM1Wdkjmeo7l9GXOZiRs97sPkuayl39wjA==", - "dev": true, - "bin": { - "pidtree": "bin/pidtree.js" - }, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/pirates": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", - "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "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, - "dependencies": { - "find-up": "^4.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, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "dependencies": { - "find-up": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/pkg-up/node_modules/find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dependencies": { - "locate-path": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dependencies": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/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==", - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/pkg-up/node_modules/p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dependencies": { - "p-limit": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/pkg-up/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "engines": { - "node": ">=4" - } - }, - "node_modules/plist": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.6.tgz", - "integrity": "sha512-WiIVYyrp8TD4w8yCvyeIr+lkmrGRd5u0VbRnU+tP/aRLxP/YadJUYOMZJ/6hIa3oUyVCsycXvtNRgd5XBJIbiA==", - "dev": true, - "dependencies": { - "base64-js": "^1.5.1", - "xmlbuilder": "^15.1.1" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/portfinder": { - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", - "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", - "dev": true, - "dependencies": { - "async": "^2.6.2", - "debug": "^3.1.1", - "mkdirp": "^0.5.5" - }, - "engines": { - "node": ">= 0.12.0" - } - }, - "node_modules/portfinder/node_modules/async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "dev": true, - "dependencies": { - "lodash": "^4.17.14" - } - }, - "node_modules/portfinder/node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss": { - "version": "8.4.20", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz", - "integrity": "sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==", - "dev": true, - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/postcss" - } - ], - "dependencies": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - }, - "engines": { - "node": "^10 || ^12 || >=14" - } - }, - "node_modules/postcss-calc": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", - "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", - "dev": true, - "dependencies": { - "postcss-selector-parser": "^6.0.9", - "postcss-value-parser": "^4.2.0" - }, - "peerDependencies": { - "postcss": "^8.2.2" - } - }, - "node_modules/postcss-colormin": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.0.tgz", - "integrity": "sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg==", - "dev": true, - "dependencies": { - "browserslist": "^4.16.6", - "caniuse-api": "^3.0.0", - "colord": "^2.9.1", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-convert-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.0.tgz", - "integrity": "sha512-GkyPbZEYJiWtQB0KZ0X6qusqFHUepguBCNFi9t5JJc7I2OTXG7C0twbTLvCfaKOLl3rSXmpAwV7W5txd91V84g==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-comments": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.1.tgz", - "integrity": "sha512-5JscyFmvkUxz/5/+TB3QTTT9Gi9jHkcn8dcmmuN68JQcv3aQg4y88yEHHhwFB52l/NkaJ43O0dbksGMAo49nfQ==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-duplicates": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", - "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-empty": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", - "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-discard-overridden": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", - "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-html": { - "version": "0.36.0", - "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-0.36.0.tgz", - "integrity": "sha512-HeiOxGcuwID0AFsNAL0ox3mW6MHH5cstWN1Z3Y+n6H+g12ih7LHdYxWwEA/QmrebctLjo79xz9ouK3MroHwOJw==", - "dev": true, - "dependencies": { - "htmlparser2": "^3.10.0" - }, - "peerDependencies": { - "postcss": ">=5.0.0", - "postcss-syntax": ">=0.36.0" - } - }, - "node_modules/postcss-html/node_modules/dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "dev": true, - "dependencies": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - } - }, - "node_modules/postcss-html/node_modules/dom-serializer/node_modules/domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/fb55" - } - ] - }, - "node_modules/postcss-html/node_modules/dom-serializer/node_modules/entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true, - "funding": { - "url": "https://github.com/fb55/entities?sponsor=1" - } - }, - "node_modules/postcss-html/node_modules/domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true - }, - "node_modules/postcss-html/node_modules/domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "dev": true, - "dependencies": { - "domelementtype": "1" - } - }, - "node_modules/postcss-html/node_modules/domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "dev": true, - "dependencies": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "node_modules/postcss-html/node_modules/entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - }, - "node_modules/postcss-html/node_modules/htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "dev": true, - "dependencies": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "node_modules/postcss-html/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/postcss-jsx": { - "version": "0.36.4", - "resolved": "https://registry.npmjs.org/postcss-jsx/-/postcss-jsx-0.36.4.tgz", - "integrity": "sha512-jwO/7qWUvYuWYnpOb0+4bIIgJt7003pgU3P6nETBLaOyBXuTD55ho21xnals5nBrlpTIFodyd3/jBi6UO3dHvA==", - "dev": true, - "dependencies": { - "@babel/core": ">=7.2.2" - }, - "peerDependencies": { - "postcss": ">=5.0.0", - "postcss-syntax": ">=0.36.0" - } - }, - "node_modules/postcss-less": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-3.1.4.tgz", - "integrity": "sha512-7TvleQWNM2QLcHqvudt3VYjULVB49uiW6XzEUFmvwHzvsOEF5MwBrIXZDJQvJNFGjJQTzSzZnDoCJ8h/ljyGXA==", - "dev": true, - "dependencies": { - "postcss": "^7.0.14" - }, - "engines": { - "node": ">=6.14.4" - } - }, - "node_modules/postcss-less/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "node_modules/postcss-less/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-less/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-markdown": { - "version": "0.36.0", - "resolved": "https://registry.npmjs.org/postcss-markdown/-/postcss-markdown-0.36.0.tgz", - "integrity": "sha512-rl7fs1r/LNSB2bWRhyZ+lM/0bwKv9fhl38/06gF6mKMo/NPnp55+K1dSTosSVjFZc0e1ppBlu+WT91ba0PMBfQ==", - "dev": true, - "dependencies": { - "remark": "^10.0.1", - "unist-util-find-all-after": "^1.0.2" - }, - "peerDependencies": { - "postcss": ">=5.0.0", - "postcss-syntax": ">=0.36.0" - } - }, - "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-merge-longhand": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.4.tgz", - "integrity": "sha512-hbqRRqYfmXoGpzYKeW0/NCZhvNyQIlQeWVSao5iKWdyx7skLvCfQFGIUsP9NUs3dSbPac2IC4Go85/zG+7MlmA==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0", - "stylehacks": "^5.1.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-merge-rules": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.1.tgz", - "integrity": "sha512-8wv8q2cXjEuCcgpIB1Xx1pIy8/rhMPIQqYKNzEdyx37m6gpq83mQQdCxgIkFgliyEnKvdwJf/C61vN4tQDq4Ww==", - "dev": true, - "dependencies": { - "browserslist": "^4.16.6", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^3.1.0", - "postcss-selector-parser": "^6.0.5" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-font-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", - "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-gradients": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", - "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", - "dev": true, - "dependencies": { - "colord": "^2.9.1", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-params": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.2.tgz", - "integrity": "sha512-aEP+p71S/urY48HWaRHasyx4WHQJyOYaKpQ6eXl8k0kxg66Wt/30VR6/woh8THgcpRbonJD5IeD+CzNhPi1L8g==", - "dev": true, - "dependencies": { - "browserslist": "^4.16.6", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-minify-selectors": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.0.tgz", - "integrity": "sha512-vYxvHkW+iULstA+ctVNx0VoRAR4THQQRkG77o0oa4/mBS0OzGvvzLIvHDv/nNEM0crzN2WIyFU5X7wZhaUK3RA==", - "dev": true, - "dependencies": { - "postcss-selector-parser": "^6.0.5" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-modules-extract-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-local-by-default": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", - "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", - "dev": true, - "dependencies": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-scope": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", - "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", - "dev": true, - "dependencies": { - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "dev": true, - "dependencies": { - "icss-utils": "^5.0.0" - }, - "engines": { - "node": "^10 || ^12 || >= 14" - }, - "peerDependencies": { - "postcss": "^8.1.0" - } - }, - "node_modules/postcss-normalize-charset": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", - "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", - "dev": true, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-display-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", - "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-positions": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.0.tgz", - "integrity": "sha512-8gmItgA4H5xiUxgN/3TVvXRoJxkAWLW6f/KKhdsH03atg0cB8ilXnrB5PpSshwVu/dD2ZsRFQcR1OEmSBDAgcQ==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-repeat-style": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.0.tgz", - "integrity": "sha512-IR3uBjc+7mcWGL6CtniKNQ4Rr5fTxwkaDHwMBDGGs1x9IVRkYIT/M4NelZWkAOBdV6v3Z9S46zqaKGlyzHSchw==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-string": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", - "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-timing-functions": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", - "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-unicode": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.0.tgz", - "integrity": "sha512-J6M3MizAAZ2dOdSjy2caayJLQT8E8K9XjLce8AUQMwOrCvjCHv24aLC/Lps1R1ylOfol5VIDMaM/Lo9NGlk1SQ==", - "dev": true, - "dependencies": { - "browserslist": "^4.16.6", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", - "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", - "dev": true, - "dependencies": { - "normalize-url": "^6.0.1", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-normalize-whitespace": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", - "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-ordered-values": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.1.tgz", - "integrity": "sha512-7lxgXF0NaoMIgyihL/2boNAEZKiW0+HkMhdKMTD93CjW8TdCy2hSdj8lsAo+uwm7EDG16Da2Jdmtqpedl0cMfw==", - "dev": true, - "dependencies": { - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-reduce-initial": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.0.tgz", - "integrity": "sha512-5OgTUviz0aeH6MtBjHfbr57tml13PuedK/Ecg8szzd4XRMbYxH4572JFG067z+FqBIf6Zp/d+0581glkvvWMFw==", - "dev": true, - "dependencies": { - "browserslist": "^4.16.6", - "caniuse-api": "^3.0.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-reduce-transforms": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", - "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-reporter": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-6.0.1.tgz", - "integrity": "sha512-LpmQjfRWyabc+fRygxZjpRxfhRf9u/fdlKf4VHG4TSPbV2XNsuISzYW1KL+1aQzx53CAppa1bKG4APIB/DOXXw==", - "dev": true, - "dependencies": { - "chalk": "^2.4.1", - "lodash": "^4.17.11", - "log-symbols": "^2.2.0", - "postcss": "^7.0.7" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/postcss-reporter/node_modules/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, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-reporter/node_modules/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, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-reporter/node_modules/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, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/postcss-reporter/node_modules/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 - }, - "node_modules/postcss-reporter/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, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/postcss-reporter/node_modules/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, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-reporter/node_modules/log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "dependencies": { - "chalk": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-reporter/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "node_modules/postcss-reporter/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-reporter/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-reporter/node_modules/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, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "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/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, - "engines": { - "node": ">=12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.3.3" - } - }, - "node_modules/postcss-sass": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.3.5.tgz", - "integrity": "sha512-B5z2Kob4xBxFjcufFnhQ2HqJQ2y/Zs/ic5EZbCywCkxKd756Q40cIQ/veRDwSrw1BF6+4wUgmpm0sBASqVi65A==", - "dev": true, - "dependencies": { - "gonzales-pe": "^4.2.3", - "postcss": "^7.0.1" - } - }, - "node_modules/postcss-sass/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "node_modules/postcss-sass/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/postcss-sass/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/postcss-scss": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.4.tgz", - "integrity": "sha512-aBBbVyzA8b3hUL0MGrpydxxXKXFZc5Eqva0Q3V9qsBOLEMsjb6w49WfpsoWzpEgcqJGW4t7Rio8WXVU9Gd8vWg==", - "dev": true, - "engines": { - "node": ">=12.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - }, - "peerDependencies": { - "postcss": "^8.3.3" - } - }, - "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==", - "dev": true, - "dependencies": { - "cssesc": "^3.0.0", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/postcss-sorting": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-7.0.1.tgz", - "integrity": "sha512-iLBFYz6VRYyLJEJsBJ8M3TCqNcckVzz4wFounSc5Oez35ogE/X+aoC5fFu103Ot7NyvjU3/xqIXn93Gp3kJk4g==", - "dev": true, - "peerDependencies": { - "postcss": "^8.3.9" - } - }, - "node_modules/postcss-svgo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", - "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", - "dev": true, - "dependencies": { - "postcss-value-parser": "^4.2.0", - "svgo": "^2.7.0" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/postcss-syntax": { - "version": "0.36.2", - "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz", - "integrity": "sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==", - "dev": true, - "peerDependencies": { - "postcss": ">=5.0.0" - } - }, - "node_modules/postcss-unique-selectors": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", - "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", - "dev": true, - "dependencies": { - "postcss-selector-parser": "^6.0.5" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "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==" - }, - "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==", - "dev": true, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/prettier": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz", - "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==", - "dev": true, - "bin": { - "prettier": "bin-prettier.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "url": "https://github.com/prettier/prettier?sponsor=1" - } - }, - "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, - "dependencies": { - "fast-diff": "^1.1.2" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/pretty-error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", - "dev": true, - "dependencies": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, - "node_modules/pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - } - }, - "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, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "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==", - "dev": true - }, - "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "node_modules/promise-map-series": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/promise-map-series/-/promise-map-series-0.3.0.tgz", - "integrity": "sha512-3npG2NGhTc8BWBolLLf8l/92OxMGaRLbqvIh9wjCHhDXNvk4zsxaTaCpiCunW09qWPrN2zeNSNwRLVBrQQtutA==", - "dev": true, - "engines": { - "node": "10.* || >= 12.*" - } - }, - "node_modules/promise-retry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", - "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "dev": true, - "dependencies": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - }, - "engines": { - "node": ">=10" - } - }, - "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" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - } - }, - "node_modules/prop-types/node_modules/react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - }, - "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==", - "dev": true, - "dependencies": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-addr/node_modules/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==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" - }, - "node_modules/psl": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "dev": true - }, - "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==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "node_modules/pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "dependencies": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - } - }, - "node_modules/pumpify/node_modules/pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "dependencies": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "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==", - "engines": { - "node": ">=6" - } - }, - "node_modules/qs": { - "version": "6.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "dev": true, - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ] - }, - "node_modules/queue-tick": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", - "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", - "dev": true - }, - "node_modules/quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/quick-temp": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/quick-temp/-/quick-temp-0.1.8.tgz", - "integrity": "sha1-urAqJCq4+w3XWKPJd2sy+aXZRAg=", - "dev": true, - "dependencies": { - "mktemp": "~0.4.0", - "rimraf": "^2.5.4", - "underscore.string": "~3.3.4" - } - }, - "node_modules/quick-temp/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "dependencies": { - "safe-buffer": "^5.1.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==", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "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==", - "dev": true, - "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/raw-body/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "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==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", - "dependencies": { - "loose-envify": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-dom": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", - "dependencies": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" - }, - "peerDependencies": { - "react": "^18.2.0" - } - }, - "node_modules/react-dom/node_modules/scheduler": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", - "dependencies": { - "loose-envify": "^1.1.0" - } - }, - "node_modules/react-error-boundary": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz", - "integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==", - "dependencies": { - "@babel/runtime": "^7.12.5" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - }, - "peerDependencies": { - "react": ">=16.13.1" - } - }, - "node_modules/react-fast-compare": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", - "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" - }, - "node_modules/react-i18next": { - "version": "11.16.7", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.16.7.tgz", - "integrity": "sha512-7yotILJLnKfvUfrl/nt9eK9vFpVFjZPLWAwBzWL6XppSZZEvlmlKk0GBGDCAPfLfs8oND7WAbry8wGzdoiW5Nw==", - "dependencies": { - "@babel/runtime": "^7.14.5", - "html-escaper": "^2.0.2", - "html-parse-stringify": "^3.0.1" - }, - "peerDependencies": { - "i18next": ">= 19.0.0", - "react": ">= 16.8.0" - }, - "peerDependenciesMeta": { - "react-dom": { - "optional": true - }, - "react-native": { - "optional": true - } - } - }, - "node_modules/react-icons": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.8.0.tgz", - "integrity": "sha512-N6+kOLcihDiAnj5Czu637waJqSnwlMNROzVZMhfX68V/9bu9qHaMIJC4UdozWoOk57gahFCNHwVvWzm0MTzRjg==", - "peerDependencies": { - "react": "*" - } - }, - "node_modules/react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" - }, - "node_modules/react-player": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/react-player/-/react-player-2.11.0.tgz", - "integrity": "sha512-fIrwpuXOBXdEg1FiyV9isKevZOaaIsAAtZy5fcjkQK9Nhmk1I2NXzY/hkPos8V0zb/ZX416LFy8gv7l/1k3a5w==", - "dependencies": { - "deepmerge": "^4.0.0", - "load-script": "^1.0.0", - "memoize-one": "^5.1.1", - "prop-types": "^15.7.2", - "react-fast-compare": "^3.0.1" - }, - "peerDependencies": { - "react": ">=16.6.0" - } - }, - "node_modules/react-player/node_modules/memoize-one": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", - "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" - }, - "node_modules/react-refresh": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.12.0.tgz", - "integrity": "sha512-suLIhrU2IHKL5JEKR/fAwJv7bbeq4kJ+pJopf77jHwuR+HmJS/HbrPIGsTBUVfw7tXPOmYv7UJ7PCaN49e8x4A==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/react-refresh-typescript": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/react-refresh-typescript/-/react-refresh-typescript-2.0.4.tgz", - "integrity": "sha512-ySsBExEFik5Jjf7NoXtFbzUk2rYWM4gF5gg+wRTNmp9p7B2uMpAAa339FHWqmB8EAr0e6mzzskAXxc0Jd04fBw==", - "dev": true, - "peerDependencies": { - "react-refresh": "0.10.x || 0.11.x || 0.12.x", - "typescript": "^4" - } - }, - "node_modules/react-remove-scroll": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", - "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", - "dependencies": { - "react-remove-scroll-bar": "^2.3.3", - "react-style-singleton": "^2.2.1", - "tslib": "^2.1.0", - "use-callback-ref": "^1.3.0", - "use-sidecar": "^1.1.2" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/react-remove-scroll-bar": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz", - "integrity": "sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==", - "dependencies": { - "react-style-singleton": "^2.2.1", - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/react-router": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.5.0.tgz", - "integrity": "sha512-fqqUSU0NC0tSX0sZbyuxzuAzvGqbjiZItBQnyicWlOUmzhAU8YuLgRbaCL2hf3sJdtRy4LP/WBrWtARkMvdGPQ==", - "dependencies": { - "@remix-run/router": "1.1.0" - }, - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "react": ">=16.8" - } - }, - "node_modules/react-router-dom": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.5.0.tgz", - "integrity": "sha512-/XzRc5fq80gW1ctiIGilyKFZC/j4kfe75uivMsTChFbkvrK4ZrF3P3cGIc1f/SSkQ4JiJozPrf+AwUHHWVehVg==", - "dependencies": { - "@remix-run/router": "1.1.0", - "react-router": "6.5.0" - }, - "engines": { - "node": ">=14" - }, - "peerDependencies": { - "react": ">=16.8", - "react-dom": ">=16.8" - } - }, - "node_modules/react-shallow-renderer": { - "version": "16.15.0", - "resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz", - "integrity": "sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA==", - "dev": true, - "dependencies": { - "object-assign": "^4.1.1", - "react-is": "^16.12.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependencies": { - "react": "^16.0.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/react-simple-img": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/react-simple-img/-/react-simple-img-3.0.0.tgz", - "integrity": "sha512-I0sG/GgY9c+04BgWf1YRlipWBQxR3oG2s/bagU8EO7zals3/Vkfk1PJMeYh/wHfjxJtUmal+y7HWEBm4MzXVsQ==", - "peerDependencies": { - "react": ">= 16.3.0", - "react-dom": ">= 16.3.0" - } - }, - "node_modules/react-style-singleton": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", - "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", - "dependencies": { - "get-nonce": "^1.0.0", - "invariant": "^2.2.4", - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/react-test-renderer": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-18.0.0.tgz", - "integrity": "sha512-SyZTP/FSkwfiKOZuTZiISzsrC8A80KNlQ8PyyoGoOq+VzMAab6Em1POK/CiX3+XyXG6oiJa1C53zYDbdrJu9fw==", - "dev": true, - "dependencies": { - "react-is": "^18.0.0", - "react-shallow-renderer": "^16.13.1", - "scheduler": "^0.21.0" - }, - "peerDependencies": { - "react": "^18.0.0" - } - }, - "node_modules/react-test-renderer/node_modules/react-is": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.0.0.tgz", - "integrity": "sha512-yUcBYdBBbo3QiPsgYDcfQcIkGZHfxOaoE6HLSnr1sPzMhdyxusbfKOSUbSd/ocGi32dxcj366PsTj+5oggeKKw==", - "dev": true - }, - "node_modules/react-textarea-autosize": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.4.tgz", - "integrity": "sha512-CdtmP8Dc19xL8/R6sWvtknD/eCXkQr30dtvC4VmGInhRsfF8X/ihXCq6+9l9qbxmKRiq407/7z5fxE7cVWQNgQ==", - "dependencies": { - "@babel/runtime": "^7.10.2", - "use-composed-ref": "^1.3.0", - "use-latest": "^1.2.1" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/react-transition-group": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", - "integrity": "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==", - "dependencies": { - "@babel/runtime": "^7.5.5", - "dom-helpers": "^5.0.1", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2" - }, - "peerDependencies": { - "react": ">=16.6.0", - "react-dom": ">=16.6.0" - } - }, - "node_modules/react-virtualized-auto-sizer": { - "version": "1.0.17", - "resolved": "https://registry.npmjs.org/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.17.tgz", - "integrity": "sha512-XtojyZHGo/iYmGkOEL8psTQsr5XI4fd+QxCD16ru00mnJhuvXFXcPLHXj5cKJh/xUttxPCglnpUI8d2u6gUgzw==", - "peerDependencies": { - "react": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc", - "react-dom": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc" - } - }, - "node_modules/react-window": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.9.tgz", - "integrity": "sha512-+Eqx/fj1Aa5WnhRfj9dJg4VYATGwIUP2ItwItiJ6zboKWA6EX3lYDAXfGF2hyNqplEprhbtjbipiADEcwQ823Q==", - "dependencies": { - "@babel/runtime": "^7.0.0", - "memoize-one": ">=3.1.1 <6" - }, - "engines": { - "node": ">8.0.0" - }, - "peerDependencies": { - "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/react-window-infinite-loader": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/react-window-infinite-loader/-/react-window-infinite-loader-1.0.9.tgz", - "integrity": "sha512-5Hg89IdU4Vrp0RT8kZYKeTIxWZYhNkVXeI1HbKo01Vm/Z7qztDvXljwx16sMzsa9yapRJQW3ODZfMUw38SOWHw==", - "engines": { - "node": ">8.0.0" - }, - "peerDependencies": { - "react": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0", - "react-dom": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/react-window/node_modules/memoize-one": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", - "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" - }, - "node_modules/read-config-file": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-6.3.2.tgz", - "integrity": "sha512-M80lpCjnE6Wt6zb98DoW8WHR09nzMSpu8XHtPkiTHrJ5Az9CybfeQhTJ8D7saeBHpGhLPIVyA8lcL6ZmdKwY6Q==", - "dev": true, - "dependencies": { - "config-file-ts": "^0.2.4", - "dotenv": "^9.0.2", - "dotenv-expand": "^5.1.0", - "js-yaml": "^4.1.0", - "json5": "^2.2.0", - "lazy-val": "^1.0.4" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "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, - "dependencies": { - "@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/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, - "dependencies": { - "find-up": "^4.1.0", - "read-pkg": "^5.2.0", - "type-fest": "^0.8.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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, - "dependencies": { - "locate-path": "^5.0.0", - "path-exists": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "dependencies": { - "p-locate": "^4.1.0" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "dependencies": { - "p-try": "^2.0.0" - }, - "engines": { - "node": ">=6" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "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, - "dependencies": { - "p-limit": "^2.2.0" - }, - "engines": { - "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==", - "dev": true, - "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, - "bin": { - "semver": "bin/semver" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/readable-stream": { - "version": "2.3.7", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", - "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", - "dev": 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/readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "dependencies": { - "picomatch": "^2.2.1" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/rechoir": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", - "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", - "dev": true, - "dependencies": { - "resolve": "^1.9.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "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/regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" - }, - "node_modules/regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - } - }, - "node_modules/relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/remark": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/remark/-/remark-10.0.1.tgz", - "integrity": "sha512-E6lMuoLIy2TyiokHprMjcWNJ5UxfGQjaMSMhV+f4idM625UjjK4j798+gPs5mfjzDE6vL0oFKVeZM6gZVSVrzQ==", - "dev": true, - "dependencies": { - "remark-parse": "^6.0.0", - "remark-stringify": "^6.0.0", - "unified": "^7.0.0" - } - }, - "node_modules/remark-parse": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-6.0.3.tgz", - "integrity": "sha512-QbDXWN4HfKTUC0hHa4teU463KclLAnwpn/FBn87j9cKYJWWawbiLgMfP2Q4XwhxxuuuOxHlw+pSN0OKuJwyVvg==", - "dev": true, - "dependencies": { - "collapse-white-space": "^1.0.2", - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "is-word-character": "^1.0.0", - "markdown-escapes": "^1.0.0", - "parse-entities": "^1.1.0", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "trim": "0.0.1", - "trim-trailing-lines": "^1.0.0", - "unherit": "^1.0.4", - "unist-util-remove-position": "^1.0.0", - "vfile-location": "^2.0.0", - "xtend": "^4.0.1" - } - }, - "node_modules/remark-stringify": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-6.0.4.tgz", - "integrity": "sha512-eRWGdEPMVudijE/psbIDNcnJLRVx3xhfuEsTDGgH4GsFF91dVhw5nhmnBppafJ7+NWINW6C7ZwWbi30ImJzqWg==", - "dev": true, - "dependencies": { - "ccount": "^1.0.0", - "is-alphanumeric": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "longest-streak": "^2.0.1", - "markdown-escapes": "^1.0.0", - "markdown-table": "^1.1.0", - "mdast-util-compact": "^1.0.0", - "parse-entities": "^1.0.2", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "stringify-entities": "^1.0.1", - "unherit": "^1.0.4", - "xtend": "^4.0.1" - } - }, - "node_modules/remove-accents": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz", - "integrity": "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA==" - }, - "node_modules/remove-bom-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", - "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5", - "is-utf8": "^0.2.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/remove-bom-stream": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", - "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", - "dev": true, - "dependencies": { - "remove-bom-buffer": "^3.0.0", - "safe-buffer": "^5.1.0", - "through2": "^2.0.3" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/remove-bom-stream/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "node_modules/renderkid": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", - "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", - "dev": true, - "dependencies": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - } - }, - "node_modules/repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/replace-ext": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", - "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true, - "engines": { - "node": ">=0.10.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==", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/requireindex": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", - "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", - "dev": true, - "engines": { - "node": ">=0.10.5" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "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==", - "dependencies": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - }, - "bin": { - "resolve": "bin/resolve" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "dev": 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, - "dependencies": { - "resolve-from": "^5.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "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==", - "engines": { - "node": ">=4" - } - }, - "node_modules/resolve-options": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", - "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", - "dev": true, - "dependencies": { - "value-or-function": "^3.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "deprecated": "https://github.com/lydell/resolve-url#deprecated", - "dev": true - }, - "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/responselike": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", - "dev": true, - "dependencies": { - "lowercase-keys": "^2.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "dependencies": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true, - "engines": { - "node": ">=0.12" - } - }, - "node_modules/retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true, - "engines": { - "iojs": ">=1.0.0", - "node": ">=0.10.0" - } - }, - "node_modules/rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", - "dev": true - }, - "node_modules/rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "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==", - "dev": true, - "optional": true, - "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" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/rsvp": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", - "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", - "dev": true, - "engines": { - "node": "6.* || >= 7.*" - } - }, - "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==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "dependencies": { - "queue-microtask": "^1.2.2" - } - }, - "node_modules/runtime-required": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/runtime-required/-/runtime-required-1.1.0.tgz", - "integrity": "sha512-yX97f5E0WfNpcQnfVjap6vzQcvErkYYCx6eTK4siqGEdC8lglwypUFgZVTX7ShvIlgfkC4XGFl9O1KTYcff0pw==", - "dev": true, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "dependencies": { - "tslib": "^1.9.0" - }, - "engines": { - "npm": ">=2.0.0" - } - }, - "node_modules/rxjs/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "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==" - }, - "node_modules/safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "dependencies": { - "ret": "~0.1.10" - } - }, - "node_modules/safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "node_modules/sanitize-filename": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", - "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", - "dev": true, - "dependencies": { - "truncate-utf8-bytes": "^1.0.0" - } - }, - "node_modules/sass": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.50.0.tgz", - "integrity": "sha512-cLsD6MEZ5URXHStxApajEh7gW189kkjn4Rc8DQweMyF+o5HF5nfEz8QYLMlPsTOD88DknatTmBWkOcw5/LnJLQ==", - "dev": true, - "dependencies": { - "chokidar": ">=3.0.0 <4.0.0", - "immutable": "^4.0.0", - "source-map-js": ">=0.6.2 <2.0.0" - }, - "bin": { - "sass": "sass.js" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/sass-loader": { - "version": "12.6.0", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz", - "integrity": "sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==", - "dev": true, - "dependencies": { - "klona": "^2.0.4", - "neo-async": "^2.6.2" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "fibers": ">= 3.1.0", - "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", - "sass": "^1.3.0", - "sass-embedded": "*", - "webpack": "^5.0.0" - }, - "peerDependenciesMeta": { - "fibers": { - "optional": true - }, - "node-sass": { - "optional": true - }, - "sass": { - "optional": true - }, - "sass-embedded": { - "optional": true - } - } - }, - "node_modules/sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "node_modules/saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "dependencies": { - "xmlchars": "^2.2.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/scheduler": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", - "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", - "dev": true, - "dependencies": { - "loose-envify": "^1.1.0" - } - }, - "node_modules/schema-utils": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz", - "integrity": "sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", - "dev": true - }, - "node_modules/selfsigned": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.0.1.tgz", - "integrity": "sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ==", - "dev": true, - "dependencies": { - "node-forge": "^1" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "dependencies": { - "lru-cache": "^6.0.0" - }, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "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==", - "dev": true, - "optional": true - }, - "node_modules/send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dev": true, - "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" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "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==", - "dev": true, - "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": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/send/node_modules/depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/send/node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "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==", - "dev": true - }, - "node_modules/send/node_modules/statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "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==", - "dev": true, - "optional": true, - "dependencies": { - "type-fest": "^0.13.1" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/serialize-error/node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", - "dev": true, - "dependencies": { - "randombytes": "^2.1.0" - } - }, - "node_modules/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", - "dev": true, - "dependencies": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/serve-index/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/serve-index/node_modules/http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "dependencies": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/serve-index/node_modules/inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "node_modules/serve-index/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "node_modules/serve-index/node_modules/setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": true - }, - "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==", - "dev": true, - "dependencies": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "node_modules/set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/set-value/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, - "node_modules/shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "dependencies": { - "kind-of": "^6.0.2" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/shallowequal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" - }, - "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==", - "dev": true, - "dependencies": { - "shebang-regex": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "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==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.0", - "get-intrinsic": "^1.0.2", - "object-inspect": "^1.9.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "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/simple-update-notifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", - "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", - "dev": true, - "dependencies": { - "semver": "~7.0.0" - }, - "engines": { - "node": ">=8.10.0" - } - }, - "node_modules/simple-update-notifier/node_modules/semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "dev": true, - "bin": { - "semver": "bin/semver.js" - } - }, - "node_modules/sirv": { - "version": "1.0.19", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.19.tgz", - "integrity": "sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==", - "dev": true, - "dependencies": { - "@polka/url": "^1.0.0-next.20", - "mrmime": "^1.0.0", - "totalist": "^1.0.0" - }, - "engines": { - "node": ">= 10" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/slice-ansi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">= 6.0.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "dependencies": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "dependencies": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-node/node_modules/define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "dependencies": { - "is-descriptor": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "dependencies": { - "kind-of": "^3.2.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon-util/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "dependencies": { - "ms": "2.0.0" - } - }, - "node_modules/snapdragon/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "node_modules/snapdragon/node_modules/source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/snapdragon/node_modules/source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "dev": true, - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "node_modules/sockjs": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", - "dev": true, - "dependencies": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "node_modules/socks": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz", - "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==", - "dev": true, - "dependencies": { - "ip": "^1.1.5", - "smart-buffer": "^4.2.0" - }, - "engines": { - "node": ">= 10.13.0", - "npm": ">= 3.0.0" - } - }, - "node_modules/sort-keys": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-5.0.0.tgz", - "integrity": "sha512-Pdz01AvCAottHTPQGzndktFNdbRA75BgOfeT1hH+AMnJFv8lynkPi42rfeEhpx1saTEI3YNMWxfqu0sFD1G8pw==", - "dev": true, - "dependencies": { - "is-plain-obj": "^4.0.0" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/sort-keys/node_modules/is-plain-obj": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", - "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true, - "engines": { - "node": ">= 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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-resolve": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", - "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", - "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", - "dev": true, - "dependencies": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0" - } - }, - "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==", - "dev": true, - "dependencies": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - }, - "node_modules/source-map-support/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "deprecated": "See https://github.com/lydell/source-map-url#deprecated", - "dev": true - }, - "node_modules/spawn-command": { - "version": "0.0.2-1", - "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", - "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=", - "dev": true - }, - "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, - "dependencies": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "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==", - "dev": true, - "dependencies": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "node_modules/spdx-license-ids": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", - "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", - "dev": true - }, - "node_modules/spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "dev": true, - "dependencies": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "dev": true, - "dependencies": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - } - }, - "node_modules/spdy-transport/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/specificity": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.4.1.tgz", - "integrity": "sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==", - "dev": true, - "bin": { - "specificity": "bin/specificity" - } - }, - "node_modules/split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "dependencies": { - "extend-shallow": "^3.0.0" - }, - "engines": { - "node": ">=0.10.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==", - "dev": true - }, - "node_modules/ssr-window": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/ssr-window/-/ssr-window-4.0.2.tgz", - "integrity": "sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ==" - }, - "node_modules/stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility", - "dev": 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==", - "dev": true, - "dependencies": { - "escape-string-regexp": "^2.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/stackframe": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", - "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", - "dev": true - }, - "node_modules/stat-mode": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz", - "integrity": "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/state-toggle": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", - "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "dependencies": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "dependencies": { - "is-descriptor": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "dependencies": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/static-extend/node_modules/kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "node_modules/streamx": { - "version": "2.13.2", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.13.2.tgz", - "integrity": "sha512-+TWqixPhGDXEG9L/XczSbhfkmwAtGs3BJX5QNU6cvno+pOLKeszByWcnaTu6dg8efsTYqR8ZZuXWHhZfgrxMvA==", - "dev": true, - "dependencies": { - "fast-fifo": "^1.1.0", - "queue-tick": "^1.0.1" - } - }, - "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==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, - "node_modules/string-argv": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", - "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", - "dev": true, - "engines": { - "node": ">=0.6.19" - } - }, - "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, - "dependencies": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "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, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/string-width/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 - }, - "node_modules/string.prototype.matchall": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", - "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.4.3", - "side-channel": "^1.0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", - "dev": true, - "dependencies": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/stringify-entities": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.2.tgz", - "integrity": "sha512-nrBAQClJAPN2p+uGCVJRPIPakKeKWZ9GtBCmormE7pWOSlHat7+x5A8gx85M7HM5Dt0BP3pP5RhVW77WdbJJ3A==", - "dev": true, - "dependencies": { - "character-entities-html4": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-hexadecimal": "^1.0.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==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "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==", - "dev": true, - "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==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "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, - "dependencies": { - "min-indent": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/style-loader": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz", - "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==", - "dev": true, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.0.0" - } - }, - "node_modules/style-search": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", - "integrity": "sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=", - "dev": true - }, - "node_modules/styled-components": { - "version": "5.3.11", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.11.tgz", - "integrity": "sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==", - "dependencies": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/traverse": "^7.4.5", - "@emotion/is-prop-valid": "^1.1.0", - "@emotion/stylis": "^0.8.4", - "@emotion/unitless": "^0.7.4", - "babel-plugin-styled-components": ">= 1.12.0", - "css-to-react-native": "^3.0.0", - "hoist-non-react-statics": "^3.0.0", - "shallowequal": "^1.1.0", - "supports-color": "^5.5.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/styled-components" - }, - "peerDependencies": { - "react": ">= 16.8.0", - "react-dom": ">= 16.8.0", - "react-is": ">= 16.8.0" - } - }, - "node_modules/styled-components/node_modules/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==", - "engines": { - "node": ">=4" - } - }, - "node_modules/styled-components/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylehacks": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.0.tgz", - "integrity": "sha512-SzLmvHQTrIWfSgljkQCw2++C9+Ne91d/6Sp92I8c5uHTcy/PgeHamwITIbBW9wnFTY/3ZfSXR9HIL6Ikqmcu6Q==", - "dev": true, - "dependencies": { - "browserslist": "^4.16.6", - "postcss-selector-parser": "^6.0.4" - }, - "engines": { - "node": "^10 || ^12 || >=14.0" - }, - "peerDependencies": { - "postcss": "^8.2.15" - } - }, - "node_modules/stylelint": { - "version": "14.9.1", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.9.1.tgz", - "integrity": "sha512-RdAkJdPiLqHawCSnu21nE27MjNXaVd4WcOHA4vK5GtIGjScfhNnaOuWR2wWdfKFAvcWQPOYe311iveiVKSmwsA==", - "dev": true, - "dependencies": { - "@csstools/selector-specificity": "^2.0.1", - "balanced-match": "^2.0.0", - "colord": "^2.9.2", - "cosmiconfig": "^7.0.1", - "css-functions-list": "^3.1.0", - "debug": "^4.3.4", - "execall": "^2.0.0", - "fast-glob": "^3.2.11", - "fastest-levenshtein": "^1.0.12", - "file-entry-cache": "^6.0.1", - "get-stdin": "^8.0.0", - "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.14", - "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.2.0", - "svg-tags": "^1.0.0", - "table": "^6.8.0", - "v8-compile-cache": "^2.3.0", - "write-file-atomic": "^4.0.1" - }, - "bin": { - "stylelint": "bin/stylelint.js" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/stylelint" - } - }, - "node_modules/stylelint-config-rational-order": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/stylelint-config-rational-order/-/stylelint-config-rational-order-0.1.2.tgz", - "integrity": "sha512-Qo7ZQaihCwTqijfZg4sbdQQHtugOX/B1/fYh018EiDZHW+lkqH9uHOnsDwDPGZrYJuB6CoyI7MZh2ecw2dOkew==", - "dev": true, - "dependencies": { - "stylelint": "^9.10.1", - "stylelint-order": "^2.2.1" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/@nodelib/fs.stat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", - "dev": true, - "engines": { - "node": ">= 6" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/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, - "dependencies": { - "color-convert": "^1.9.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "dependencies": { - "sprintf-js": "~1.0.2" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", - "dev": true, - "dependencies": { - "array-uniq": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "dependencies": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/braces/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/camelcase-keys": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", - "integrity": "sha512-Ej37YKYbFUI8QiYlvj9YHb6/Z60dZyPJW0Cs8sFilMbd2lP0bw3ylAq9yJkK4lcTA2dID5fG8LjmJYbO7kWb7Q==", - "dev": true, - "dependencies": { - "camelcase": "^4.1.0", - "map-obj": "^2.0.0", - "quick-lru": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/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, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/clone-regexp": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-1.0.1.tgz", - "integrity": "sha512-Fcij9IwRW27XedRIJnSOEupS7RVcXtObJXbcUOX93UCLqqOdRpkvzKywOOSizmEK/Is3S/RHX9dLdfo6R1Q1mw==", - "dev": true, - "dependencies": { - "is-regexp": "^1.0.0", - "is-supported-regexp-flag": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/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, - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/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 - }, - "node_modules/stylelint-config-rational-order/node_modules/cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dev": true, - "dependencies": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/dir-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", - "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", - "dev": true, - "dependencies": { - "path-type": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "node_modules/stylelint-config-rational-order/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, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/execall": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execall/-/execall-1.0.0.tgz", - "integrity": "sha512-/J0Q8CvOvlAdpvhfkD/WnTQ4H1eU0exze2nFGPj/RSC7jpQ0NkKe2r28T5eMkhEEs+fzepMZNy1kVRKNlC04nQ==", - "dev": true, - "dependencies": { - "clone-regexp": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/fast-glob": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", - "dev": true, - "dependencies": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/file-entry-cache": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-4.0.0.tgz", - "integrity": "sha512-AVSwsnbV8vH/UVbvgEhf3saVQXORNv0ZzSkvkhQIaia5Tia+JhGTaa/ePUSVoPHQyGayQNmYfkzFi3WZV5zcpA==", - "dev": true, - "dependencies": { - "flat-cache": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "dependencies": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/fill-range/node_modules/extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "dependencies": { - "is-extendable": "^0.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "dependencies": { - "locate-path": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "dependencies": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true - }, - "node_modules/stylelint-config-rational-order/node_modules/get-stdin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", - "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", - "dev": true, - "dependencies": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/glob-parent/node_modules/is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "dependencies": { - "is-extglob": "^2.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/globby": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", - "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", - "dev": true, - "dependencies": { - "@types/glob": "^7.1.1", - "array-union": "^1.0.2", - "dir-glob": "^2.2.2", - "fast-glob": "^2.2.6", - "glob": "^7.1.3", - "ignore": "^4.0.3", - "pify": "^4.0.1", - "slash": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/globby/node_modules/ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true, - "engines": { - "node": ">= 4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/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, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/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/stylelint-config-rational-order/node_modules/html-tags": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz", - "integrity": "sha512-+Il6N8cCo2wB/Vd3gqy/8TZhTD3QvcVeQLCnZiGkGCH3JP28IgGAY41giccp2W4R3jfyJPAP318FQTa1yU7K7g==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", - "dev": true, - "dependencies": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/import-fresh/node_modules/resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/import-lazy": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-3.1.0.tgz", - "integrity": "sha512-8/gvXvX2JMn0F+CDlSC4l6kOmVaLOO3XLkksI7CI3Ud95KDYJuYur2b9P/PUt/i/pDAMd/DulQsNbbbmRRsDIQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha512-BYqTHXTGUIvg7t1r4sJNKcbDZkL92nkXA8YtRpbjFHRHGDL/NtUeiBJMeE60kIFN/Mg8ESaWQvftaYMGJzQZCQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/is-number/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stylelint-config-rational-order/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==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/js-yaml": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", - "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", - "dev": true, - "dependencies": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - }, - "bin": { - "js-yaml": "bin/js-yaml.js" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/known-css-properties": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.11.0.tgz", - "integrity": "sha512-bEZlJzXo5V/ApNNa5z375mJC6Nrz4vG43UgcSCrg2OHC+yuB6j0iDSrY7RQ/+PRofFB03wNIIt9iXIVLr4wc7w==", - "dev": true - }, - "node_modules/stylelint-config-rational-order/node_modules/leven": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "dependencies": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "dependencies": { - "chalk": "^2.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/map-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", - "integrity": "sha512-TzQSV2DiMYgoF5RycneKVUzIa9bQsj/B3tTgsE3dOGqlzHnGIDaC7XBE7grnA+8kZPnfqSGFe95VHc2oc0VFUQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/meow": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz", - "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==", - "dev": true, - "dependencies": { - "camelcase-keys": "^4.0.0", - "decamelize-keys": "^1.0.0", - "loud-rejection": "^1.0.0", - "minimist-options": "^3.0.1", - "normalize-package-data": "^2.3.4", - "read-pkg-up": "^3.0.0", - "redent": "^2.0.0", - "trim-newlines": "^2.0.0", - "yargs-parser": "^10.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "dependencies": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/minimist-options": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", - "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", - "dev": true, - "dependencies": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0" - }, - "engines": { - "node": ">= 4" - } - }, - "node_modules/stylelint-config-rational-order/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, - "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/stylelint-config-rational-order/node_modules/p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "dependencies": { - "p-try": "^1.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "dependencies": { - "p-limit": "^1.1.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "dependencies": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "dependencies": { - "pify": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/path-type/node_modules/pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "node_modules/stylelint-config-rational-order/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/postcss-safe-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz", - "integrity": "sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g==", - "dev": true, - "dependencies": { - "postcss": "^7.0.26" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/postcss-scss": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.1.1.tgz", - "integrity": "sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA==", - "dev": true, - "dependencies": { - "postcss": "^7.0.6" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dev": true, - "dependencies": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/postcss-sorting": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-4.1.0.tgz", - "integrity": "sha512-r4T2oQd1giURJdHQ/RMb72dKZCuLOdWx2B/XhXN1Y1ZdnwXsKH896Qz6vD4tFy9xSjpKNYhlZoJmWyhH/7JUQw==", - "dev": true, - "dependencies": { - "lodash": "^4.17.4", - "postcss": "^7.0.0" - }, - "engines": { - "node": ">=6.14.3" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "node_modules/stylelint-config-rational-order/node_modules/quick-lru": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", - "integrity": "sha512-tRS7sTgyxMXtLum8L65daJnHUhfDUgboRdcWW2bR9vBfrj2+O5HSMbQOJfJJjIVSPFqbBCF37FpwWXGitDc5tA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "dependencies": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", - "dev": true, - "dependencies": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/redent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", - "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", - "dev": true, - "dependencies": { - "indent-string": "^3.0.0", - "strip-indent": "^2.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true, - "bin": { - "semver": "bin/semver" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/stylelint-config-rational-order/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "node_modules/stylelint-config-rational-order/node_modules/string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "dependencies": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "dependencies": { - "ansi-regex": "^4.1.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/stylelint": { - "version": "9.10.1", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-9.10.1.tgz", - "integrity": "sha512-9UiHxZhOAHEgeQ7oLGwrwoDR8vclBKlSX7r4fH0iuu0SfPwFaLkb1c7Q2j1cqg9P7IDXeAV2TvQML/fRQzGBBQ==", - "dev": true, - "dependencies": { - "autoprefixer": "^9.0.0", - "balanced-match": "^1.0.0", - "chalk": "^2.4.1", - "cosmiconfig": "^5.0.0", - "debug": "^4.0.0", - "execall": "^1.0.0", - "file-entry-cache": "^4.0.0", - "get-stdin": "^6.0.0", - "global-modules": "^2.0.0", - "globby": "^9.0.0", - "globjoin": "^0.1.4", - "html-tags": "^2.0.0", - "ignore": "^5.0.4", - "import-lazy": "^3.1.0", - "imurmurhash": "^0.1.4", - "known-css-properties": "^0.11.0", - "leven": "^2.1.0", - "lodash": "^4.17.4", - "log-symbols": "^2.0.0", - "mathml-tag-names": "^2.0.1", - "meow": "^5.0.0", - "micromatch": "^3.1.10", - "normalize-selector": "^0.2.0", - "pify": "^4.0.0", - "postcss": "^7.0.13", - "postcss-html": "^0.36.0", - "postcss-jsx": "^0.36.0", - "postcss-less": "^3.1.0", - "postcss-markdown": "^0.36.0", - "postcss-media-query-parser": "^0.2.3", - "postcss-reporter": "^6.0.0", - "postcss-resolve-nested-selector": "^0.1.1", - "postcss-safe-parser": "^4.0.0", - "postcss-sass": "^0.3.5", - "postcss-scss": "^2.0.0", - "postcss-selector-parser": "^3.1.0", - "postcss-syntax": "^0.36.2", - "postcss-value-parser": "^3.3.0", - "resolve-from": "^4.0.0", - "signal-exit": "^3.0.2", - "slash": "^2.0.0", - "specificity": "^0.4.1", - "string-width": "^3.0.0", - "style-search": "^0.1.0", - "sugarss": "^2.0.0", - "svg-tags": "^1.0.0", - "table": "^5.0.0" - }, - "bin": { - "stylelint": "bin/stylelint.js" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/stylelint-order": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-2.2.1.tgz", - "integrity": "sha512-019KBV9j8qp1MfBjJuotse6MgaZqGVtXMc91GU9MsS9Feb+jYUvUU3Z8XiClqPdqJZQ0ryXQJGg3U3PcEjXwfg==", - "dev": true, - "dependencies": { - "lodash": "^4.17.10", - "postcss": "^7.0.2", - "postcss-sorting": "^4.1.0" - }, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "stylelint": "^9.10.1 || ^10.0.0" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/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, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "dependencies": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - }, - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "dependencies": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/trim-newlines": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", - "integrity": "sha512-MTBWv3jhVjTU7XR3IQHllbiJs8sc75a80OEhB6or/q7pLTWgQ0bMGQXXYQSrSuXe6WiKWDZ5txXY5P59a/coVA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/stylelint-config-rational-order/node_modules/yargs-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", - "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", - "dev": true, - "dependencies": { - "camelcase": "^4.1.0" - } - }, - "node_modules/stylelint-config-recommended": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-7.0.0.tgz", - "integrity": "sha512-yGn84Bf/q41J4luis1AZ95gj0EQwRX8lWmGmBwkwBNSkpGSpl66XcPTulxGa/Z91aPoNGuIGBmFkcM1MejMo9Q==", - "dev": true, - "peerDependencies": { - "stylelint": "^14.4.0" - } - }, - "node_modules/stylelint-config-recommended-scss": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-6.0.0.tgz", - "integrity": "sha512-6QOe2/OzXV2AP5FE12A7+qtKdZik7Saf42SMMl84ksVBBPpTdrV+9HaCbPYiRMiwELY9hXCVdH4wlJ+YJb5eig==", - "dev": true, - "dependencies": { - "postcss-scss": "^4.0.2", - "stylelint-config-recommended": "^7.0.0", - "stylelint-scss": "^4.0.0" - }, - "peerDependencies": { - "stylelint": "^14.4.0" - } - }, - "node_modules/stylelint-config-standard": { - "version": "25.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-25.0.0.tgz", - "integrity": "sha512-21HnP3VSpaT1wFjFvv9VjvOGDtAviv47uTp3uFmzcN+3Lt+RYRv6oAplLaV51Kf792JSxJ6svCJh/G18E9VnCA==", - "dev": true, - "dependencies": { - "stylelint-config-recommended": "^7.0.0" - }, - "peerDependencies": { - "stylelint": "^14.4.0" - } - }, - "node_modules/stylelint-config-standard-scss": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-standard-scss/-/stylelint-config-standard-scss-4.0.0.tgz", - "integrity": "sha512-xizu8PTEyB6zYXBiVg6VtvUYn9m57x+6ZtaOdaxsfpbe5eagLPGNlbYnKfm/CfN69ArUpnwR6LjgsTHzlGbtXQ==", - "dev": true, - "dependencies": { - "stylelint-config-recommended-scss": "^6.0.0", - "stylelint-config-standard": "^25.0.0" - }, - "peerDependencies": { - "stylelint": "^14.4.0" - } - }, - "node_modules/stylelint-config-styled-components": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/stylelint-config-styled-components/-/stylelint-config-styled-components-0.1.1.tgz", - "integrity": "sha512-z5Xz/9GmvxO6e/DLzBMwkB85zHxEEjN6K7Cj80Bi+o/9vR9eS3GX3E9VuMnX9WLFYulqbqLtTapGGY28JBiy9Q==", - "dev": true - }, - "node_modules/stylelint-order": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-5.0.0.tgz", - "integrity": "sha512-OWQ7pmicXufDw5BlRqzdz3fkGKJPgLyDwD1rFY3AIEfIH/LQY38Vu/85v8/up0I+VPiuGRwbc2Hg3zLAsJaiyw==", - "dev": true, - "dependencies": { - "postcss": "^8.3.11", - "postcss-sorting": "^7.0.1" - }, - "peerDependencies": { - "stylelint": "^14.0.0" - } - }, - "node_modules/stylelint-processor-styled-components": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/stylelint-processor-styled-components/-/stylelint-processor-styled-components-1.10.0.tgz", - "integrity": "sha512-g4HpN9rm0JD0LoHuIOcd/FIjTZCJ0ErQ+dC3VTxp+dSvnkV+MklKCCmCQEdz5K5WxF4vPuzfVgdbSDuPYGZhoA==", - "dev": true, - "dependencies": { - "@babel/parser": "^7.8.3", - "@babel/traverse": "^7.8.3", - "micromatch": "^4.0.2", - "postcss": "^7.0.26" - } - }, - "node_modules/stylelint-processor-styled-components/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "node_modules/stylelint-processor-styled-components/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/stylelint-processor-styled-components/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, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/stylelint-scss": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-4.3.0.tgz", - "integrity": "sha512-GvSaKCA3tipzZHoz+nNO7S02ZqOsdBzMiCx9poSmLlb3tdJlGddEX/8QzCOD8O7GQan9bjsvLMsO5xiw6IhhIQ==", - "dev": true, - "dependencies": { - "lodash": "^4.17.21", - "postcss-media-query-parser": "^0.2.3", - "postcss-resolve-nested-selector": "^0.1.1", - "postcss-selector-parser": "^6.0.6", - "postcss-value-parser": "^4.1.0" - }, - "peerDependencies": { - "stylelint": "^14.5.1" - } - }, - "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/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/stylelint/node_modules/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, - "engines": { - "node": ">=0.10.0" - } - }, - "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, - "engines": { - "node": ">=8" - } - }, - "node_modules/stylelint/node_modules/write-file-atomic": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz", - "integrity": "sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - }, - "engines": { - "node": "^12.13.0 || ^14.15.0 || >=16" - } - }, - "node_modules/stylis": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz", - "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==" - }, - "node_modules/sugarss": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-2.0.0.tgz", - "integrity": "sha512-WfxjozUk0UVA4jm+U1d736AUpzSrNsQcIbyOkoE364GrtWmIrFdk5lksEupgWMD4VaT/0kVx1dobpiDumSgmJQ==", - "dev": true, - "dependencies": { - "postcss": "^7.0.2" - } - }, - "node_modules/sugarss/node_modules/picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "node_modules/sugarss/node_modules/postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "dependencies": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - }, - "engines": { - "node": ">=6.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/postcss/" - } - }, - "node_modules/sugarss/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, - "engines": { - "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==", - "dev": true, - "dependencies": { - "debug": "^4.1.0" - }, - "engines": { - "node": ">= 8.0" - } - }, - "node_modules/superjson": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/superjson/-/superjson-1.11.0.tgz", - "integrity": "sha512-6PfAg1FKhqkwWvPb2uXhH4MkMttdc17eJ91+Aoz4s1XUEDZFmLfFx/xVA3wgkPxAGy5dpozgGdK6V/n20Wj9yg==", - "dependencies": { - "copy-anything": "^3.0.2" - }, - "engines": { - "node": ">=10" - } - }, - "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==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", - "dev": true, - "dependencies": { - "has-flag": "^4.0.0", - "supports-color": "^7.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==", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/svg-tags": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", - "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", - "dev": true - }, - "node_modules/svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", - "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", - "dev": true, - "dependencies": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^4.1.3", - "css-tree": "^1.1.3", - "csso": "^4.2.0", - "picocolors": "^1.0.0", - "stable": "^0.1.8" - }, - "bin": { - "svgo": "bin/svgo" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/svgo/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/swiper": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/swiper/-/swiper-9.3.1.tgz", - "integrity": "sha512-YBDf0DLBLO7O4rwYHfz+HltkY4sDwKSbRf1it56rngpkYHxiKg0NkPMXAFmw2nGvMNQJwV14Dse47hQIifJzzA==", - "funding": [ - { - "type": "patreon", - "url": "https://www.patreon.com/swiperjs" - }, - { - "type": "open_collective", - "url": "http://opencollective.com/swiper" - } - ], - "dependencies": { - "ssr-window": "^4.0.2" - }, - "engines": { - "node": ">= 4.7.0" - } - }, - "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/symlink-or-copy": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/symlink-or-copy/-/symlink-or-copy-1.3.1.tgz", - "integrity": "sha512-0K91MEXFpBUaywiwSSkmKjnGcasG/rVBXFLJz5DrgGabpYD6N+3yZrfD6uUIfpuTu65DZLHi7N8CizHc07BPZA==", - "dev": true - }, - "node_modules/tabbable": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.1.1.tgz", - "integrity": "sha512-4kl5w+nCB44EVRdO0g/UGoOp3vlwgycUVtkk/7DPyeLZUCuNFFKCFG6/t/DgHLrUPHjrZg6s5tNm+56Q2B0xyg==" - }, - "node_modules/table": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", - "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" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "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, - "dependencies": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "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/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, - "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/tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/tar": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz", - "integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==", - "dev": true, - "dependencies": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^4.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/tar/node_modules/minipass": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.5.tgz", - "integrity": "sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/tar/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true, - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/teex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", - "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", - "dev": true, - "dependencies": { - "streamx": "^2.12.5" - } - }, - "node_modules/temp-file": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz", - "integrity": "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==", - "dev": true, - "dependencies": { - "async-exit-hook": "^2.0.1", - "fs-extra": "^10.0.0" - } - }, - "node_modules/temp-file/node_modules/fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/temp-file/node_modules/jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "dependencies": { - "universalify": "^2.0.0" - }, - "optionalDependencies": { - "graceful-fs": "^4.1.6" - } - }, - "node_modules/temp-file/node_modules/universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true, - "engines": { - "node": ">= 10.0.0" - } - }, - "node_modules/terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "dependencies": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/terser": { - "version": "5.17.7", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.7.tgz", - "integrity": "sha512-/bi0Zm2C6VAexlGgLlVxA0P2lru/sdLyfCVaRMfKVo9nWxbmz7f/sD8VPybPeSUJaJcwmCJis9pBIhcVcG1QcQ==", - "dev": true, - "dependencies": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "bin": { - "terser": "bin/terser" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/terser-webpack-plugin": { - "version": "5.3.9", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", - "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", - "dev": true, - "dependencies": { - "@jridgewell/trace-mapping": "^0.3.17", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.16.8" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^5.1.0" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "esbuild": { - "optional": true - }, - "uglify-js": { - "optional": true - } - } - }, - "node_modules/terser/node_modules/commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "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==", - "dev": true, - "dependencies": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "node_modules/throat": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", - "dev": true - }, - "node_modules/through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "node_modules/through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dev": true, - "dependencies": { - "readable-stream": "3" - } - }, - "node_modules/through2-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", - "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", - "dev": true, - "dependencies": { - "through2": "~2.0.0", - "xtend": "~4.0.0" - } - }, - "node_modules/through2-filter/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/through2/node_modules/readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, - "node_modules/thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", - "dev": true - }, - "node_modules/tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "dependencies": { - "rimraf": "^3.0.0" - }, - "engines": { - "node": ">=8.17.0" - } - }, - "node_modules/tmp-promise": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", - "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", - "dev": true, - "dependencies": { - "tmp": "^0.2.0" - } - }, - "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-absolute-glob": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", - "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", - "dev": true, - "dependencies": { - "is-absolute": "^1.0.0", - "is-negated-glob": "^1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "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": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", - "engines": { - "node": ">=4" - } - }, - "node_modules/to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "dependencies": { - "kind-of": "^3.0.2" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-object-path/node_modules/kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "dependencies": { - "is-buffer": "^1.1.5" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "dependencies": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "dependencies": { - "is-number": "^7.0.0" - }, - "engines": { - "node": ">=8.0" - } - }, - "node_modules/to-through": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", - "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", - "dev": true, - "dependencies": { - "through2": "^2.0.3" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/to-through/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/totalist": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", - "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", - "dev": true, - "dependencies": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.1.2" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "dependencies": { - "punycode": "^2.1.1" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", - "dev": true, - "bin": { - "tree-kill": "cli.js" - } - }, - "node_modules/trim": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ==", - "deprecated": "Use String.prototype.trim() instead", - "dev": true - }, - "node_modules/trim-newlines": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", - "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", - "dev": true, - "engines": { - "node": ">=8" - } - }, - "node_modules/trim-trailing-lines": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz", - "integrity": "sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/trough": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", - "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", - "dev": true, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/truncate-utf8-bytes": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", - "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", - "dev": true, - "dependencies": { - "utf8-byte-length": "^1.0.1" - } - }, - "node_modules/ts-jest": { - "version": "27.1.4", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.4.tgz", - "integrity": "sha512-qjkZlVPWVctAezwsOD1OPzbZ+k7zA5z3oxII4dGdZo5ggX/PL7kvwTM0pXTr10fAtbiVpJaL3bWd502zAhpgSQ==", - "dev": true, - "dependencies": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^27.0.0", - "json5": "2.x", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "20.x" - }, - "bin": { - "ts-jest": "cli.js" - }, - "engines": { - "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" - }, - "peerDependencies": { - "@babel/core": ">=7.0.0-beta.0 <8", - "@types/jest": "^27.0.0", - "babel-jest": ">=27.0.0 <28", - "jest": "^27.0.0", - "typescript": ">=3.8 <5.0" - }, - "peerDependenciesMeta": { - "@babel/core": { - "optional": true - }, - "@types/jest": { - "optional": true - }, - "babel-jest": { - "optional": true - }, - "esbuild": { - "optional": true - } - } - }, - "node_modules/ts-loader": { - "version": "9.2.8", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.2.8.tgz", - "integrity": "sha512-gxSak7IHUuRtwKf3FIPSW1VpZcqF9+MBrHOvBp9cjHh+525SjtCIJKVGjRKIAfxBwDGDGCFF00rTfzB1quxdSw==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4" - }, - "engines": { - "node": ">=12.0.0" - }, - "peerDependencies": { - "typescript": "*", - "webpack": "^5.0.0" - } - }, - "node_modules/ts-loader/node_modules/enhanced-resolve": { - "version": "5.9.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.2.tgz", - "integrity": "sha512-GIm3fQfwLJ8YZx2smuHpBKkXC1yOk+OBEmKckVyL0i/ea8mqDEykK3ld5dgH1QYPNyT/lIllxV2LULnxCHaHkA==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/ts-node": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", - "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "0.7.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.0", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/ts-node/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/tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", - "dev": true, - "dependencies": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - }, - "node_modules/tsconfig-paths-webpack-plugin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.0.0.tgz", - "integrity": "sha512-fw/7265mIWukrSHd0i+wSwx64kYUSAKPfxRDksjKIYTxSAp9W9/xcZVBF4Kl0eqQd5eBpAQ/oQrc5RyM/0c1GQ==", - "dev": true, - "dependencies": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.7.0", - "tsconfig-paths": "^4.0.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/tsconfig-paths-webpack-plugin/node_modules/enhanced-resolve": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", - "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/tsconfig-paths-webpack-plugin/node_modules/strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/tsconfig-paths-webpack-plugin/node_modules/tsconfig-paths": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.1.0.tgz", - "integrity": "sha512-AHx4Euop/dXFC+Vx589alFba8QItjF+8hf8LtmuiCwHyI4rHXQtOOENaM8kvYf5fR0dRChy3wzWIZ9WbB7FWow==", - "dev": true, - "dependencies": { - "json5": "^2.2.1", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - }, - "engines": { - "node": ">=6" - } - }, - "node_modules/tsconfig-paths/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "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": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true, - "engines": { - "node": ">=4" - } - }, - "node_modules/tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" - }, - "node_modules/tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "dependencies": { - "tslib": "^1.8.1" - }, - "engines": { - "node": ">= 6" - }, - "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" - } - }, - "node_modules/tsutils/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - }, - "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==", - "dev": true, - "dependencies": { - "prelude-ls": "^1.2.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, - "engines": { - "node": ">=4" - } - }, - "node_modules/type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "dependencies": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - }, - "engines": { - "node": ">= 0.6" - } - }, - "node_modules/typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "node_modules/typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "dependencies": { - "is-typedarray": "^1.0.0" - } - }, - "node_modules/typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/typescript-plugin-styled-components": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/typescript-plugin-styled-components/-/typescript-plugin-styled-components-2.0.0.tgz", - "integrity": "sha512-Wu7F96dwuphgiACHfu63vTbRRg6tkPwLnpFJwdxM70Y0PLfeKLRnvs2Yo5MAySMwE120ODMKk9W4TtJgY1ZumA==", - "dev": true, - "peerDependencies": { - "typescript": "^4.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==", - "dev": true, - "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/unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/underscore.string": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz", - "integrity": "sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ==", - "dev": true, - "dependencies": { - "sprintf-js": "^1.1.1", - "util-deprecate": "^1.0.2" - }, - "engines": { - "node": "*" - } - }, - "node_modules/unherit": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", - "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", - "dev": true, - "dependencies": { - "inherits": "^2.0.0", - "xtend": "^4.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, - "node_modules/unified": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/unified/-/unified-7.1.0.tgz", - "integrity": "sha512-lbk82UOIGuCEsZhPj8rNAkXSDXd6p0QLzIuSsCdxrqnqU56St4eyOB+AlXsVgVeRmetPTYydIuvFfpDIed8mqw==", - "dev": true, - "dependencies": { - "@types/unist": "^2.0.0", - "@types/vfile": "^3.0.0", - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^1.1.0", - "trough": "^1.0.0", - "vfile": "^3.0.0", - "x-is-string": "^0.1.0" - } - }, - "node_modules/unified/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==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "dependencies": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/union-value/node_modules/is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", - "dev": true - }, - "node_modules/unique-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", - "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", - "dev": true, - "dependencies": { - "json-stable-stringify-without-jsonify": "^1.0.1", - "through2-filter": "^3.0.0" - } - }, - "node_modules/unist-util-find-all-after": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-1.0.5.tgz", - "integrity": "sha512-lWgIc3rrTMTlK1Y0hEuL+k+ApzFk78h+lsaa2gHf63Gp5Ww+mt11huDniuaoq1H+XMK2lIIjjPkncxXcDp3QDw==", - "dev": true, - "dependencies": { - "unist-util-is": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-is": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", - "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==", - "dev": true - }, - "node_modules/unist-util-remove-position": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz", - "integrity": "sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==", - "dev": true, - "dependencies": { - "unist-util-visit": "^1.1.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/unist-util-stringify-position": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", - "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==", - "dev": true - }, - "node_modules/unist-util-visit": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", - "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", - "dev": true, - "dependencies": { - "unist-util-visit-parents": "^2.0.0" - } - }, - "node_modules/unist-util-visit-parents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", - "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", - "dev": true, - "dependencies": { - "unist-util-is": "^3.0.0" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">= 4.0.0" - } - }, - "node_modules/unixify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unixify/-/unixify-1.0.0.tgz", - "integrity": "sha1-OmQcjC/7zk2mg6XHDwOkYpQMIJA=", - "dev": true, - "dependencies": { - "normalize-path": "^2.1.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unixify/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "dependencies": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", - "dev": true, - "dependencies": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", - "dev": true, - "dependencies": { - "isarray": "1.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unset-value/node_modules/has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/unzip-crx-3": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/unzip-crx-3/-/unzip-crx-3-0.2.0.tgz", - "integrity": "sha512-0+JiUq/z7faJ6oifVB5nSwt589v1KCduqIJupNVDoWSXZtWDmjDGO3RAEOvwJ07w90aoXoP4enKsR7ecMrJtWQ==", - "dev": true, - "dependencies": { - "jszip": "^3.1.0", - "mkdirp": "^0.5.1", - "yaku": "^0.16.6" - } - }, - "node_modules/update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", - "funding": [ - { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - }, - { - "type": "tidelift", - "url": "https://tidelift.com/funding/github/npm/browserslist" - } - ], - "dependencies": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - }, - "bin": { - "browserslist-lint": "cli.js" - }, - "peerDependencies": { - "browserslist": ">= 4.21.0" - } - }, - "node_modules/uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "dependencies": { - "punycode": "^2.1.0" - } - }, - "node_modules/urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "deprecated": "Please see https://github.com/lydell/urix#deprecated", - "dev": true - }, - "node_modules/url-loader": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", - "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", - "dev": true, - "dependencies": { - "loader-utils": "^2.0.0", - "mime-types": "^2.1.27", - "schema-utils": "^3.0.0" - }, - "engines": { - "node": ">= 10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "file-loader": "*", - "webpack": "^4.0.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "file-loader": { - "optional": true - } - } - }, - "node_modules/use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/use-callback-ref": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.0.tgz", - "integrity": "sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==", - "dependencies": { - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/use-composed-ref": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.3.0.tgz", - "integrity": "sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/use-isomorphic-layout-effect": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", - "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/use-latest": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.2.1.tgz", - "integrity": "sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==", - "dependencies": { - "use-isomorphic-layout-effect": "^1.1.1" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/use-sidecar": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", - "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", - "dependencies": { - "detect-node-es": "^1.1.0", - "tslib": "^2.0.0" - }, - "engines": { - "node": ">=10" - }, - "peerDependencies": { - "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/use-sync-external-store": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", - "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/utf8-byte-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", - "integrity": "sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==", - "dev": true - }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "node_modules/utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", - "dev": true - }, - "node_modules/utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true, - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true, - "bin": { - "uuid": "dist/bin/uuid" - } - }, - "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-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, - "node_modules/v8-to-istanbul": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", - "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", - "dev": true, - "dependencies": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - }, - "engines": { - "node": ">=10.12.0" - } - }, - "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, - "dependencies": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "node_modules/value-or-function": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", - "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/verror": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", - "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", - "dev": true, - "optional": true, - "dependencies": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - }, - "engines": { - "node": ">=0.6.0" - } - }, - "node_modules/verror/node_modules/core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true, - "optional": true - }, - "node_modules/vfile": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-3.0.1.tgz", - "integrity": "sha512-y7Y3gH9BsUSdD4KzHsuMaCzRjglXN0W2EcMf0gpvu6+SbsGhMje7xDc8AEoeXy6mIwCKMI6BkjMsRjzQbhMEjQ==", - "dev": true, - "dependencies": { - "is-buffer": "^2.0.0", - "replace-ext": "1.0.0", - "unist-util-stringify-position": "^1.0.0", - "vfile-message": "^1.0.0" - } - }, - "node_modules/vfile-location": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.6.tgz", - "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-message": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.2.tgz", - "integrity": "sha512-QjSNP6Yxzyycd4SVOtmKKyTsSvClqBPJcd00Z0zuPj3hOIjg0rUPG6DbFGPvUKRgYyaIWLPKpuEclcuvb3H8qA==", - "dev": true, - "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^3.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile-message/node_modules/unist-util-stringify-position": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.2.tgz", - "integrity": "sha512-7A6eiDCs9UtjcwZOcCpM4aPII3bAAGv13E96IkawkOAW0OhH+yRxtY0lzo8KiHpzEMfH7Q+FizUmwp8Iqy5EWg==", - "dev": true, - "dependencies": { - "@types/unist": "^2.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/vfile/node_modules/is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "dev": true, - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "engines": { - "node": ">=4" - } - }, - "node_modules/vfile/node_modules/replace-ext": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/vfile/node_modules/vfile-message": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz", - "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==", - "dev": true, - "dependencies": { - "unist-util-stringify-position": "^1.1.1" - } - }, - "node_modules/vinyl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", - "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", - "dev": true, - "dependencies": { - "clone": "^2.1.1", - "clone-buffer": "^1.0.0", - "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/vinyl-fs": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", - "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", - "dev": true, - "dependencies": { - "fs-mkdirp-stream": "^1.0.0", - "glob-stream": "^6.1.0", - "graceful-fs": "^4.0.0", - "is-valid-glob": "^1.0.0", - "lazystream": "^1.0.0", - "lead": "^1.0.0", - "object.assign": "^4.0.4", - "pumpify": "^1.3.5", - "readable-stream": "^2.3.3", - "remove-bom-buffer": "^3.0.0", - "remove-bom-stream": "^1.2.0", - "resolve-options": "^1.1.0", - "through2": "^2.0.0", - "to-through": "^2.0.0", - "value-or-function": "^3.0.0", - "vinyl": "^2.0.0", - "vinyl-sourcemap": "^1.1.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/vinyl-fs/node_modules/through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "dependencies": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "node_modules/vinyl-sourcemap": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", - "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", - "dev": true, - "dependencies": { - "append-buffer": "^1.0.2", - "convert-source-map": "^1.5.0", - "graceful-fs": "^4.1.6", - "normalize-path": "^2.1.1", - "now-and-later": "^2.0.0", - "remove-bom-buffer": "^3.0.0", - "vinyl": "^2.0.0" - }, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/vinyl-sourcemap/node_modules/normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "dependencies": { - "remove-trailing-separator": "^1.0.1" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/vinyl/node_modules/clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", - "dev": true, - "engines": { - "node": ">=0.8" - } - }, - "node_modules/void-elements": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", - "integrity": "sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=", - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/vue-template-compiler": { - "version": "2.6.14", - "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.14.tgz", - "integrity": "sha512-ODQS1SyMbjKoO1JBJZojSw6FE4qnh9rIpUZn2EUT86FKizx9uH5z6uXiIrm4/Nb/gwxTi/o17ZDEGWAXHvtC7g==", - "dev": true, - "dependencies": { - "de-indent": "^1.0.2", - "he": "^1.1.0" - } - }, - "node_modules/w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.", - "dev": true, - "dependencies": { - "browser-process-hrtime": "^1.0.0" - } - }, - "node_modules/w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "dependencies": { - "xml-name-validator": "^3.0.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/walk-sync": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/walk-sync/-/walk-sync-2.2.0.tgz", - "integrity": "sha512-IC8sL7aB4/ZgFcGI2T1LczZeFWZ06b3zoHH7jBPyHxOtIIz1jppWHjjEXkOFvFojBVAK9pV7g47xOZ4LW3QLfg==", - "dev": true, - "dependencies": { - "@types/minimatch": "^3.0.3", - "ensure-posix-path": "^1.1.0", - "matcher-collection": "^2.0.0", - "minimatch": "^3.0.4" - }, - "engines": { - "node": "8.* || >= 10.*" - } - }, - "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, - "dependencies": { - "makeerror": "1.0.12" - } - }, - "node_modules/watchboy": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/watchboy/-/watchboy-0.4.3.tgz", - "integrity": "sha512-GHs1HxwvxSMBsqd/WfTOZhj5gBdMqf5HQpfgtKxDfZRxrlYPDdVLRB61LCeRzJaWANmvSIMlfmRVDwVmJFgAKA==", - "dev": true, - "dependencies": { - "lodash.difference": "^4.5.0", - "micromatch": "^4.0.2", - "pify": "^4.0.1", - "unixify": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/watchboy/node_modules/pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "node_modules/watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", - "dev": true, - "dependencies": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dev": true, - "dependencies": { - "minimalistic-assert": "^1.0.0" - } - }, - "node_modules/wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", - "dev": true, - "dependencies": { - "defaults": "^1.0.3" - } - }, - "node_modules/webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true, - "engines": { - "node": ">=10.4" - } - }, - "node_modules/webpack": { - "version": "5.85.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.85.0.tgz", - "integrity": "sha512-7gazTiYqwo5OSqwH1tigLDL2r3qDeP2dOKYgd+LlXpsUMqDTklg6tOghexqky0/+6QY38kb/R/uRPUleuL43zg==", - "dev": true, - "dependencies": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.0", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.14.1", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.2", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.7", - "watchpack": "^2.4.0", - "webpack-sources": "^3.2.3" - }, - "bin": { - "webpack": "bin/webpack.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-bundle-analyzer": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.5.0.tgz", - "integrity": "sha512-GUMZlM3SKwS8Z+CKeIFx7CVoHn3dXFcUAjT/dcZQQmfSZGvitPfMob2ipjai7ovFFqPvTqkEZ/leL4O0YOdAYQ==", - "dev": true, - "dependencies": { - "acorn": "^8.0.4", - "acorn-walk": "^8.0.0", - "chalk": "^4.1.0", - "commander": "^7.2.0", - "gzip-size": "^6.0.0", - "lodash": "^4.17.20", - "opener": "^1.5.2", - "sirv": "^1.0.7", - "ws": "^7.3.1" - }, - "bin": { - "webpack-bundle-analyzer": "lib/bin/analyzer.js" - }, - "engines": { - "node": ">= 10.13.0" - } - }, - "node_modules/webpack-bundle-analyzer/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/webpack-bundle-analyzer/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/webpack-cli": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.9.2.tgz", - "integrity": "sha512-m3/AACnBBzK/kMTcxWHcZFPrw/eQuY4Df1TxvIWfWM2x7mRqBQCqKEd96oCUa9jkapLBaFfRce33eGDb4Pr7YQ==", - "dev": true, - "dependencies": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.1.1", - "@webpack-cli/info": "^1.4.1", - "@webpack-cli/serve": "^1.6.1", - "colorette": "^2.0.14", - "commander": "^7.0.0", - "execa": "^5.0.0", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", - "webpack-merge": "^5.7.3" - }, - "bin": { - "webpack-cli": "bin/cli.js" - }, - "engines": { - "node": ">=10.13.0" - }, - "peerDependencies": { - "webpack": "4.x.x || 5.x.x" - }, - "peerDependenciesMeta": { - "@webpack-cli/generators": { - "optional": true - }, - "@webpack-cli/migrate": { - "optional": true - }, - "webpack-bundle-analyzer": { - "optional": true - }, - "webpack-dev-server": { - "optional": true - } - } - }, - "node_modules/webpack-cli/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, - "node_modules/webpack-cli/node_modules/interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", - "dev": true, - "engines": { - "node": ">= 0.10" - } - }, - "node_modules/webpack-dev-middleware": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz", - "integrity": "sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg==", - "dev": true, - "dependencies": { - "colorette": "^2.0.10", - "memfs": "^3.4.1", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - }, - "peerDependencies": { - "webpack": "^4.0.0 || ^5.0.0" - } - }, - "node_modules/webpack-dev-middleware/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": 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" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/webpack-dev-middleware/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/webpack-dev-middleware/node_modules/schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/webpack-dev-server": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.8.1.tgz", - "integrity": "sha512-dwld70gkgNJa33czmcj/PlKY/nOy/BimbrgZRaR9vDATBQAYgLzggR0nxDtPLJiLrMgZwbE6RRfJ5vnBBasTyg==", - "dev": true, - "dependencies": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.1", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^1.6.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "portfinder": "^1.0.28", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.0.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.21", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.1", - "ws": "^8.4.2" - }, - "bin": { - "webpack-dev-server": "bin/webpack-dev-server.js" - }, - "engines": { - "node": ">= 12.13.0" - }, - "peerDependencies": { - "webpack": "^4.37.0 || ^5.0.0" - }, - "peerDependenciesMeta": { - "webpack-cli": { - "optional": true - } - } - }, - "node_modules/webpack-dev-server/node_modules/ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "dev": 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" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/webpack-dev-server/node_modules/ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3" - }, - "peerDependencies": { - "ajv": "^8.8.2" - } - }, - "node_modules/webpack-dev-server/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/webpack-dev-server/node_modules/schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "dev": true, - "dependencies": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - }, - "engines": { - "node": ">= 12.13.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/webpack" - } - }, - "node_modules/webpack-dev-server/node_modules/ws": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", - "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": "^5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/webpack-merge": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", - "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", - "dev": true, - "dependencies": { - "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" - }, - "engines": { - "node": ">=10.0.0" - } - }, - "node_modules/webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "dev": true, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/webpack/node_modules/enhanced-resolve": { - "version": "5.14.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.14.1.tgz", - "integrity": "sha512-Vklwq2vDKtl0y/vtwjSesgJ5MYS7Etuk5txS8VdKL4AOS1aUlD96zqIfsOSLQsdv3xgMRbtkWM8eG9XDfKUPow==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - }, - "engines": { - "node": ">=10.13.0" - } - }, - "node_modules/websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "dev": true, - "dependencies": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - }, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "dev": true, - "engines": { - "node": ">=0.8.0" - } - }, - "node_modules/whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "dependencies": { - "iconv-lite": "0.4.24" - } - }, - "node_modules/whatwg-encoding/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==", - "dev": true, - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true - }, - "node_modules/whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "dependencies": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "dependencies": { - "isexe": "^2.0.0" - }, - "bin": { - "node-which": "bin/node-which" - }, - "engines": { - "node": ">= 8" - } - }, - "node_modules/which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "dependencies": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dev": true, - "dependencies": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "node_modules/wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", - "dev": true - }, - "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==", - "dev": true, - "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==", - "dev": true, - "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/wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "node_modules/write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "dependencies": { - "mkdirp": "^0.5.1" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "dependencies": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "node_modules/ws": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", - "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", - "dev": true, - "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/x-is-string": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", - "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=", - "dev": true - }, - "node_modules/xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true - }, - "node_modules/xmlbuilder": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", - "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", - "dev": true, - "engines": { - "node": ">=8.0" - } - }, - "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 - }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true, - "engines": { - "node": ">=0.4" - } - }, - "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, - "engines": { - "node": ">=10" - } - }, - "node_modules/yaku": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/yaku/-/yaku-0.16.7.tgz", - "integrity": "sha1-HRlceKqbW/hHnIlblQT9TwhHmE4=", - "dev": true - }, - "node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "node_modules/yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", - "engines": { - "node": ">= 6" - } - }, - "node_modules/yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "dependencies": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - }, - "engines": { - "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==", - "dev": true, - "engines": { - "node": ">=10" - } - }, - "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==", - "dev": true, - "dependencies": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - }, - "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==", - "dev": true, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/zod": { - "version": "3.21.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz", - "integrity": "sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==", - "funding": { - "url": "https://github.com/sponsors/colinhacks" - } - }, - "node_modules/zustand": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.3.8.tgz", - "integrity": "sha512-4h28KCkHg5ii/wcFFJ5Fp+k1J3gJoasaIbppdgZFO4BPJnsNxL0mQXBSFgOgAdCdBj35aDTPvdAJReTMntFPGg==", - "dependencies": { - "use-sync-external-store": "1.2.0" - }, - "engines": { - "node": ">=12.7.0" - }, - "peerDependencies": { - "immer": ">=9.0", - "react": ">=16.8" - }, - "peerDependenciesMeta": { - "immer": { - "optional": true - }, - "react": { - "optional": true - } - } - } - }, - "dependencies": { - "@ag-grid-community/client-side-row-model": { - "version": "28.2.1", - "resolved": "https://registry.npmjs.org/@ag-grid-community/client-side-row-model/-/client-side-row-model-28.2.1.tgz", - "integrity": "sha512-JLLNVNAtSbVjg/h0+JqNxbRGzHR9xl3YHO4kVt8Bu0UO1XQLfGLT8wkzqQTcEOiq0pEfFTee7/BGT3oHOQfUQg==", - "requires": { - "@ag-grid-community/core": "~28.2.1" - } - }, - "@ag-grid-community/core": { - "version": "28.2.1", - "resolved": "https://registry.npmjs.org/@ag-grid-community/core/-/core-28.2.1.tgz", - "integrity": "sha512-qGhqZhY8KbPlr3cJBVkNjGKu+cOyFc8IGvPcvlm0pjNC9cdxO/ct9Sa1Dg+k3ACCEroMEt1apBvnoOgurpvewQ==" - }, - "@ag-grid-community/infinite-row-model": { - "version": "28.2.1", - "resolved": "https://registry.npmjs.org/@ag-grid-community/infinite-row-model/-/infinite-row-model-28.2.1.tgz", - "integrity": "sha512-jvEvVNQ/USlQjGW0LbryR4/I1ZSgOBPn4tg45KWm3+R0jmDSfetI20D5t3UaSQHY6ZQMDVYxR3xSkorPFI3Vng==", - "requires": { - "@ag-grid-community/core": "~28.2.1" - } - }, - "@ag-grid-community/react": { - "version": "28.2.1", - "resolved": "https://registry.npmjs.org/@ag-grid-community/react/-/react-28.2.1.tgz", - "integrity": "sha512-VWtiBMhvDKp//lIa2Ovzv+/gcQj6wnZDhngyPW5e97Sl+sIs6/UngHSTbbmhIb+wWUCIKmSRL1+R05PNnKjFTA==", - "requires": { - "prop-types": "^15.8.1" - } - }, - "@ag-grid-community/styles": { - "version": "28.2.1", - "resolved": "https://registry.npmjs.org/@ag-grid-community/styles/-/styles-28.2.1.tgz", - "integrity": "sha512-dy3Z46zTnzrwJOnH+tFvIvY9g/8qIi+b7XmbQlmATBr9zcNMk0wqWH1/9sNHs1fFW6m3Csvu4ctyzdr9mSw1YA==" - }, - "@ampproject/remapping": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz", - "integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==", - "requires": { - "@jridgewell/trace-mapping": "^0.3.0" - } - }, - "@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==", - "requires": { - "@babel/highlight": "^7.18.6" - } - }, - "@babel/compat-data": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", - "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==" - }, - "@babel/core": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz", - "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", - "requires": { - "@ampproject/remapping": "^2.1.0", - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.5", - "@babel/helper-compilation-targets": "^7.20.0", - "@babel/helper-module-transforms": "^7.20.2", - "@babel/helpers": "^7.20.5", - "@babel/parser": "^7.20.5", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.2", - "json5": "^2.2.1", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "@babel/generator": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz", - "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", - "requires": { - "@babel/types": "^7.20.5", - "@jridgewell/gen-mapping": "^0.3.2", - "jsesc": "^2.5.1" - } - }, - "@babel/helper-annotate-as-pure": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", - "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-compilation-targets": { - "version": "7.20.0", - "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", - "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", - "requires": { - "@babel/compat-data": "^7.20.0", - "@babel/helper-validator-option": "^7.18.6", - "browserslist": "^4.21.3", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" - } - } - }, - "@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==" - }, - "@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==", - "requires": { - "@babel/template": "^7.18.10", - "@babel/types": "^7.19.0" - } - }, - "@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==", - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@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==", - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-module-transforms": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", - "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", - "requires": { - "@babel/helper-environment-visitor": "^7.18.9", - "@babel/helper-module-imports": "^7.18.6", - "@babel/helper-simple-access": "^7.20.2", - "@babel/helper-split-export-declaration": "^7.18.6", - "@babel/helper-validator-identifier": "^7.19.1", - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.1", - "@babel/types": "^7.20.2" - } - }, - "@babel/helper-plugin-utils": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", - "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==" - }, - "@babel/helper-simple-access": { - "version": "7.20.2", - "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", - "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", - "requires": { - "@babel/types": "^7.20.2" - } - }, - "@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==", - "requires": { - "@babel/types": "^7.18.6" - } - }, - "@babel/helper-string-parser": { - "version": "7.19.4", - "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", - "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==" - }, - "@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==" - }, - "@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==" - }, - "@babel/helpers": { - "version": "7.20.6", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", - "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", - "requires": { - "@babel/template": "^7.18.10", - "@babel/traverse": "^7.20.5", - "@babel/types": "^7.20.5" - } - }, - "@babel/highlight": { - "version": "7.18.6", - "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", - "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", - "requires": { - "@babel/helper-validator-identifier": "^7.18.6", - "chalk": "^2.0.0", - "js-tokens": "^4.0.0" - }, - "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==", - "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==", - "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==", - "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==" - }, - "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==" - }, - "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==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "@babel/parser": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", - "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==" - }, - "@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==", - "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.16.7", - "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz", - "integrity": "sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==", - "dev": true, - "requires": { - "@babel/helper-plugin-utils": "^7.16.7" - } - }, - "@babel/runtime": { - "version": "7.18.9", - "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz", - "integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==", - "requires": { - "regenerator-runtime": "^0.13.4" - } - }, - "@babel/runtime-corejs3": { - "version": "7.17.9", - "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.17.9.tgz", - "integrity": "sha512-WxYHHUWF2uZ7Hp1K+D1xQgbgkGUfA+5UPOegEXGt2Y5SMog/rYCVaifLZDbw8UkNXozEqqrZTy6bglL7xTaCOw==", - "dev": true, - "requires": { - "core-js-pure": "^3.20.2", - "regenerator-runtime": "^0.13.4" - } - }, - "@babel/template": { - "version": "7.18.10", - "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", - "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/parser": "^7.18.10", - "@babel/types": "^7.18.10" - } - }, - "@babel/traverse": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz", - "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", - "requires": { - "@babel/code-frame": "^7.18.6", - "@babel/generator": "^7.20.5", - "@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.20.5", - "@babel/types": "^7.20.5", - "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==" - } - } - }, - "@babel/types": { - "version": "7.20.5", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", - "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", - "requires": { - "@babel/helper-string-parser": "^7.19.4", - "@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 - }, - "@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", - "dev": true - }, - "@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", - "dev": true, - "requires": { - "@cspotcode/source-map-consumer": "0.8.0" - } - }, - "@csstools/selector-specificity": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.1.tgz", - "integrity": "sha512-aG20vknL4/YjQF9BSV7ts4EWm/yrjagAN7OWBNmlbEOUiu0llj4OGrFoOKK3g2vey4/p2omKCoHrWtPxSwV3HA==", - "dev": true, - "requires": {} - }, - "@develar/schema-utils": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz", - "integrity": "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==", - "dev": true, - "requires": { - "ajv": "^6.12.0", - "ajv-keywords": "^3.4.1" - } - }, - "@discoveryjs/json-ext": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", - "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", - "dev": true - }, - "@electron/asar": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.3.tgz", - "integrity": "sha512-wmOfE6szYyqZhRIiLH+eyZEp+bGcJI0OD/SCvSUrfBE0jvauyGYO2ZhpWxmNCcDojKu5DYrsVqT5BOCZZ01XIg==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "chromium-pickle-js": "^0.2.0", - "commander": "^5.0.0", - "glob": "^7.1.6", - "minimatch": "^3.0.4" - } - }, - "@electron/get": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.2.tgz", - "integrity": "sha512-eFZVFoRXb3GFGd7Ak7W4+6jBl9wBtiZ4AaYOse97ej6mKj5tkyO0dUnUChs1IhJZtx1BENo4/p4WUTXpi6vT+g==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "env-paths": "^2.2.0", - "fs-extra": "^8.1.0", - "global-agent": "^3.0.0", - "got": "^11.8.5", - "progress": "^2.0.3", - "semver": "^6.2.0", - "sumchecker": "^3.0.1" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "@electron/notarize": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-1.2.3.tgz", - "integrity": "sha512-9oRzT56rKh5bspk3KpAVF8lPKHYQrBnRwcgiOeR0hdilVEQmszDaAu0IPCPrwwzJN0ugNs0rRboTreHMt/6mBQ==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "fs-extra": "^9.0.1" - }, - "dependencies": { - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } - } - }, - "@electron/osx-sign": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.0.4.tgz", - "integrity": "sha512-xfhdEcIOfAZg7scZ9RQPya1G1lWo8/zMCwUXAulq0SfY7ONIW+b9qGyKdMyuMctNYwllrIS+vmxfijSfjeh97g==", - "dev": true, - "requires": { - "compare-version": "^0.1.2", - "debug": "^4.3.4", - "fs-extra": "^10.0.0", - "isbinaryfile": "^4.0.8", - "minimist": "^1.2.6", - "plist": "^3.0.5" - }, - "dependencies": { - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "isbinaryfile": { - "version": "4.0.10", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", - "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", - "dev": true - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } - } - }, - "@electron/rebuild": { - "version": "3.2.10", - "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.2.10.tgz", - "integrity": "sha512-SUBM6Mwi3yZaDFQjZzfGKpYTtOp9m60glounwX6tfGeVc/ZOl4jbquktUcyy7gYSLDWFLtKkftkY2xgMJZLQgg==", - "dev": true, - "requires": { - "@malept/cross-spawn-promise": "^2.0.0", - "chalk": "^4.0.0", - "debug": "^4.1.1", - "detect-libc": "^2.0.1", - "fs-extra": "^10.0.0", - "got": "^11.7.0", - "lzma-native": "^8.0.5", - "node-abi": "^3.0.0", - "node-api-version": "^0.1.4", - "node-gyp": "^9.0.0", - "ora": "^5.1.0", - "semver": "^7.3.5", - "tar": "^6.0.5", - "yargs": "^17.0.1" - }, - "dependencies": { - "@malept/cross-spawn-promise": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-2.0.0.tgz", - "integrity": "sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.1" - } - }, - "@npmcli/fs": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", - "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", - "dev": true, - "requires": { - "@gar/promisify": "^1.1.3", - "semver": "^7.3.5" - } - }, - "@npmcli/move-file": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", - "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", - "dev": true, - "requires": { - "mkdirp": "^1.0.4", - "rimraf": "^3.0.2" - } - }, - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } - }, - "cacache": { - "version": "16.1.3", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", - "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", - "dev": true, - "requires": { - "@npmcli/fs": "^2.1.0", - "@npmcli/move-file": "^2.0.0", - "chownr": "^2.0.0", - "fs-minipass": "^2.1.0", - "glob": "^8.0.1", - "infer-owner": "^1.0.4", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "mkdirp": "^1.0.4", - "p-map": "^4.0.0", - "promise-inflight": "^1.0.1", - "rimraf": "^3.0.2", - "ssri": "^9.0.0", - "tar": "^6.1.11", - "unique-filename": "^2.0.0" - }, - "dependencies": { - "glob": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", - "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", - "dev": true, - "requires": { + "name": "feishin", + "version": "0.2.0", + "lockfileVersion": 2, + "requires": true, + "packages": { + "": { + "name": "feishin", + "version": "0.2.0", + "hasInstallScript": true, + "license": "GPL-3.0", + "dependencies": { + "@ag-grid-community/client-side-row-model": "^28.2.1", + "@ag-grid-community/core": "^28.2.1", + "@ag-grid-community/infinite-row-model": "^28.2.1", + "@ag-grid-community/react": "^28.2.1", + "@ag-grid-community/styles": "^28.2.1", + "@emotion/react": "^11.10.4", + "@mantine/core": "^6.0.13", + "@mantine/dates": "^6.0.13", + "@mantine/form": "^6.0.13", + "@mantine/hooks": "^6.0.13", + "@mantine/modals": "^6.0.13", + "@mantine/notifications": "^6.0.13", + "@mantine/utils": "^6.0.13", + "@tanstack/react-query": "^4.29.5", + "@tanstack/react-query-devtools": "^4.29.6", + "@ts-rest/core": "^3.23.0", + "axios": "^1.4.0", + "cmdk": "^0.2.0", + "dayjs": "^1.11.6", + "electron-debug": "^3.2.0", + "electron-localshortcut": "^3.2.1", + "electron-log": "^4.4.6", + "electron-store": "^8.1.0", + "electron-updater": "^4.6.5", + "fast-average-color": "^9.3.0", + "format-duration": "^2.0.0", + "framer-motion": "^9.1.7", + "fuse.js": "^6.6.2", + "history": "^5.3.0", + "i18next": "^21.6.16", + "immer": "^9.0.21", + "is-electron": "^2.2.2", + "lodash": "^4.17.21", + "md5": "^2.3.0", + "memoize-one": "^6.0.0", + "nanoid": "^3.3.3", + "net": "^1.0.2", + "node-mpv": "github:jeffvli/Node-MPV", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-error-boundary": "^3.1.4", + "react-i18next": "^11.16.7", + "react-icons": "^4.8.0", + "react-player": "^2.11.0", + "react-router": "^6.5.0", + "react-router-dom": "^6.5.0", + "react-simple-img": "^3.0.0", + "react-virtualized-auto-sizer": "^1.0.17", + "react-window": "^1.8.9", + "react-window-infinite-loader": "^1.0.9", + "styled-components": "^5.3.11", + "swiper": "^9.3.1", + "zod": "^3.21.4", + "zustand": "^4.3.8" + }, + "devDependencies": { + "@electron/rebuild": "^3.2.10", + "@pmmmwh/react-refresh-webpack-plugin": "0.5.5", + "@stylelint/postcss-css-in-js": "^0.38.0", + "@teamsupercell/typings-for-css-modules-loader": "^2.5.1", + "@testing-library/jest-dom": "^5.16.4", + "@testing-library/react": "^13.0.0", + "@types/electron-localshortcut": "^3.1.0", + "@types/jest": "^27.4.1", + "@types/lodash": "^4.14.188", + "@types/md5": "^2.3.2", + "@types/node": "^17.0.23", + "@types/react": "^18.0.25", + "@types/react-dom": "^18.0.8", + "@types/react-test-renderer": "^17.0.1", + "@types/react-virtualized-auto-sizer": "^1.0.1", + "@types/react-window": "^1.8.5", + "@types/react-window-infinite-loader": "^1.0.6", + "@types/styled-components": "^5.1.26", + "@types/terser-webpack-plugin": "^5.0.4", + "@types/webpack-bundle-analyzer": "^4.4.1", + "@types/webpack-env": "^1.16.3", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "browserslist-config-erb": "^0.0.3", + "chalk": "^4.1.2", + "concurrently": "^7.1.0", + "core-js": "^3.21.1", + "cross-env": "^7.0.3", + "css-loader": "^6.7.1", + "css-minimizer-webpack-plugin": "^3.4.1", + "detect-port": "^1.3.0", + "electron": "^22.3.1", + "electron-builder": "^24.0.0-alpha.13", + "electron-devtools-installer": "^3.2.0", + "electron-notarize": "^1.2.1", + "electronmon": "^2.0.2", + "eslint": "^8.30.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-erb": "^4.0.3", + "eslint-import-resolver-typescript": "^2.7.1", + "eslint-import-resolver-webpack": "^0.13.2", + "eslint-plugin-compat": "^4.0.2", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-jest": "^26.1.3", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-promise": "^6.0.0", + "eslint-plugin-react": "^7.29.4", + "eslint-plugin-react-hooks": "^4.4.0", + "eslint-plugin-sort-keys-fix": "^1.1.2", + "eslint-plugin-typescript-sort-keys": "^2.1.0", + "file-loader": "^6.2.0", + "html-webpack-plugin": "^5.5.0", + "husky": "^7.0.4", + "i18next-parser": "^6.3.0", + "identity-obj-proxy": "^3.0.0", + "jest": "^27.5.1", + "lint-staged": "^12.3.7", + "mini-css-extract-plugin": "^2.6.0", + "postcss-scss": "^4.0.4", + "postcss-syntax": "^0.36.2", + "prettier": "^2.6.2", + "react-refresh": "^0.12.0", + "react-refresh-typescript": "^2.0.4", + "react-test-renderer": "^18.0.0", + "rimraf": "^3.0.2", + "sass": "^1.49.11", + "sass-loader": "^12.6.0", + "style-loader": "^3.3.1", + "stylelint": "^14.9.1", + "stylelint-config-rational-order": "^0.1.2", + "stylelint-config-standard-scss": "^4.0.0", + "stylelint-config-styled-components": "^0.1.1", + "stylelint-order": "^5.0.0", + "stylelint-processor-styled-components": "^1.10.0", + "terser-webpack-plugin": "^5.3.1", + "ts-jest": "^27.1.4", + "ts-loader": "^9.2.8", + "ts-node": "^10.7.0", + "tsconfig-paths-webpack-plugin": "^4.0.0", + "typescript": "^4.8.4", + "typescript-plugin-styled-components": "^2.0.0", + "url-loader": "^4.1.1", + "webpack": "^5.71.0", + "webpack-bundle-analyzer": "^4.5.0", + "webpack-cli": "^4.9.2", + "webpack-dev-server": "^4.8.0", + "webpack-merge": "^5.8.0" + } + }, + "node_modules/@ag-grid-community/client-side-row-model": { + "version": "28.2.1", + "resolved": "https://registry.npmjs.org/@ag-grid-community/client-side-row-model/-/client-side-row-model-28.2.1.tgz", + "integrity": "sha512-JLLNVNAtSbVjg/h0+JqNxbRGzHR9xl3YHO4kVt8Bu0UO1XQLfGLT8wkzqQTcEOiq0pEfFTee7/BGT3oHOQfUQg==", + "dependencies": { + "@ag-grid-community/core": "~28.2.1" + } + }, + "node_modules/@ag-grid-community/core": { + "version": "28.2.1", + "resolved": "https://registry.npmjs.org/@ag-grid-community/core/-/core-28.2.1.tgz", + "integrity": "sha512-qGhqZhY8KbPlr3cJBVkNjGKu+cOyFc8IGvPcvlm0pjNC9cdxO/ct9Sa1Dg+k3ACCEroMEt1apBvnoOgurpvewQ==" + }, + "node_modules/@ag-grid-community/infinite-row-model": { + "version": "28.2.1", + "resolved": "https://registry.npmjs.org/@ag-grid-community/infinite-row-model/-/infinite-row-model-28.2.1.tgz", + "integrity": "sha512-jvEvVNQ/USlQjGW0LbryR4/I1ZSgOBPn4tg45KWm3+R0jmDSfetI20D5t3UaSQHY6ZQMDVYxR3xSkorPFI3Vng==", + "dependencies": { + "@ag-grid-community/core": "~28.2.1" + } + }, + "node_modules/@ag-grid-community/react": { + "version": "28.2.1", + "resolved": "https://registry.npmjs.org/@ag-grid-community/react/-/react-28.2.1.tgz", + "integrity": "sha512-VWtiBMhvDKp//lIa2Ovzv+/gcQj6wnZDhngyPW5e97Sl+sIs6/UngHSTbbmhIb+wWUCIKmSRL1+R05PNnKjFTA==", + "dependencies": { + "prop-types": "^15.8.1" + }, + "peerDependencies": { + "@ag-grid-community/core": "~28.2.1", + "react": "^16.3.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.3.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@ag-grid-community/styles": { + "version": "28.2.1", + "resolved": "https://registry.npmjs.org/@ag-grid-community/styles/-/styles-28.2.1.tgz", + "integrity": "sha512-dy3Z46zTnzrwJOnH+tFvIvY9g/8qIi+b7XmbQlmATBr9zcNMk0wqWH1/9sNHs1fFW6m3Csvu4ctyzdr9mSw1YA==" + }, + "node_modules/@ampproject/remapping": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz", + "integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==", + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.0" + }, + "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==", + "dependencies": { + "@babel/highlight": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/compat-data": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", + "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz", + "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", + "dependencies": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-module-transforms": "^7.20.2", + "@babel/helpers": "^7.20.5", + "@babel/parser": "^7.20.5", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/babel" + } + }, + "node_modules/@babel/core/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@babel/generator": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz", + "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", + "dependencies": { + "@babel/types": "^7.20.5", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-annotate-as-pure": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", + "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-compilation-targets": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", + "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", + "dependencies": { + "@babel/compat-data": "^7.20.0", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/@babel/helper-compilation-targets/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "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==", + "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==", + "dependencies": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + }, + "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==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "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==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-module-transforms": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", + "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", + "dependencies": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.1", + "@babel/types": "^7.20.2" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-plugin-utils": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-simple-access": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "dependencies": { + "@babel/types": "^7.20.2" + }, + "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==", + "dependencies": { + "@babel/types": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==", + "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==", + "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==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/helpers": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", + "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", + "dependencies": { + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" + }, + "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==", + "dependencies": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/highlight/node_modules/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==", + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/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==", + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/@babel/highlight/node_modules/color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==" + }, + "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==", + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/@babel/highlight/node_modules/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==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/parser": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", + "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==", + "bin": { + "parser": "bin/babel-parser.js" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@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, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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, + "dependencies": { + "@babel/helper-plugin-utils": "^7.12.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "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==", + "dependencies": { + "@babel/helper-plugin-utils": "^7.18.6" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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, + "dependencies": { + "@babel/helper-plugin-utils": "^7.10.4" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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, + "dependencies": { + "@babel/helper-plugin-utils": "^7.8.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@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, + "dependencies": { + "@babel/helper-plugin-utils": "^7.14.5" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/plugin-syntax-typescript": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz", + "integrity": "sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==", + "dev": true, + "dependencies": { + "@babel/helper-plugin-utils": "^7.16.7" + }, + "engines": { + "node": ">=6.9.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0-0" + } + }, + "node_modules/@babel/runtime": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz", + "integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==", + "dependencies": { + "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/runtime-corejs3": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.17.9.tgz", + "integrity": "sha512-WxYHHUWF2uZ7Hp1K+D1xQgbgkGUfA+5UPOegEXGt2Y5SMog/rYCVaifLZDbw8UkNXozEqqrZTy6bglL7xTaCOw==", + "dev": true, + "dependencies": { + "core-js-pure": "^3.20.2", + "regenerator-runtime": "^0.13.4" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/template": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz", + "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", + "dependencies": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.5", + "@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.20.5", + "@babel/types": "^7.20.5", + "debug": "^4.1.0", + "globals": "^11.1.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@babel/traverse/node_modules/globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/types": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", + "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", + "dependencies": { + "@babel/helper-string-parser": "^7.19.4", + "@babel/helper-validator-identifier": "^7.19.1", + "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/@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 + }, + "node_modules/@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-consumer": "0.8.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@csstools/selector-specificity": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.1.tgz", + "integrity": "sha512-aG20vknL4/YjQF9BSV7ts4EWm/yrjagAN7OWBNmlbEOUiu0llj4OGrFoOKK3g2vey4/p2omKCoHrWtPxSwV3HA==", + "dev": true, + "engines": { + "node": "^12 || ^14 || >=16" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/csstools" + }, + "peerDependencies": { + "postcss": "^8.3", + "postcss-selector-parser": "^6.0.10" + } + }, + "node_modules/@develar/schema-utils": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz", + "integrity": "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==", + "dev": true, + "dependencies": { + "ajv": "^6.12.0", + "ajv-keywords": "^3.4.1" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/@electron/asar": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.3.tgz", + "integrity": "sha512-wmOfE6szYyqZhRIiLH+eyZEp+bGcJI0OD/SCvSUrfBE0jvauyGYO2ZhpWxmNCcDojKu5DYrsVqT5BOCZZ01XIg==", + "dev": true, + "dependencies": { + "chromium-pickle-js": "^0.2.0", + "commander": "^5.0.0", + "glob": "^7.1.6", + "minimatch": "^3.0.4" + }, + "bin": { + "asar": "bin/asar.js" + }, + "engines": { + "node": ">=10.12.0" + }, + "optionalDependencies": { + "@types/glob": "^7.1.1" + } + }, + "node_modules/@electron/get": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.2.tgz", + "integrity": "sha512-eFZVFoRXb3GFGd7Ak7W4+6jBl9wBtiZ4AaYOse97ej6mKj5tkyO0dUnUChs1IhJZtx1BENo4/p4WUTXpi6vT+g==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "env-paths": "^2.2.0", + "fs-extra": "^8.1.0", + "got": "^11.8.5", + "progress": "^2.0.3", + "semver": "^6.2.0", + "sumchecker": "^3.0.1" + }, + "engines": { + "node": ">=12" + }, + "optionalDependencies": { + "global-agent": "^3.0.0" + } + }, + "node_modules/@electron/get/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/@electron/notarize": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-1.2.3.tgz", + "integrity": "sha512-9oRzT56rKh5bspk3KpAVF8lPKHYQrBnRwcgiOeR0hdilVEQmszDaAu0IPCPrwwzJN0ugNs0rRboTreHMt/6mBQ==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "fs-extra": "^9.0.1" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@electron/notarize/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@electron/notarize/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/notarize/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@electron/osx-sign": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.0.4.tgz", + "integrity": "sha512-xfhdEcIOfAZg7scZ9RQPya1G1lWo8/zMCwUXAulq0SfY7ONIW+b9qGyKdMyuMctNYwllrIS+vmxfijSfjeh97g==", + "dev": true, + "dependencies": { + "compare-version": "^0.1.2", + "debug": "^4.3.4", + "fs-extra": "^10.0.0", + "isbinaryfile": "^4.0.8", + "minimist": "^1.2.6", + "plist": "^3.0.5" + }, + "bin": { + "electron-osx-flat": "bin/electron-osx-flat.js", + "electron-osx-sign": "bin/electron-osx-sign.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/@electron/osx-sign/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@electron/osx-sign/node_modules/isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true, + "engines": { + "node": ">= 8.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/@electron/osx-sign/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@electron/osx-sign/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@electron/rebuild": { + "version": "3.2.10", + "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.2.10.tgz", + "integrity": "sha512-SUBM6Mwi3yZaDFQjZzfGKpYTtOp9m60glounwX6tfGeVc/ZOl4jbquktUcyy7gYSLDWFLtKkftkY2xgMJZLQgg==", + "dev": true, + "dependencies": { + "@malept/cross-spawn-promise": "^2.0.0", + "chalk": "^4.0.0", + "debug": "^4.1.1", + "detect-libc": "^2.0.1", + "fs-extra": "^10.0.0", + "got": "^11.7.0", + "lzma-native": "^8.0.5", + "node-abi": "^3.0.0", + "node-api-version": "^0.1.4", + "node-gyp": "^9.0.0", + "ora": "^5.1.0", + "semver": "^7.3.5", + "tar": "^6.0.5", + "yargs": "^17.0.1" + }, + "bin": { + "electron-rebuild": "lib/src/cli.js" + }, + "engines": { + "node": ">=12.13.0" + } + }, + "node_modules/@electron/rebuild/node_modules/@malept/cross-spawn-promise": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-2.0.0.tgz", + "integrity": "sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/malept" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" + } + ], + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "engines": { + "node": ">= 12.13.0" + } + }, + "node_modules/@electron/rebuild/node_modules/@npmcli/fs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", + "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", + "dev": true, + "dependencies": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/@electron/rebuild/node_modules/@npmcli/move-file": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", + "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", + "deprecated": "This functionality has been moved to @npmcli/fs", + "dev": true, + "dependencies": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/@electron/rebuild/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@electron/rebuild/node_modules/cacache": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", + "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", + "dev": true, + "dependencies": { + "@npmcli/fs": "^2.1.0", + "@npmcli/move-file": "^2.0.0", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "glob": "^8.0.1", + "infer-owner": "^1.0.4", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "mkdirp": "^1.0.4", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^9.0.0", + "tar": "^6.1.11", + "unique-filename": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "node_modules/@electron/rebuild/node_modules/cacache/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dev": true, + "dependencies": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", "inherits": "2", "minimatch": "^5.0.1", "once": "^1.3.0" - } + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" } - } }, - "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" - } + "node_modules/@electron/rebuild/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, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } }, - "detect-libc": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", - "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", - "dev": true + "node_modules/@electron/rebuild/node_modules/detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } + "node_modules/@electron/rebuild/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } + "node_modules/@electron/rebuild/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } }, - "lru-cache": { - "version": "7.18.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.1.tgz", - "integrity": "sha512-8/HcIENyQnfUTCDizRu9rrDyG6XG/21M4X7/YEGZeD76ZJilFPAUVb/2zysFf7VVO1LEjCDFyHp8pMMvozIrvg==", - "dev": true + "node_modules/@electron/rebuild/node_modules/lru-cache": { + "version": "7.18.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.1.tgz", + "integrity": "sha512-8/HcIENyQnfUTCDizRu9rrDyG6XG/21M4X7/YEGZeD76ZJilFPAUVb/2zysFf7VVO1LEjCDFyHp8pMMvozIrvg==", + "dev": true, + "engines": { + "node": ">=12" + } }, - "make-fetch-happen": { - "version": "10.2.1", - "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", - "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", - "dev": true, - "requires": { - "agentkeepalive": "^4.2.1", - "cacache": "^16.1.0", - "http-cache-semantics": "^4.1.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.0", - "is-lambda": "^1.0.1", - "lru-cache": "^7.7.1", - "minipass": "^3.1.6", - "minipass-collect": "^1.0.2", - "minipass-fetch": "^2.0.3", - "minipass-flush": "^1.0.5", - "minipass-pipeline": "^1.2.4", - "negotiator": "^0.6.3", - "promise-retry": "^2.0.1", - "socks-proxy-agent": "^7.0.0", - "ssri": "^9.0.0" - } + "node_modules/@electron/rebuild/node_modules/make-fetch-happen": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", + "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", + "dev": true, + "dependencies": { + "agentkeepalive": "^4.2.1", + "cacache": "^16.1.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^2.0.3", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^9.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } }, - "minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } + "node_modules/@electron/rebuild/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } }, - "minipass-fetch": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", - "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", - "dev": true, - "requires": { - "encoding": "^0.1.13", - "minipass": "^3.1.6", - "minipass-sized": "^1.0.3", - "minizlib": "^2.1.2" - } + "node_modules/@electron/rebuild/node_modules/minipass-fetch": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", + "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", + "dev": true, + "dependencies": { + "minipass": "^3.1.6", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + }, + "optionalDependencies": { + "encoding": "^0.1.13" + } }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true + "node_modules/@electron/rebuild/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } }, - "node-gyp": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.3.1.tgz", - "integrity": "sha512-4Q16ZCqq3g8awk6UplT7AuxQ35XN4R/yf/+wSAwcBUAjg7l58RTactWaP8fIDTi0FzI7YcVLujwExakZlfWkXg==", - "dev": true, - "requires": { - "env-paths": "^2.2.0", - "glob": "^7.1.4", - "graceful-fs": "^4.2.6", - "make-fetch-happen": "^10.0.3", - "nopt": "^6.0.0", - "npmlog": "^6.0.0", - "rimraf": "^3.0.2", - "semver": "^7.3.5", - "tar": "^6.1.2", - "which": "^2.0.2" - } + "node_modules/@electron/rebuild/node_modules/node-gyp": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.3.1.tgz", + "integrity": "sha512-4Q16ZCqq3g8awk6UplT7AuxQ35XN4R/yf/+wSAwcBUAjg7l58RTactWaP8fIDTi0FzI7YcVLujwExakZlfWkXg==", + "dev": true, + "dependencies": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^10.0.3", + "nopt": "^6.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + }, + "bin": { + "node-gyp": "bin/node-gyp.js" + }, + "engines": { + "node": "^12.13 || ^14.13 || >=16" + } }, - "nopt": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", - "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", - "dev": true, - "requires": { - "abbrev": "^1.0.0" - } + "node_modules/@electron/rebuild/node_modules/nopt": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", + "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", + "dev": true, + "dependencies": { + "abbrev": "^1.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } }, - "socks-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", - "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", - "dev": true, - "requires": { - "agent-base": "^6.0.2", - "debug": "^4.3.3", - "socks": "^2.6.2" - } + "node_modules/@electron/rebuild/node_modules/socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "dev": true, + "dependencies": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + }, + "engines": { + "node": ">= 10" + } }, - "ssri": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", - "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", - "dev": true, - "requires": { - "minipass": "^3.1.1" - } + "node_modules/@electron/rebuild/node_modules/ssri": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", + "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", + "dev": true, + "dependencies": { + "minipass": "^3.1.1" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } }, - "unique-filename": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", - "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", - "dev": true, - "requires": { - "unique-slug": "^3.0.0" - } + "node_modules/@electron/rebuild/node_modules/unique-filename": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", + "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", + "dev": true, + "dependencies": { + "unique-slug": "^3.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } }, - "unique-slug": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", - "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } + "node_modules/@electron/rebuild/node_modules/unique-slug": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", + "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true + "node_modules/@electron/rebuild/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } }, - "yargs": { - "version": "17.7.1", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", - "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", - "dev": true, - "requires": { - "cliui": "^8.0.1", - "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.1.1" - } + "node_modules/@electron/rebuild/node_modules/yargs": { + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "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.1.1" + }, + "engines": { + "node": ">=12" + } }, - "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 - } - } - }, - "@electron/universal": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-1.3.4.tgz", - "integrity": "sha512-BdhBgm2ZBnYyYRLRgOjM5VHkyFItsbggJ0MHycOjKWdFGYwK97ZFXH54dTvUWEfha81vfvwr5On6XBjt99uDcg==", - "dev": true, - "requires": { - "@electron/asar": "^3.2.1", - "@malept/cross-spawn-promise": "^1.1.0", - "debug": "^4.3.1", - "dir-compare": "^3.0.0", - "fs-extra": "^9.0.1", - "minimatch": "^3.0.4", - "plist": "^3.0.4" - }, - "dependencies": { - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } + "node_modules/@electron/rebuild/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, + "engines": { + "node": ">=12" + } }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } + "node_modules/@electron/universal": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-1.3.4.tgz", + "integrity": "sha512-BdhBgm2ZBnYyYRLRgOjM5VHkyFItsbggJ0MHycOjKWdFGYwK97ZFXH54dTvUWEfha81vfvwr5On6XBjt99uDcg==", + "dev": true, + "dependencies": { + "@electron/asar": "^3.2.1", + "@malept/cross-spawn-promise": "^1.1.0", + "debug": "^4.3.1", + "dir-compare": "^3.0.0", + "fs-extra": "^9.0.1", + "minimatch": "^3.0.4", + "plist": "^3.0.4" + }, + "engines": { + "node": ">=8.6" + } }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } - } - }, - "@emotion/babel-plugin": { - "version": "11.10.2", - "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.2.tgz", - "integrity": "sha512-xNQ57njWTFVfPAc3cjfuaPdsgLp5QOSuRsj9MA6ndEhH/AzuZM86qIQzt6rq+aGBwj3n5/TkLmU5lhAfdRmogA==", - "requires": { - "@babel/helper-module-imports": "^7.16.7", - "@babel/plugin-syntax-jsx": "^7.17.12", - "@babel/runtime": "^7.18.3", - "@emotion/hash": "^0.9.0", - "@emotion/memoize": "^0.8.0", - "@emotion/serialize": "^1.1.0", - "babel-plugin-macros": "^3.1.0", - "convert-source-map": "^1.5.0", - "escape-string-regexp": "^4.0.0", - "find-root": "^1.1.0", - "source-map": "^0.5.7", - "stylis": "4.0.13" - }, - "dependencies": { - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" - } - } - }, - "@emotion/cache": { - "version": "11.10.3", - "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.3.tgz", - "integrity": "sha512-Psmp/7ovAa8appWh3g51goxu/z3iVms7JXOreq136D8Bbn6dYraPnmL6mdM8GThEx9vwSn92Fz+mGSjBzN8UPQ==", - "requires": { - "@emotion/memoize": "^0.8.0", - "@emotion/sheet": "^1.2.0", - "@emotion/utils": "^1.2.0", - "@emotion/weak-memoize": "^0.3.0", - "stylis": "4.0.13" - } - }, - "@emotion/hash": { - "version": "0.9.0", - "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz", - "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==" - }, - "@emotion/is-prop-valid": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", - "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", - "requires": { - "@emotion/memoize": "^0.8.0" - } - }, - "@emotion/memoize": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", - "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" - }, - "@emotion/react": { - "version": "11.10.4", - "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.4.tgz", - "integrity": "sha512-j0AkMpr6BL8gldJZ6XQsQ8DnS9TxEQu1R+OGmDZiWjBAJtCcbt0tS3I/YffoqHXxH6MjgI7KdMbYKw3MEiU9eA==", - "requires": { - "@babel/runtime": "^7.18.3", - "@emotion/babel-plugin": "^11.10.0", - "@emotion/cache": "^11.10.0", - "@emotion/serialize": "^1.1.0", - "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", - "@emotion/utils": "^1.2.0", - "@emotion/weak-memoize": "^0.3.0", - "hoist-non-react-statics": "^3.3.1" - } - }, - "@emotion/serialize": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.0.tgz", - "integrity": "sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA==", - "requires": { - "@emotion/hash": "^0.9.0", - "@emotion/memoize": "^0.8.0", - "@emotion/unitless": "^0.8.0", - "@emotion/utils": "^1.2.0", - "csstype": "^3.0.2" - }, - "dependencies": { - "@emotion/unitless": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", - "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" - } - } - }, - "@emotion/sheet": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.0.tgz", - "integrity": "sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w==" - }, - "@emotion/stylis": { - "version": "0.8.5", - "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", - "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" - }, - "@emotion/unitless": { - "version": "0.7.5", - "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", - "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" - }, - "@emotion/use-insertion-effect-with-fallbacks": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz", - "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==", - "requires": {} - }, - "@emotion/utils": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz", - "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==" - }, - "@emotion/weak-memoize": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz", - "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==" - }, - "@eslint/eslintrc": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.0.tgz", - "integrity": "sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A==", - "dev": true, - "requires": { - "ajv": "^6.12.4", - "debug": "^4.3.2", - "espree": "^9.4.0", - "globals": "^13.19.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" - } - }, - "@floating-ui/core": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.2.1.tgz", - "integrity": "sha512-LSqwPZkK3rYfD7GKoIeExXOyYx6Q1O4iqZWwIehDNuv3Dv425FIAE8PRwtAx1imEolFTHgBEcoFHm9MDnYgPCg==" - }, - "@floating-ui/dom": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.2.1.tgz", - "integrity": "sha512-Rt45SmRiV8eU+xXSB9t0uMYiQ/ZWGE/jumse2o3i5RGlyvcbqOF4q+1qBnzLE2kZ5JGhq0iMkcGXUKbFe7MpTA==", - "requires": { - "@floating-ui/core": "^1.2.1" - } - }, - "@floating-ui/react": { - "version": "0.19.2", - "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.19.2.tgz", - "integrity": "sha512-JyNk4A0Ezirq8FlXECvRtQOX/iBe5Ize0W/pLkrZjfHW9GUV7Xnq6zm6fyZuQzaHHqEnVizmvlA96e1/CkZv+w==", - "requires": { - "@floating-ui/react-dom": "^1.3.0", - "aria-hidden": "^1.1.3", - "tabbable": "^6.0.1" - } - }, - "@floating-ui/react-dom": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-1.3.0.tgz", - "integrity": "sha512-htwHm67Ji5E/pROEAr7f8IKFShuiCKHwUC/UY4vC3I5jiSvGFAYnSYiZO5MlGmads+QqvUkR9ANHEguGrDv72g==", - "requires": { - "@floating-ui/dom": "^1.2.1" - } - }, - "@gar/promisify": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", - "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", - "dev": true - }, - "@humanwhocodes/config-array": { - "version": "0.11.8", - "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", - "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", - "dev": true, - "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==", - "dev": true - }, - "@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==", - "dev": true - }, - "@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" - } + "node_modules/@electron/universal/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } }, - "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" - } + "node_modules/@electron/universal/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } }, - "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" - } + "node_modules/@electron/universal/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.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" - } + "node_modules/@emotion/babel-plugin": { + "version": "11.10.2", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.2.tgz", + "integrity": "sha512-xNQ57njWTFVfPAc3cjfuaPdsgLp5QOSuRsj9MA6ndEhH/AzuZM86qIQzt6rq+aGBwj3n5/TkLmU5lhAfdRmogA==", + "dependencies": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/plugin-syntax-jsx": "^7.17.12", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.0", + "@emotion/memoize": "^0.8.0", + "@emotion/serialize": "^1.1.0", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.0.13" + }, + "peerDependencies": { + "@babel/core": "^7.0.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" - } + "node_modules/@emotion/babel-plugin/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "engines": { + "node": ">=0.10.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" - } + "node_modules/@emotion/cache": { + "version": "11.10.3", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.3.tgz", + "integrity": "sha512-Psmp/7ovAa8appWh3g51goxu/z3iVms7JXOreq136D8Bbn6dYraPnmL6mdM8GThEx9vwSn92Fz+mGSjBzN8UPQ==", + "dependencies": { + "@emotion/memoize": "^0.8.0", + "@emotion/sheet": "^1.2.0", + "@emotion/utils": "^1.2.0", + "@emotion/weak-memoize": "^0.3.0", + "stylis": "4.0.13" + } }, - "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/@emotion/hash": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz", + "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==" }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "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": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", - "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0" - } - }, - "@jest/core": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", - "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", - "dev": true, - "requires": { - "@jest/console": "^27.5.1", - "@jest/reporters": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "jest-changed-files": "^27.5.1", - "jest-config": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-resolve-dependencies": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "jest-watcher": "^27.5.1", - "micromatch": "^4.0.4", - "rimraf": "^3.0.0", - "slash": "^3.0.0", - "strip-ansi": "^6.0.0" - } - }, - "@jest/environment": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", - "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", - "dev": true, - "requires": { - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1" - } - }, - "@jest/fake-timers": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", - "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@sinonjs/fake-timers": "^8.0.1", - "@types/node": "*", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - } - }, - "@jest/globals": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", - "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/types": "^27.5.1", - "expect": "^27.5.1" - } - }, - "@jest/reporters": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", - "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", - "dev": true, - "requires": { - "@bcoe/v8-coverage": "^0.2.3", - "@jest/console": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "collect-v8-coverage": "^1.0.0", - "exit": "^0.1.2", - "glob": "^7.1.2", - "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-haste-map": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "slash": "^3.0.0", - "source-map": "^0.6.0", - "string-length": "^4.0.1", - "terminal-link": "^2.0.0", - "v8-to-istanbul": "^8.1.0" - }, - "dependencies": { - "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 - } - } - }, - "@jest/source-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", - "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", - "dev": true, - "requires": { - "callsites": "^3.0.0", - "graceful-fs": "^4.2.9", - "source-map": "^0.6.0" - }, - "dependencies": { - "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 - } - } - }, - "@jest/test-result": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", - "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", - "dev": true, - "requires": { - "@jest/console": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/istanbul-lib-coverage": "^2.0.0", - "collect-v8-coverage": "^1.0.0" - } - }, - "@jest/test-sequencer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", - "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", - "dev": true, - "requires": { - "@jest/test-result": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-runtime": "^27.5.1" - } - }, - "@jest/transform": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", - "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", - "dev": true, - "requires": { - "@babel/core": "^7.1.0", - "@jest/types": "^27.5.1", - "babel-plugin-istanbul": "^6.1.1", - "chalk": "^4.0.0", - "convert-source-map": "^1.4.0", - "fast-json-stable-stringify": "^2.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-util": "^27.5.1", - "micromatch": "^4.0.4", - "pirates": "^4.0.4", - "slash": "^3.0.0", - "source-map": "^0.6.1", - "write-file-atomic": "^3.0.0" - }, - "dependencies": { - "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 - } - } - }, - "@jest/types": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", - "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.0", - "@types/istanbul-reports": "^3.0.0", - "@types/node": "*", - "@types/yargs": "^16.0.0", - "chalk": "^4.0.0" - }, - "dependencies": { - "@types/yargs": { - "version": "16.0.4", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", - "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", - "dev": true, - "requires": { - "@types/yargs-parser": "*" - } - } - } - }, - "@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==", - "requires": { - "@jridgewell/set-array": "^1.0.1", - "@jridgewell/sourcemap-codec": "^1.4.10", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@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==" - }, - "@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==" - }, - "@jridgewell/source-map": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", - "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", - "dev": true, - "requires": { - "@jridgewell/gen-mapping": "^0.3.0", - "@jridgewell/trace-mapping": "^0.3.9" - } - }, - "@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==" - }, - "@jridgewell/trace-mapping": { - "version": "0.3.18", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", - "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", - "requires": { - "@jridgewell/resolve-uri": "3.1.0", - "@jridgewell/sourcemap-codec": "1.4.14" - } - }, - "@leichtgewicht/ip-codec": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz", - "integrity": "sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg==", - "dev": true - }, - "@malept/cross-spawn-promise": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", - "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.1" - } - }, - "@malept/flatpak-bundler": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz", - "integrity": "sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "fs-extra": "^9.0.0", - "lodash": "^4.17.15", - "tmp-promise": "^3.0.2" - }, - "dependencies": { - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } + "node_modules/@emotion/is-prop-valid": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", + "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", + "dependencies": { + "@emotion/memoize": "^0.8.0" + } }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } + "node_modules/@emotion/memoize": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", + "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } - } - }, - "@mantine/core": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@mantine/core/-/core-6.0.13.tgz", - "integrity": "sha512-FjVUGgat2qISV9WD1maVJa81y7H0JjKJ3m0cJj65PzgrXT20hzdEda7S3i4j+a8vUnx+836x5q/yS+RDHvoSlA==", - "requires": { - "@floating-ui/react": "^0.19.1", - "@mantine/styles": "6.0.13", - "@mantine/utils": "6.0.13", - "@radix-ui/react-scroll-area": "1.0.2", - "react-remove-scroll": "^2.5.5", - "react-textarea-autosize": "8.3.4" - } - }, - "@mantine/dates": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@mantine/dates/-/dates-6.0.13.tgz", - "integrity": "sha512-sWStU+sgblTZAfuuFlwG3w3WCFYHVf1L+sG2WdlXOljd9WpQVem214HTh6staJ894+vIQESIvseWvq6FDyQAaQ==", - "requires": { - "@mantine/utils": "6.0.13" - } - }, - "@mantine/form": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@mantine/form/-/form-6.0.13.tgz", - "integrity": "sha512-oR/bnnJEd6T42N5pUhXYZ5RaKC4EZozEFW2jHCWDKIAJDjIgGUQrLL/tCjclQ2NwtghaoCTz+9zu32CuXer7TA==", - "requires": { - "fast-deep-equal": "^3.1.3", - "klona": "^2.0.5" - } - }, - "@mantine/hooks": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-6.0.13.tgz", - "integrity": "sha512-fHuE3zXo5OP/Q1dMOTnegU6U+tI9GuhO2tgOz6szVuOxrrk0Hzuq1Na9NUSv27HShSRbAfQk+hvyIh+iVV7KXA==", - "requires": {} - }, - "@mantine/modals": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@mantine/modals/-/modals-6.0.13.tgz", - "integrity": "sha512-R/FfH+vzk1iKxl/HDgUC0CXZI7zvQ79J+VUSw9eQcNWgSTx9IwrDbFeEtWC2SvVNaCYmMSxgadCbgjKsaeqzWA==", - "requires": { - "@mantine/utils": "6.0.13" - } - }, - "@mantine/notifications": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@mantine/notifications/-/notifications-6.0.13.tgz", - "integrity": "sha512-d3BxNN7LEblvAsui0yGiI1q1Ji2OlhFLfe/cLdj7s5VMOtiKYRV14dICJxe4Jn/o+8Gg+UKw+aO/ZiQoT+BGIw==", - "requires": { - "@mantine/utils": "6.0.13", - "react-transition-group": "4.4.2" - } - }, - "@mantine/styles": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@mantine/styles/-/styles-6.0.13.tgz", - "integrity": "sha512-+27oX8ObiBv8jHHDxXKjqe+7cfTJyaAV/Ie00T49EE4LuHuS6nL4vlXHmqamFtDCj2ypEWBV0sdXDev/DNAXSg==", - "requires": { - "clsx": "1.1.1", - "csstype": "3.0.9" - }, - "dependencies": { - "csstype": { - "version": "3.0.9", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.9.tgz", - "integrity": "sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw==" - } - } - }, - "@mantine/utils": { - "version": "6.0.13", - "resolved": "https://registry.npmjs.org/@mantine/utils/-/utils-6.0.13.tgz", - "integrity": "sha512-iqIU9wurqAeccVbWjM0yr1JGne5VP+ob55M03QAXOEN4+ck93VDTjCkZJR2RFhDcs5q0twQFoOmU/gULR8aKIA==", - "requires": {} - }, - "@mdn/browser-compat-data": { - "version": "4.1.15", - "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-4.1.15.tgz", - "integrity": "sha512-OZx2PxHtJDc9NOHGR3T0ZtX1WYl5qH/xmiH3sKSmcd3o+vPMG1kVUYbZrMxH3fVKpkkkrQpwETCIDRXcMXAWTw==", - "dev": true - }, - "@mrmlnc/readdir-enhanced": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", - "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", - "dev": true, - "requires": { - "call-me-maybe": "^1.0.1", - "glob-to-regexp": "^0.3.0" - }, - "dependencies": { - "glob-to-regexp": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", - "integrity": "sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==", - "dev": true - } - } - }, - "@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==", - "dev": true, - "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==", - "dev": true - }, - "@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==", - "dev": true, - "requires": { - "@nodelib/fs.scandir": "2.1.5", - "fastq": "^1.6.0" - } - }, - "@pmmmwh/react-refresh-webpack-plugin": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.5.tgz", - "integrity": "sha512-RbG7h6TuP6nFFYKJwbcToA1rjC1FyPg25NR2noAZ0vKI+la01KTSRPkuVPE+U88jXv7javx2JHglUcL1MHcshQ==", - "dev": true, - "requires": { - "ansi-html-community": "^0.0.8", - "common-path-prefix": "^3.0.0", - "core-js-pure": "^3.8.1", - "error-stack-parser": "^2.0.6", - "find-up": "^5.0.0", - "html-entities": "^2.1.0", - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0", - "source-map": "^0.7.3" - } - }, - "@polka/url": { - "version": "1.0.0-next.21", - "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", - "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==", - "dev": true - }, - "@radix-ui/number": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.0.tgz", - "integrity": "sha512-Ofwh/1HX69ZfJRiRBMTy7rgjAzHmwe4kW9C9Y99HTRUcYLUuVT0KESFj15rPjRgKJs20GPq8Bm5aEDJ8DuA3vA==", - "requires": { - "@babel/runtime": "^7.13.10" - } - }, - "@radix-ui/primitive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.0.tgz", - "integrity": "sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==", - "requires": { - "@babel/runtime": "^7.13.10" - } - }, - "@radix-ui/react-compose-refs": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz", - "integrity": "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA==", - "requires": { - "@babel/runtime": "^7.13.10" - } - }, - "@radix-ui/react-context": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.0.tgz", - "integrity": "sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg==", - "requires": { - "@babel/runtime": "^7.13.10" - } - }, - "@radix-ui/react-dialog": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.0.tgz", - "integrity": "sha512-Yn9YU+QlHYLWwV1XfKiqnGVpWYWk6MeBVM6x/bcoyPvxgjQGoeT35482viLPctTMWoMw0PoHgqfSox7Ig+957Q==", - "requires": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.0", - "@radix-ui/react-compose-refs": "1.0.0", - "@radix-ui/react-context": "1.0.0", - "@radix-ui/react-dismissable-layer": "1.0.0", - "@radix-ui/react-focus-guards": "1.0.0", - "@radix-ui/react-focus-scope": "1.0.0", - "@radix-ui/react-id": "1.0.0", - "@radix-ui/react-portal": "1.0.0", - "@radix-ui/react-presence": "1.0.0", - "@radix-ui/react-primitive": "1.0.0", - "@radix-ui/react-slot": "1.0.0", - "@radix-ui/react-use-controllable-state": "1.0.0", - "aria-hidden": "^1.1.1", - "react-remove-scroll": "2.5.4" - }, - "dependencies": { - "@radix-ui/react-primitive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.0.tgz", - "integrity": "sha512-EyXe6mnRlHZ8b6f4ilTDrXmkLShICIuOTTj0GX4w1rp+wSxf3+TD05u1UOITC8VsJ2a9nwHvdXtOXEOl0Cw/zQ==", - "requires": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-slot": "1.0.0" - } + "node_modules/@emotion/react": { + "version": "11.10.4", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.4.tgz", + "integrity": "sha512-j0AkMpr6BL8gldJZ6XQsQ8DnS9TxEQu1R+OGmDZiWjBAJtCcbt0tS3I/YffoqHXxH6MjgI7KdMbYKw3MEiU9eA==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.10.0", + "@emotion/cache": "^11.10.0", + "@emotion/serialize": "^1.1.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", + "@emotion/utils": "^1.2.0", + "@emotion/weak-memoize": "^0.3.0", + "hoist-non-react-statics": "^3.3.1" + }, + "peerDependencies": { + "@babel/core": "^7.0.0", + "react": ">=16.8.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@types/react": { + "optional": true + } + } }, - "@radix-ui/react-slot": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.0.tgz", - "integrity": "sha512-3mrKauI/tWXo1Ll+gN5dHcxDPdm/Df1ufcDLCecn+pnCIVcdWE7CujXo8QaXOWRJyZyQWWbpB8eFwHzWXlv5mQ==", - "requires": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.0" - } + "node_modules/@emotion/serialize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.0.tgz", + "integrity": "sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA==", + "dependencies": { + "@emotion/hash": "^0.9.0", + "@emotion/memoize": "^0.8.0", + "@emotion/unitless": "^0.8.0", + "@emotion/utils": "^1.2.0", + "csstype": "^3.0.2" + } }, - "react-remove-scroll": { - "version": "2.5.4", - "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.4.tgz", - "integrity": "sha512-xGVKJJr0SJGQVirVFAUZ2k1QLyO6m+2fy0l8Qawbp5Jgrv3DeLalrfMNBFSlmz5kriGGzsVBtGVnf4pTKIhhWA==", - "requires": { - "react-remove-scroll-bar": "^2.3.3", - "react-style-singleton": "^2.2.1", - "tslib": "^2.1.0", - "use-callback-ref": "^1.3.0", - "use-sidecar": "^1.1.2" - } - } - } - }, - "@radix-ui/react-direction": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.0.tgz", - "integrity": "sha512-2HV05lGUgYcA6xgLQ4BKPDmtL+QbIZYH5fCOTAOOcJ5O0QbWS3i9lKaurLzliYUDhORI2Qr3pyjhJh44lKA3rQ==", - "requires": { - "@babel/runtime": "^7.13.10" - } - }, - "@radix-ui/react-dismissable-layer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.0.tgz", - "integrity": "sha512-n7kDRfx+LB1zLueRDvZ1Pd0bxdJWDUZNQ/GWoxDn2prnuJKRdxsjulejX/ePkOsLi2tTm6P24mDqlMSgQpsT6g==", - "requires": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.0", - "@radix-ui/react-compose-refs": "1.0.0", - "@radix-ui/react-primitive": "1.0.0", - "@radix-ui/react-use-callback-ref": "1.0.0", - "@radix-ui/react-use-escape-keydown": "1.0.0" - }, - "dependencies": { - "@radix-ui/react-primitive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.0.tgz", - "integrity": "sha512-EyXe6mnRlHZ8b6f4ilTDrXmkLShICIuOTTj0GX4w1rp+wSxf3+TD05u1UOITC8VsJ2a9nwHvdXtOXEOl0Cw/zQ==", - "requires": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-slot": "1.0.0" - } + "node_modules/@emotion/serialize/node_modules/@emotion/unitless": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", + "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" }, - "@radix-ui/react-slot": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.0.tgz", - "integrity": "sha512-3mrKauI/tWXo1Ll+gN5dHcxDPdm/Df1ufcDLCecn+pnCIVcdWE7CujXo8QaXOWRJyZyQWWbpB8eFwHzWXlv5mQ==", - "requires": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.0" - } - } - } - }, - "@radix-ui/react-focus-guards": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.0.tgz", - "integrity": "sha512-UagjDk4ijOAnGu4WMUPj9ahi7/zJJqNZ9ZAiGPp7waUWJO0O1aWXi/udPphI0IUjvrhBsZJGSN66dR2dsueLWQ==", - "requires": { - "@babel/runtime": "^7.13.10" - } - }, - "@radix-ui/react-focus-scope": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.0.tgz", - "integrity": "sha512-C4SWtsULLGf/2L4oGeIHlvWQx7Rf+7cX/vKOAD2dXW0A1b5QXwi3wWeaEgW+wn+SEVrraMUk05vLU9fZZz5HbQ==", - "requires": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.0", - "@radix-ui/react-primitive": "1.0.0", - "@radix-ui/react-use-callback-ref": "1.0.0" - }, - "dependencies": { - "@radix-ui/react-primitive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.0.tgz", - "integrity": "sha512-EyXe6mnRlHZ8b6f4ilTDrXmkLShICIuOTTj0GX4w1rp+wSxf3+TD05u1UOITC8VsJ2a9nwHvdXtOXEOl0Cw/zQ==", - "requires": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-slot": "1.0.0" - } + "node_modules/@emotion/sheet": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.0.tgz", + "integrity": "sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w==" }, - "@radix-ui/react-slot": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.0.tgz", - "integrity": "sha512-3mrKauI/tWXo1Ll+gN5dHcxDPdm/Df1ufcDLCecn+pnCIVcdWE7CujXo8QaXOWRJyZyQWWbpB8eFwHzWXlv5mQ==", - "requires": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.0" - } - } - } - }, - "@radix-ui/react-id": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.0.tgz", - "integrity": "sha512-Q6iAB/U7Tq3NTolBBQbHTgclPmGWE3OlktGGqrClPozSw4vkQ1DfQAOtzgRPecKsMdJINE05iaoDUG8tRzCBjw==", - "requires": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-layout-effect": "1.0.0" - } - }, - "@radix-ui/react-portal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.0.tgz", - "integrity": "sha512-a8qyFO/Xb99d8wQdu4o7qnigNjTPG123uADNecz0eX4usnQEj7o+cG4ZX4zkqq98NYekT7UoEQIjxBNWIFuqTA==", - "requires": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-primitive": "1.0.0" - }, - "dependencies": { - "@radix-ui/react-primitive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.0.tgz", - "integrity": "sha512-EyXe6mnRlHZ8b6f4ilTDrXmkLShICIuOTTj0GX4w1rp+wSxf3+TD05u1UOITC8VsJ2a9nwHvdXtOXEOl0Cw/zQ==", - "requires": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-slot": "1.0.0" - } + "node_modules/@emotion/stylis": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", + "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" }, - "@radix-ui/react-slot": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.0.tgz", - "integrity": "sha512-3mrKauI/tWXo1Ll+gN5dHcxDPdm/Df1ufcDLCecn+pnCIVcdWE7CujXo8QaXOWRJyZyQWWbpB8eFwHzWXlv5mQ==", - "requires": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.0" - } - } - } - }, - "@radix-ui/react-presence": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.0.tgz", - "integrity": "sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w==", - "requires": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.0", - "@radix-ui/react-use-layout-effect": "1.0.0" - } - }, - "@radix-ui/react-primitive": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.1.tgz", - "integrity": "sha512-fHbmislWVkZaIdeF6GZxF0A/NH/3BjrGIYj+Ae6eTmTCr7EB0RQAAVEiqsXK6p3/JcRqVSBQoceZroj30Jj3XA==", - "requires": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-slot": "1.0.1" - } - }, - "@radix-ui/react-scroll-area": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.0.2.tgz", - "integrity": "sha512-k8VseTxI26kcKJaX0HPwkvlNBPTs56JRdYzcZ/vzrNUkDlvXBy8sMc7WvCpYzZkHgb+hd72VW9MqkqecGtuNgg==", - "requires": { - "@babel/runtime": "^7.13.10", - "@radix-ui/number": "1.0.0", - "@radix-ui/primitive": "1.0.0", - "@radix-ui/react-compose-refs": "1.0.0", - "@radix-ui/react-context": "1.0.0", - "@radix-ui/react-direction": "1.0.0", - "@radix-ui/react-presence": "1.0.0", - "@radix-ui/react-primitive": "1.0.1", - "@radix-ui/react-use-callback-ref": "1.0.0", - "@radix-ui/react-use-layout-effect": "1.0.0" - } - }, - "@radix-ui/react-slot": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.1.tgz", - "integrity": "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw==", - "requires": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.0" - } - }, - "@radix-ui/react-use-callback-ref": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz", - "integrity": "sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg==", - "requires": { - "@babel/runtime": "^7.13.10" - } - }, - "@radix-ui/react-use-controllable-state": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.0.tgz", - "integrity": "sha512-FohDoZvk3mEXh9AWAVyRTYR4Sq7/gavuofglmiXB2g1aKyboUD4YtgWxKj8O5n+Uak52gXQ4wKz5IFST4vtJHg==", - "requires": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-callback-ref": "1.0.0" - } - }, - "@radix-ui/react-use-escape-keydown": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.0.tgz", - "integrity": "sha512-JwfBCUIfhXRxKExgIqGa4CQsiMemo1Xt0W/B4ei3fpzpvPENKpMKQ8mZSB6Acj3ebrAEgi2xiQvcI1PAAodvyg==", - "requires": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-callback-ref": "1.0.0" - } - }, - "@radix-ui/react-use-layout-effect": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.0.tgz", - "integrity": "sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ==", - "requires": { - "@babel/runtime": "^7.13.10" - } - }, - "@remix-run/router": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.1.0.tgz", - "integrity": "sha512-rGl+jH/7x1KBCQScz9p54p0dtPLNeKGb3e0wD2H5/oZj41bwQUnXdzbj2TbUAFhvD7cp9EyEQA4dEgpUFa1O7Q==" - }, - "@sindresorhus/is": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", - "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", - "dev": 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": "8.1.0", - "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", - "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", - "dev": true, - "requires": { - "@sinonjs/commons": "^1.7.0" - } - }, - "@stylelint/postcss-css-in-js": { - "version": "0.38.0", - "resolved": "https://registry.npmjs.org/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.38.0.tgz", - "integrity": "sha512-XOz5CAe49kS95p5yRd+DAIWDojTjfmyAQ4bbDlXMdbZTQ5t0ThjSLvWI6JI2uiS7MFurVBkZ6zUqcimzcLTBoQ==", - "dev": true, - "requires": { - "@babel/core": "^7.17.9" - } - }, - "@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==", - "dev": true, - "requires": { - "defer-to-connect": "^2.0.0" - } - }, - "@tanstack/match-sorter-utils": { - "version": "8.7.2", - "resolved": "https://registry.npmjs.org/@tanstack/match-sorter-utils/-/match-sorter-utils-8.7.2.tgz", - "integrity": "sha512-bptNeoexeDB947fWoCPwUchPSx5FA9gwzU0bkXz0du5pT8Ud2+1ob+xOgHj6EF3VN0kdXtLhwjPyhY7/dJglkg==", - "requires": { - "remove-accents": "0.4.2" - } - }, - "@tanstack/query-core": { - "version": "4.29.5", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.29.5.tgz", - "integrity": "sha512-xXIiyQ/4r9KfaJ3k6kejqcaqFXXBTzN2aOJ5H1J6aTJE9hl/nbgAdfF6oiIu0CD5xowejJEJ6bBg8TO7BN4NuQ==" - }, - "@tanstack/react-query": { - "version": "4.29.5", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-4.29.5.tgz", - "integrity": "sha512-F87cibC3s3eG0Q90g2O+hqntpCrudKFnR8P24qkH9uccEhXErnJxBC/AAI4cJRV2bfMO8IeGZQYf3WyYgmSg0w==", - "requires": { - "@tanstack/query-core": "4.29.5", - "use-sync-external-store": "^1.2.0" - } - }, - "@tanstack/react-query-devtools": { - "version": "4.29.6", - "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-4.29.6.tgz", - "integrity": "sha512-qpYI41a69MWmrllcGiSE1KlpmnwJY/w0yKMnmp6VXn7nVy0i5TMMAT4u8D48F1Ipv/BKIDI1lqxPAvB4MqryBg==", - "requires": { - "@tanstack/match-sorter-utils": "^8.7.0", - "superjson": "^1.10.0", - "use-sync-external-store": "^1.2.0" - } - }, - "@teamsupercell/typings-for-css-modules-loader": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@teamsupercell/typings-for-css-modules-loader/-/typings-for-css-modules-loader-2.5.2.tgz", - "integrity": "sha512-3sqH2B4itcm5XgV1IHENt4NOaW7bOC1CwJr63vrdKWWyKVxNxtBM+ABVhJZYFCCVAwNy7ulA64z6HyQqw96m4A==", - "dev": true, - "requires": { - "camelcase": "^5.3.1", - "loader-utils": "^1.4.2", - "prettier": "*", - "schema-utils": "^2.0.1" - }, - "dependencies": { - "json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } + "node_modules/@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" }, - "loader-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", - "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - } + "node_modules/@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz", + "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==", + "peerDependencies": { + "react": ">=16.8.0" + } }, - "schema-utils": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", - "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.5", - "ajv": "^6.12.4", - "ajv-keywords": "^3.5.2" - } - } - } - }, - "@testing-library/dom": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.13.0.tgz", - "integrity": "sha512-9VHgfIatKNXQNaZTtLnalIy0jNZzY35a4S3oi08YAt9Hv1VsfZ/DfA45lM8D/UhtHBGJ4/lGwp0PZkVndRkoOQ==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.10.4", - "@babel/runtime": "^7.12.5", - "@types/aria-query": "^4.2.0", - "aria-query": "^5.0.0", - "chalk": "^4.1.0", - "dom-accessibility-api": "^0.5.9", - "lz-string": "^1.4.4", - "pretty-format": "^27.0.2" - } - }, - "@testing-library/jest-dom": { - "version": "5.16.4", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.4.tgz", - "integrity": "sha512-Gy+IoFutbMQcky0k+bqqumXZ1cTGswLsFqmNLzNdSKkU9KGV2u9oXhukCbbJ9/LRPKiqwxEE8VpV/+YZlfkPUA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.9.2", - "@types/testing-library__jest-dom": "^5.9.1", - "aria-query": "^5.0.0", - "chalk": "^3.0.0", - "css": "^3.0.0", - "css.escape": "^1.5.1", - "dom-accessibility-api": "^0.5.6", - "lodash": "^4.17.15", - "redent": "^3.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" - } - } - } - }, - "@testing-library/react": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-13.0.0.tgz", - "integrity": "sha512-p0lYA1M7uoEmk2LnCbZLGmHJHyH59sAaZVXChTXlyhV/PRW9LoIh4mdf7tiXsO8BoNG+vN8UnFJff1hbZeXv+w==", - "dev": true, - "requires": { - "@babel/runtime": "^7.12.5", - "@testing-library/dom": "^8.5.0", - "@types/react-dom": "*" - } - }, - "@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 - }, - "@trysound/sax": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", - "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", - "dev": true - }, - "@ts-rest/core": { - "version": "3.23.0", - "resolved": "https://registry.npmjs.org/@ts-rest/core/-/core-3.23.0.tgz", - "integrity": "sha512-2vJwa682m9yS/xQPvPxZBluJfIZwNkt2HY9ER3UtGnu8Dijw+8iymSyIyjRLpFFWUyRnVp9IqrEi/d84bkNFIw==", - "requires": {} - }, - "@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", - "dev": true - }, - "@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", - "dev": true - }, - "@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", - "dev": true - }, - "@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", - "dev": true - }, - "@types/aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==", - "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.14.2", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", - "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", - "dev": true, - "requires": { - "@babel/types": "^7.3.0" - } - }, - "@types/body-parser": { - "version": "1.19.2", - "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", - "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", - "dev": true, - "requires": { - "@types/connect": "*", - "@types/node": "*" - } - }, - "@types/bonjour": { - "version": "3.5.10", - "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz", - "integrity": "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/cacheable-request": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", - "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", - "dev": true, - "requires": { - "@types/http-cache-semantics": "*", - "@types/keyv": "*", - "@types/node": "*", - "@types/responselike": "*" - } - }, - "@types/connect": { - "version": "3.4.35", - "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", - "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/connect-history-api-fallback": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz", - "integrity": "sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==", - "dev": true, - "requires": { - "@types/express-serve-static-core": "*", - "@types/node": "*" - } - }, - "@types/debug": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", - "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", - "dev": true, - "requires": { - "@types/ms": "*" - } - }, - "@types/electron-localshortcut": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/@types/electron-localshortcut/-/electron-localshortcut-3.1.0.tgz", - "integrity": "sha512-upKSXMxBPRdz5kmcXfdfn+hWH9PCAvwhyVozDXTIwwHQ1lUJcdSgGUfxOC1QBlnAPKPqcW/r4icWfMosKz8ibg==", - "dev": true, - "requires": { - "electron": "*" - } - }, - "@types/eslint": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.2.tgz", - "integrity": "sha512-Z1nseZON+GEnFjJc04sv4NSALGjhFwy6K0HXt7qsn5ArfAKtb63dXNJHf+1YW6IpOIYRBGUbu3GwJdj8DGnCjA==", - "dev": true, - "requires": { - "@types/estree": "*", - "@types/json-schema": "*" - } - }, - "@types/eslint-scope": { - "version": "3.7.3", - "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz", - "integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==", - "dev": true, - "requires": { - "@types/eslint": "*", - "@types/estree": "*" - } - }, - "@types/estree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", - "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", - "dev": true - }, - "@types/express": { - "version": "4.17.13", - "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", - "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", - "dev": true, - "requires": { - "@types/body-parser": "*", - "@types/express-serve-static-core": "^4.17.18", - "@types/qs": "*", - "@types/serve-static": "*" - } - }, - "@types/express-serve-static-core": { - "version": "4.17.28", - "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", - "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/qs": "*", - "@types/range-parser": "*" - } - }, - "@types/fs-extra": { - "version": "9.0.13", - "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", - "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@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, - "requires": { - "@types/minimatch": "*", - "@types/node": "*" - } - }, - "@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/hoist-non-react-statics": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", - "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", - "dev": true, - "requires": { - "@types/react": "*", - "hoist-non-react-statics": "^3.3.0" - } - }, - "@types/html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", - "dev": true - }, - "@types/http-cache-semantics": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", - "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", - "dev": true - }, - "@types/http-proxy": { - "version": "1.17.8", - "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.8.tgz", - "integrity": "sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA==", - "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/jest": { - "version": "27.4.1", - "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", - "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", - "dev": true, - "requires": { - "jest-matcher-utils": "^27.0.0", - "pretty-format": "^27.0.0" - } - }, - "@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/json5": { - "version": "0.0.29", - "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", - "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", - "dev": true - }, - "@types/keyv": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", - "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/lodash": { - "version": "4.14.188", - "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.188.tgz", - "integrity": "sha512-zmEmF5OIM3rb7SbLCFYoQhO4dGt2FRM9AMkxvA3LaADOF1n8in/zGJlWji9fmafLoNyz+FoL6FE0SLtGIArD7w==", - "dev": true - }, - "@types/md5": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/@types/md5/-/md5-2.3.2.tgz", - "integrity": "sha512-v+JFDu96+UYJ3/UWzB0mEglIS//MZXgRaJ4ubUPwOM0gvLc/kcQ3TWNYwENEK7/EcXGQVrW8h/XqednSjBd/Og==", - "dev": true - }, - "@types/mime": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", - "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", - "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/ms": { - "version": "0.7.31", - "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", - "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==", - "dev": true - }, - "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==", - "dev": true - }, - "@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==" - }, - "@types/plist": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.2.tgz", - "integrity": "sha512-ULqvZNGMv0zRFvqn8/4LSPtnmN4MfhlPNtJCTpKuIIxGVGZ2rYWzFXrvEBoh9CVyqSE7D6YFRJ1hydLHI6kbWw==", - "dev": true, - "optional": true, - "requires": { - "@types/node": "*", - "xmlbuilder": ">=11.0.1" - } - }, - "@types/prettier": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.3.tgz", - "integrity": "sha512-ymZk3LEC/fsut+/Q5qejp6R9O1rMxz3XaRHDV6kX8MrGAhOSPqVARbDi+EZvInBpw+BnCX3TD240byVkOfQsHg==", - "dev": true - }, - "@types/prop-types": { - "version": "15.7.4", - "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", - "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==", - "devOptional": true - }, - "@types/qs": { - "version": "6.9.7", - "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", - "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", - "dev": true - }, - "@types/range-parser": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", - "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", - "dev": true - }, - "@types/react": { - "version": "18.0.26", - "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.26.tgz", - "integrity": "sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==", - "devOptional": true, - "requires": { - "@types/prop-types": "*", - "@types/scheduler": "*", - "csstype": "^3.0.2" - } - }, - "@types/react-dom": { - "version": "18.0.9", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.9.tgz", - "integrity": "sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==", - "dev": true, - "requires": { - "@types/react": "*" - } - }, - "@types/react-test-renderer": { - "version": "17.0.1", - "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-17.0.1.tgz", - "integrity": "sha512-3Fi2O6Zzq/f3QR9dRnlnHso9bMl7weKCviFmfF6B4LS1Uat6Hkm15k0ZAQuDz+UBq6B3+g+NM6IT2nr5QgPzCw==", - "dev": true, - "requires": { - "@types/react": "*" - } - }, - "@types/react-virtualized-auto-sizer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@types/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.1.tgz", - "integrity": "sha512-GH8sAnBEM5GV9LTeiz56r4ZhMOUSrP43tAQNSRVxNexDjcNKLCEtnxusAItg1owFUFE6k0NslV26gqVClVvong==", - "dev": true, - "requires": { - "@types/react": "*" - } - }, - "@types/react-window": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.5.tgz", - "integrity": "sha512-V9q3CvhC9Jk9bWBOysPGaWy/Z0lxYcTXLtLipkt2cnRj1JOSFNF7wqGpkScSXMgBwC+fnVRg/7shwgddBG5ICw==", - "dev": true, - "requires": { - "@types/react": "*" - } - }, - "@types/react-window-infinite-loader": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/@types/react-window-infinite-loader/-/react-window-infinite-loader-1.0.6.tgz", - "integrity": "sha512-V8g8sBDLVeJJAfEENJS7VXZK+DRJ+jzPNtk8jpj2G+obhf+iqGNUDGwNWCbBhLiD+KpHhf3kWQlKBRi0tAeU4Q==", - "dev": true, - "requires": { - "@types/react": "*", - "@types/react-window": "*" - } - }, - "@types/responselike": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", - "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/retry": { - "version": "0.12.1", - "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz", - "integrity": "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==", - "dev": true - }, - "@types/scheduler": { - "version": "0.16.2", - "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", - "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", - "devOptional": true - }, - "@types/semver": { - "version": "7.3.13", - "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", - "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==" - }, - "@types/serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==", - "dev": true, - "requires": { - "@types/express": "*" - } - }, - "@types/serve-static": { - "version": "1.13.10", - "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", - "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", - "dev": true, - "requires": { - "@types/mime": "^1", - "@types/node": "*" - } - }, - "@types/sockjs": { - "version": "0.3.33", - "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz", - "integrity": "sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@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/styled-components": { - "version": "5.1.26", - "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.26.tgz", - "integrity": "sha512-KuKJ9Z6xb93uJiIyxo/+ksS7yLjS1KzG6iv5i78dhVg/X3u5t1H7juRWqVmodIdz6wGVaIApo1u01kmFRdJHVw==", - "dev": true, - "requires": { - "@types/hoist-non-react-statics": "*", - "@types/react": "*", - "csstype": "^3.0.2" - } - }, - "@types/symlink-or-copy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@types/symlink-or-copy/-/symlink-or-copy-1.2.0.tgz", - "integrity": "sha512-Lja2xYuuf2B3knEsga8ShbOdsfNOtzT73GyJmZyY7eGl2+ajOqrs8yM5ze0fsSoYwvA6bw7/Qr7OZ7PEEmYwWg==", - "dev": true - }, - "@types/terser-webpack-plugin": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@types/terser-webpack-plugin/-/terser-webpack-plugin-5.2.0.tgz", - "integrity": "sha512-iHDR2pRfFjGyDqCALX2tgUgFtGoQf2AJhKpC2XD1IMBQVJF2bny6WChGRDKj9eaZJl4F2RmvBhxJNtVPj7aTRw==", - "dev": true, - "requires": { - "terser-webpack-plugin": "*" - } - }, - "@types/testing-library__jest-dom": { - "version": "5.14.3", - "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.3.tgz", - "integrity": "sha512-oKZe+Mf4ioWlMuzVBaXQ9WDnEm1+umLx0InILg+yvZVBBDmzV5KfZyLrCvadtWcx8+916jLmHafcmqqffl+iIw==", - "dev": true, - "requires": { - "@types/jest": "*" - } - }, - "@types/unist": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", - "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==", - "dev": true - }, - "@types/verror": { - "version": "1.10.6", - "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.6.tgz", - "integrity": "sha512-NNm+gdePAX1VGvPcGZCDKQZKYSiAWigKhKaz5KF94hG6f2s8de9Ow5+7AbXoeKxL8gavZfk4UquSAygOF2duEQ==", - "dev": true, - "optional": true - }, - "@types/vfile": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/vfile/-/vfile-3.0.2.tgz", - "integrity": "sha512-b3nLFGaGkJ9rzOcuXRfHkZMdjsawuDD0ENL9fzTophtBg8FJHSGbH7daXkEpcwy3v7Xol3pAvsmlYyFhR4pqJw==", - "dev": true, - "requires": { - "@types/node": "*", - "@types/unist": "*", - "@types/vfile-message": "*" - } - }, - "@types/vfile-message": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/vfile-message/-/vfile-message-2.0.0.tgz", - "integrity": "sha512-GpTIuDpb9u4zIO165fUy9+fXcULdD8HFRNli04GehoMVbeNq7D6OBnqSmg3lxZnC+UvgUhEWKxdKiwYUkGltIw==", - "dev": true, - "requires": { - "vfile-message": "*" - } - }, - "@types/webpack-bundle-analyzer": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/@types/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.4.1.tgz", - "integrity": "sha512-yQAj3l7bIYL+QRRlNJt6gyP+zrXZOlgaR4wsX0WY4yzZIbv41ZibREfZvuYjxY0iVtvQQlbhx0AeokkCuqUAQg==", - "dev": true, - "requires": { - "@types/node": "*", - "tapable": "^2.2.0", - "webpack": "^5" - } - }, - "@types/webpack-env": { - "version": "1.16.3", - "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.16.3.tgz", - "integrity": "sha512-9gtOPPkfyNoEqCQgx4qJKkuNm/x0R2hKR7fdl7zvTJyHnIisuE/LfvXOsYWL0o3qq6uiBnKZNNNzi3l0y/X+xw==", - "dev": true - }, - "@types/ws": { - "version": "8.5.3", - "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", - "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, - "@types/yargs": { - "version": "17.0.24", - "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", - "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", - "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 - }, - "@types/yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", - "dev": true, - "optional": true, - "requires": { - "@types/node": "*" - } - }, - "@typescript-eslint/eslint-plugin": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.47.1.tgz", - "integrity": "sha512-r4RZ2Jl9kcQN7K/dcOT+J7NAimbiis4sSM9spvWimsBvDegMhKLA5vri2jG19PmIPbDjPeWzfUPQ2hjEzA4Nmg==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "5.47.1", - "@typescript-eslint/type-utils": "5.47.1", - "@typescript-eslint/utils": "5.47.1", - "debug": "^4.3.4", - "ignore": "^5.2.0", - "natural-compare-lite": "^1.4.0", - "regexpp": "^3.2.0", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/experimental-utils": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", - "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, - "dependencies": { - "@typescript-eslint/scope-manager": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" - } + "node_modules/@emotion/utils": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz", + "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==" }, - "@typescript-eslint/types": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", - "dev": true + "node_modules/@emotion/weak-memoize": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz", + "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==" }, - "@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } + "node_modules/@eslint/eslintrc": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.0.tgz", + "integrity": "sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A==", + "dev": true, + "dependencies": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.19.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": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } }, - "@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" - } + "node_modules/@floating-ui/core": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.2.1.tgz", + "integrity": "sha512-LSqwPZkK3rYfD7GKoIeExXOyYx6Q1O4iqZWwIehDNuv3Dv425FIAE8PRwtAx1imEolFTHgBEcoFHm9MDnYgPCg==" }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true - } - } - }, - "@typescript-eslint/parser": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.47.1.tgz", - "integrity": "sha512-9Vb+KIv29r6GPu4EboWOnQM7T+UjpjXvjCPhNORlgm40a9Ia9bvaPJswvtae1gip2QEeVeGh6YquqAzEgoRAlw==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "5.47.1", - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/typescript-estree": "5.47.1", - "debug": "^4.3.4" - } - }, - "@typescript-eslint/scope-manager": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.1.tgz", - "integrity": "sha512-9hsFDsgUwrdOoW1D97Ewog7DYSHaq4WKuNs0LHF9RiCmqB0Z+XRR4Pf7u7u9z/8CciHuJ6yxNws1XznI3ddjEw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/visitor-keys": "5.47.1" - } - }, - "@typescript-eslint/type-utils": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.47.1.tgz", - "integrity": "sha512-/UKOeo8ee80A7/GJA427oIrBi/Gd4osk/3auBUg4Rn9EahFpevVV1mUK8hjyQD5lHPqX397x6CwOk5WGh1E/1w==", - "dev": true, - "requires": { - "@typescript-eslint/typescript-estree": "5.47.1", - "@typescript-eslint/utils": "5.47.1", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/types": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", - "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", - "dev": true - }, - "@typescript-eslint/typescript-estree": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.1.tgz", - "integrity": "sha512-4+ZhFSuISAvRi2xUszEj0xXbNTHceV9GbH9S8oAD2a/F9SW57aJNQVOCxG8GPfSWH/X4eOPdMEU2jYVuWKEpWA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/visitor-keys": "5.47.1", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } - }, - "@typescript-eslint/utils": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.47.1.tgz", - "integrity": "sha512-l90SdwqfmkuIVaREZ2ykEfCezepCLxzWMo5gVfcJsJCaT4jHT+QjgSkYhs5BMQmWqE9k3AtIfk4g211z/sTMVw==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.9", - "@types/semver": "^7.3.12", - "@typescript-eslint/scope-manager": "5.47.1", - "@typescript-eslint/types": "5.47.1", - "@typescript-eslint/typescript-estree": "5.47.1", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0", - "semver": "^7.3.7" - } - }, - "@typescript-eslint/visitor-keys": { - "version": "5.47.1", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", - "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.47.1", - "eslint-visitor-keys": "^3.3.0" - } - }, - "@webassemblyjs/ast": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", - "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", - "dev": true, - "requires": { - "@webassemblyjs/helper-numbers": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", - "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", - "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", - "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", - "dev": true - }, - "@webassemblyjs/helper-numbers": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", - "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", - "dev": true, - "requires": { - "@webassemblyjs/floating-point-hex-parser": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", - "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", - "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", - "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", - "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", - "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", - "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/helper-wasm-section": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-opt": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6", - "@webassemblyjs/wast-printer": "1.11.6" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", - "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", - "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-buffer": "1.11.6", - "@webassemblyjs/wasm-gen": "1.11.6", - "@webassemblyjs/wasm-parser": "1.11.6" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", - "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.6", - "@webassemblyjs/helper-api-error": "1.11.6", - "@webassemblyjs/helper-wasm-bytecode": "1.11.6", - "@webassemblyjs/ieee754": "1.11.6", - "@webassemblyjs/leb128": "1.11.6", - "@webassemblyjs/utf8": "1.11.6" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", - "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.11.6", - "@xtuc/long": "4.2.2" - } - }, - "@webpack-cli/configtest": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.1.tgz", - "integrity": "sha512-1FBc1f9G4P/AxMqIgfZgeOTuRnwZMten8E7zap5zgpPInnCrP8D4Q81+4CWIch8i/Nf7nXjP0v6CjjbHOrXhKg==", - "dev": true, - "requires": {} - }, - "@webpack-cli/info": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.4.1.tgz", - "integrity": "sha512-PKVGmazEq3oAo46Q63tpMr4HipI3OPfP7LiNOEJg963RMgT0rqheag28NCML0o3GIzA3DmxP1ZIAv9oTX1CUIA==", - "dev": true, - "requires": { - "envinfo": "^7.7.3" - } - }, - "@webpack-cli/serve": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.1.tgz", - "integrity": "sha512-gNGTiTrjEVQ0OcVnzsRSqTxaBSr+dmTfm+qJsCDluky8uhdLWep7Gcr62QsAKHTMxjCS/8nEITsmFAhfIx+QSw==", - "dev": true, - "requires": {} - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "7zip-bin": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.1.1.tgz", - "integrity": "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ==", - "dev": true - }, - "abab": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", - "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", - "dev": true - }, - "abbrev": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", - "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", - "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==", - "dev": true, - "requires": { - "mime-types": "~2.1.34", - "negotiator": "0.6.3" - } - }, - "acorn": { - "version": "8.8.2", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", - "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", - "dev": true - }, - "acorn-globals": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", - "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", - "dev": true, - "requires": { - "acorn": "^7.1.1", - "acorn-walk": "^7.1.1" - }, - "dependencies": { - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true - } - } - }, - "acorn-import-assertions": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", - "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", - "dev": true, - "requires": {} - }, - "acorn-jsx": { - "version": "5.3.2", - "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", - "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} - }, - "acorn-walk": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", - "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", - "dev": true - }, - "address": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", - "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", - "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" - } - }, - "agentkeepalive": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz", - "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "depd": "^1.1.2", - "humanize-ms": "^1.2.1" - } - }, - "aggregate-error": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", - "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", - "dev": true, - "requires": { - "clean-stack": "^2.0.0", - "indent-string": "^4.0.0" - } - }, - "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, - "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" - } - }, - "ajv-formats": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", - "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", - "requires": { - "ajv": "^8.0.0" - }, - "dependencies": { - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } + "node_modules/@floating-ui/dom": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.2.1.tgz", + "integrity": "sha512-Rt45SmRiV8eU+xXSB9t0uMYiQ/ZWGE/jumse2o3i5RGlyvcbqOF4q+1qBnzLE2kZ5JGhq0iMkcGXUKbFe7MpTA==", + "dependencies": { + "@floating-ui/core": "^1.2.1" + } }, - "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==" - } - } - }, - "ajv-keywords": { - "version": "3.5.2", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", - "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", - "dev": true, - "requires": {} - }, - "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-html-community": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", - "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", - "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==", - "dev": true - }, - "ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "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" - } - }, - "app-builder-bin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-4.0.0.tgz", - "integrity": "sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA==", - "dev": true - }, - "app-builder-lib": { - "version": "24.0.0-alpha.13", - "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-24.0.0-alpha.13.tgz", - "integrity": "sha512-fQa3zDl948PS+EvDaAtPTM3UvrXKns9TEQ7dR3BYWJbpIs7s0e1FxlwVLrINYGLv7hxdLkhbJ0ewPxKyj/ahpQ==", - "dev": true, - "requires": { - "@develar/schema-utils": "~2.6.5", - "@electron/notarize": "^1.2.3", - "@electron/osx-sign": "^1.0.4", - "@electron/rebuild": "^3.2.10", - "@electron/universal": "1.3.4", - "@malept/flatpak-bundler": "^0.4.0", - "7zip-bin": "~5.1.1", - "async-exit-hook": "^2.0.1", - "bluebird-lst": "^1.0.9", - "builder-util": "24.0.0-alpha.13", - "builder-util-runtime": "9.2.0-alpha.3", - "chromium-pickle-js": "^0.2.0", - "debug": "^4.3.4", - "ejs": "^3.1.8", - "electron-publish": "24.0.0-alpha.13", - "form-data": "^4.0.0", - "fs-extra": "^10.1.0", - "hosted-git-info": "^4.1.0", - "is-ci": "^3.0.0", - "isbinaryfile": "^5.0.0", - "js-yaml": "^4.1.0", - "lazy-val": "^1.0.5", - "minimatch": "^5.1.1", - "read-config-file": "6.3.2", - "sanitize-filename": "^1.6.3", - "semver": "^7.3.8", - "tar": "^6.1.12", - "temp-file": "^3.4.0" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } + "node_modules/@floating-ui/react": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.19.2.tgz", + "integrity": "sha512-JyNk4A0Ezirq8FlXECvRtQOX/iBe5Ize0W/pLkrZjfHW9GUV7Xnq6zm6fyZuQzaHHqEnVizmvlA96e1/CkZv+w==", + "dependencies": { + "@floating-ui/react-dom": "^1.3.0", + "aria-hidden": "^1.1.3", + "tabbable": "^6.0.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } }, - "builder-util-runtime": { - "version": "9.2.0-alpha.3", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.0-alpha.3.tgz", - "integrity": "sha512-1pOggEqknxVyhdASumips0/RaMaXwSCQMzwhk2jeOGOotBQuOHQHVy25kH5OaeXSFx9L7PckZHXjwZauD72zRw==", - "dev": true, - "requires": { - "debug": "^4.3.4", - "sax": "^1.2.4" - } + "node_modules/@floating-ui/react-dom": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-1.3.0.tgz", + "integrity": "sha512-htwHm67Ji5E/pROEAr7f8IKFShuiCKHwUC/UY4vC3I5jiSvGFAYnSYiZO5MlGmads+QqvUkR9ANHEguGrDv72g==", + "dependencies": { + "@floating-ui/dom": "^1.2.1" + }, + "peerDependencies": { + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } }, - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } + "node_modules/@gar/promisify": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "dev": true }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } + "node_modules/@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "dev": true, + "dependencies": { + "@humanwhocodes/object-schema": "^1.2.1", + "debug": "^4.1.1", + "minimatch": "^3.0.5" + }, + "engines": { + "node": ">=10.10.0" + } }, - "minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } + "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==", + "dev": true, + "engines": { + "node": ">=12.22" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/nzakas" + } }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } - } - }, - "append-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", - "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", - "dev": true, - "requires": { - "buffer-equal": "^1.0.0" - } - }, - "aproba": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", - "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", - "dev": true - }, - "are-we-there-yet": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz", - "integrity": "sha512-0GWpv50YSOcLXaN6/FAKY3vfRbllXWV2xvfA/oKJF8pzFhWXPV+yjhJXDBbjscDYowv7Yw1A3uigpzn5iEGTyw==", - "dev": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "argparse": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", - "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" - }, - "aria-hidden": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.2.tgz", - "integrity": "sha512-6y/ogyDTk/7YAe91T3E2PR1ALVKyM2QbTio5HwM+N1Q6CMlCKhvClyIjkckBswa0f2xJhjsfzIGa1yVSe1UMVA==", - "requires": { - "tslib": "^2.0.0" - } - }, - "aria-query": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.0.0.tgz", - "integrity": "sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg==", - "dev": true - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", - "dev": true - }, - "array-find": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/array-find/-/array-find-1.0.0.tgz", - "integrity": "sha1-bI4obRHtdoMn+OYuzuhzU8o+eLg=", - "dev": true - }, - "array-find-index": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", - "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", - "dev": true - }, - "array-flatten": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", - "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", - "dev": true - }, - "array-includes": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", - "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", - "is-string": "^1.0.7" - } - }, - "array-union": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", - "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", - "dev": true - }, - "array-uniq": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", - "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", - "dev": true - }, - "array.prototype.flat": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", - "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.2", - "es-shim-unscopables": "^1.0.0" - } - }, - "array.prototype.flatmap": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", - "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0" - } - }, - "array.prototype.tosorted": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz", - "integrity": "sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "es-shim-unscopables": "^1.0.0", - "get-intrinsic": "^1.1.3" - } - }, - "arrify": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", - "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", - "dev": true - }, - "assert-plus": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", - "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", - "dev": true, - "optional": true - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", - "dev": true - }, - "ast-metadata-inferer": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.7.0.tgz", - "integrity": "sha512-OkMLzd8xelb3gmnp6ToFvvsHLtS6CbagTkFQvQ+ZYFe3/AIl9iKikNR9G7pY3GfOR/2Xc222hwBjzI7HLkE76Q==", - "dev": true, - "requires": { - "@mdn/browser-compat-data": "^3.3.14" - }, - "dependencies": { - "@mdn/browser-compat-data": { - "version": "3.3.14", - "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-3.3.14.tgz", - "integrity": "sha512-n2RC9d6XatVbWFdHLimzzUJxJ1KY8LdjqrW6YvGPiRmsHkhOUx74/Ct10x5Yo7bC/Jvqx7cDEW8IMPv/+vwEzA==", - "dev": true - } - } - }, - "ast-types-flow": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", - "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", - "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 - }, - "async": { - "version": "3.2.4", - "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", - "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", - "dev": true - }, - "async-exit-hook": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", - "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", - "dev": true - }, - "asynckit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", - "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" - }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "atomically": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz", - "integrity": "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==" - }, - "autoprefixer": { - "version": "9.8.8", - "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz", - "integrity": "sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==", - "dev": true, - "requires": { - "browserslist": "^4.12.0", - "caniuse-lite": "^1.0.30001109", - "normalize-range": "^0.1.2", - "num2fraction": "^1.2.2", - "picocolors": "^0.2.1", - "postcss": "^7.0.32", - "postcss-value-parser": "^4.1.0" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true + "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==", + "dev": true }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } + "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, + "dependencies": { + "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" + }, + "engines": { + "node": ">=8" + } }, - "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 - } - } - }, - "axe-core": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.6.1.tgz", - "integrity": "sha512-lCZN5XRuOnpG4bpMq8v0khrWtUOn+i8lZSb6wHZH56ZfbIEv6XwJV84AAueh9/zi7qPVJ/E4yz6fmsiyOmXR4w==", - "dev": true - }, - "axios": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", - "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", - "requires": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, - "axobject-query": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", - "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", - "dev": true - }, - "babel-jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", - "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", - "dev": true, - "requires": { - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__core": "^7.1.14", - "babel-plugin-istanbul": "^6.1.1", - "babel-preset-jest": "^27.5.1", - "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": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", - "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", - "dev": true, - "requires": { - "@babel/template": "^7.3.3", - "@babel/types": "^7.3.3", - "@types/babel__core": "^7.0.0", - "@types/babel__traverse": "^7.0.6" - } - }, - "babel-plugin-macros": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", - "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", - "requires": { - "@babel/runtime": "^7.12.5", - "cosmiconfig": "^7.0.0", - "resolve": "^1.19.0" - } - }, - "babel-plugin-styled-components": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.7.tgz", - "integrity": "sha512-i7YhvPgVqRKfoQ66toiZ06jPNA3p6ierpfUuEWxNF+fV27Uv5gxBkf8KZLHUCc1nFA9j6+80pYoIpqCeyW3/bA==", - "requires": { - "@babel/helper-annotate-as-pure": "^7.16.0", - "@babel/helper-module-imports": "^7.16.0", - "babel-plugin-syntax-jsx": "^6.18.0", - "lodash": "^4.17.11", - "picomatch": "^2.3.0" - } - }, - "babel-plugin-syntax-jsx": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", - "integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==" - }, - "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": "27.5.1", - "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", - "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", - "dev": true, - "requires": { - "babel-plugin-jest-hoist": "^27.5.1", - "babel-preset-current-node-syntax": "^1.0.0" - } - }, - "bail": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", - "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", - "dev": true - }, - "balanced-match": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", - "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "dev": true - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - } - } - }, - "base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "dev": true - }, - "batch": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", - "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", - "dev": true - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", - "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", - "dev": true - }, - "bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "dev": true, - "requires": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "bluebird": { - "version": "3.7.2", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", - "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", - "dev": true - }, - "bluebird-lst": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.9.tgz", - "integrity": "sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw==", - "dev": true, - "requires": { - "bluebird": "^3.5.5" - } - }, - "body-parser": { - "version": "1.20.0", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", - "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", - "dev": true, - "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.10.3", - "raw-body": "2.5.1", - "type-is": "~1.6.18", - "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true + "node_modules/@istanbuljs/load-nyc-config/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } + "node_modules/@istanbuljs/load-nyc-config/node_modules/find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true + "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } + "node_modules/@istanbuljs/load-nyc-config/node_modules/locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "bonjour-service": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.0.11.tgz", - "integrity": "sha512-drMprzr2rDTCtgEE3VgdA9uUFaUHF+jXduwYSThHJnKMYM+FhI9Z3ph+TX3xy0LtgYHae6CHYPJ/2UnK8nQHcA==", - "dev": true, - "requires": { - "array-flatten": "^2.1.2", - "dns-equal": "^1.0.0", - "fast-deep-equal": "^3.1.3", - "multicast-dns": "^7.2.4" - } - }, - "boolbase": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", - "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", - "dev": true - }, - "boolean": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", - "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", - "dev": true, - "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==", - "dev": true, - "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" - } - }, - "broccoli-node-api": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/broccoli-node-api/-/broccoli-node-api-1.7.0.tgz", - "integrity": "sha512-QIqLSVJWJUVOhclmkmypJJH9u9s/aWH4+FH6Q6Ju5l+Io4dtwqdPUNmDfw40o6sxhbZHhqGujDJuHTML1wG8Yw==", - "dev": true - }, - "broccoli-node-info": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/broccoli-node-info/-/broccoli-node-info-2.2.0.tgz", - "integrity": "sha512-VabSGRpKIzpmC+r+tJueCE5h8k6vON7EIMMWu6d/FyPdtijwLQ7QvzShEw+m3mHoDzUaj/kiZsDYrS8X2adsBg==", - "dev": true - }, - "broccoli-output-wrapper": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/broccoli-output-wrapper/-/broccoli-output-wrapper-3.2.5.tgz", - "integrity": "sha512-bQAtwjSrF4Nu0CK0JOy5OZqw9t5U0zzv2555EA/cF8/a8SLDTIetk9UgrtMVw7qKLKdSpOZ2liZNeZZDaKgayw==", - "dev": true, - "requires": { - "fs-extra": "^8.1.0", - "heimdalljs-logger": "^0.1.10", - "symlink-or-copy": "^1.2.0" - } - }, - "broccoli-plugin": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/broccoli-plugin/-/broccoli-plugin-4.0.7.tgz", - "integrity": "sha512-a4zUsWtA1uns1K7p9rExYVYG99rdKeGRymW0qOCNkvDPHQxVi3yVyJHhQbM3EZwdt2E0mnhr5e0c/bPpJ7p3Wg==", - "dev": true, - "requires": { - "broccoli-node-api": "^1.7.0", - "broccoli-output-wrapper": "^3.2.5", - "fs-merger": "^3.2.1", - "promise-map-series": "^0.3.0", - "quick-temp": "^0.1.8", - "rimraf": "^3.0.2", - "symlink-or-copy": "^1.3.1" - } - }, - "browser-process-hrtime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", - "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", - "dev": true - }, - "browserslist": { - "version": "4.21.4", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", - "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", - "requires": { - "caniuse-lite": "^1.0.30001400", - "electron-to-chromium": "^1.4.251", - "node-releases": "^2.0.6", - "update-browserslist-db": "^1.0.9" - } - }, - "browserslist-config-erb": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/browserslist-config-erb/-/browserslist-config-erb-0.0.3.tgz", - "integrity": "sha512-y47DryCY92lxkKyRVMlaZvXAolIY7U33q9e4CS0MdWeJkoAht7OzsrkfdZFCBOP3H5q1EVUxS0L7VVsKM6gZCQ==", - "dev": true, - "requires": {} - }, - "bs-logger": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", - "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", - "dev": true, - "requires": { - "fast-json-stable-stringify": "2.x" - } - }, - "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": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "dev": true, - "requires": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, - "buffer-crc32": { - "version": "0.2.13", - "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", - "dev": true - }, - "buffer-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", - "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", - "dev": 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==", - "dev": true - }, - "builder-util": { - "version": "24.0.0-alpha.13", - "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-24.0.0-alpha.13.tgz", - "integrity": "sha512-S8u+ETQ9GV4hJdrxJgVh2V0Cp14WiTrXRy7NsRSlM+DXaNtCIO3VNJSlEg4Btn1cJLUhfo1Fse8FIryV3gRj0Q==", - "dev": true, - "requires": { - "@types/debug": "^4.1.6", - "@types/fs-extra": "^9.0.11", - "7zip-bin": "~5.1.1", - "app-builder-bin": "4.0.0", - "bluebird-lst": "^1.0.9", - "builder-util-runtime": "9.2.0-alpha.3", - "chalk": "^4.1.2", - "cross-spawn": "^7.0.3", - "debug": "^4.3.4", - "fs-extra": "^10.1.0", - "http-proxy-agent": "^5.0.0", - "https-proxy-agent": "^5.0.1", - "is-ci": "^3.0.0", - "js-yaml": "^4.1.0", - "source-map-support": "^0.5.19", - "stat-mode": "^1.0.0", - "temp-file": "^3.4.0" - }, - "dependencies": { - "builder-util-runtime": { - "version": "9.2.0-alpha.3", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.0-alpha.3.tgz", - "integrity": "sha512-1pOggEqknxVyhdASumips0/RaMaXwSCQMzwhk2jeOGOotBQuOHQHVy25kH5OaeXSFx9L7PckZHXjwZauD72zRw==", - "dev": true, - "requires": { - "debug": "^4.3.4", - "sax": "^1.2.4" - } + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } + "node_modules/@istanbuljs/load-nyc-config/node_modules/p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } + "node_modules/@istanbuljs/load-nyc-config/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } - } - }, - "builder-util-runtime": { - "version": "8.9.2", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.9.2.tgz", - "integrity": "sha512-rhuKm5vh7E0aAmT6i8aoSfEjxzdYEFX7zDApK+eNgOhjofnWb74d9SRJv0H/8nsgOkos0TZ4zxW0P8J4N7xQ2A==", - "requires": { - "debug": "^4.3.2", - "sax": "^1.2.4" - } - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "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==", - "dev": true - }, - "cacheable-request": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", - "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", - "dev": true, - "requires": { - "clone-response": "^1.0.2", - "get-stream": "^5.1.0", - "http-cache-semantics": "^4.0.0", - "keyv": "^4.0.0", - "lowercase-keys": "^2.0.0", - "normalize-url": "^6.0.1", - "responselike": "^2.0.0" - } - }, - "call-bind": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", - "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "get-intrinsic": "^1.0.2" - } - }, - "call-me-maybe": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", - "integrity": "sha512-wCyFsDQkKPwwF8BDwOiWNx/9K45L/hvggQiDbve+viMNMQnWhrlYIuBk09offfwCRtCO9P6XwUttufzU11WCVw==", - "dev": true - }, - "caller-callsite": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", - "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", - "dev": true, - "requires": { - "callsites": "^2.0.0" - }, - "dependencies": { - "callsites": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", - "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", - "dev": true - } - } - }, - "caller-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", - "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", - "dev": true, - "requires": { - "caller-callsite": "^2.0.0" - } - }, - "callsites": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", - "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" - }, - "camel-case": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", - "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", - "dev": true, - "requires": { - "pascal-case": "^3.1.2", - "tslib": "^2.0.3" - } - }, - "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" - }, - "dependencies": { - "quick-lru": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", - "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", - "dev": true - } - } - }, - "camelize": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", - "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==" - }, - "caniuse-api": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", - "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", - "dev": true, - "requires": { - "browserslist": "^4.0.0", - "caniuse-lite": "^1.0.0", - "lodash.memoize": "^4.1.2", - "lodash.uniq": "^4.5.0" - } - }, - "caniuse-lite": { - "version": "1.0.30001439", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz", - "integrity": "sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A==" - }, - "ccount": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", - "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==", - "dev": true - }, - "chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "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 - }, - "character-entities": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", - "dev": true - }, - "character-entities-html4": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz", - "integrity": "sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g==", - "dev": true - }, - "character-entities-legacy": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", - "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", - "dev": true - }, - "character-reference-invalid": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", - "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", - "dev": true - }, - "charenc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", - "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" - }, - "cheerio": { - "version": "1.0.0-rc.10", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz", - "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==", - "dev": true, - "requires": { - "cheerio-select": "^1.5.0", - "dom-serializer": "^1.3.2", - "domhandler": "^4.2.0", - "htmlparser2": "^6.1.0", - "parse5": "^6.0.1", - "parse5-htmlparser2-tree-adapter": "^6.0.1", - "tslib": "^2.2.0" - } - }, - "cheerio-select": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.6.0.tgz", - "integrity": "sha512-eq0GdBvxVFbqWgmCm7M3XGs1I8oLy/nExUnh6oLqmBditPO9AqQJrkslDpMun/hZ0yyTs8L0m85OHp4ho6Qm9g==", - "dev": true, - "requires": { - "css-select": "^4.3.0", - "css-what": "^6.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.3.1", - "domutils": "^2.8.0" - } - }, - "chokidar": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", - "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", - "dev": true, - "requires": { - "anymatch": "~3.1.2", - "braces": "~3.0.2", - "fsevents": "~2.3.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" - }, - "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" - } - } - } - }, - "chownr": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", - "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", - "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", - "dev": true - }, - "chromium-pickle-js": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", - "integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==", - "dev": true - }, - "ci-info": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", - "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", - "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 - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } + "node_modules/@istanbuljs/load-nyc-config/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { + "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, + "engines": { + "node": ">=8" + } + }, + "node_modules/@jest/console": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", + "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/core": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", + "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", + "dev": true, + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/reporters": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^27.5.1", + "jest-config": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-resolve-dependencies": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "jest-watcher": "^27.5.1", + "micromatch": "^4.0.4", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/environment": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", + "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", + "dev": true, + "dependencies": { + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/fake-timers": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", + "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/globals": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", + "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/types": "^27.5.1", + "expect": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/reporters": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", + "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", + "dev": true, + "dependencies": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "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-haste-map": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.1.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/@jest/reporters/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/source-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", + "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", + "dev": true, + "dependencies": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9", + "source-map": "^0.6.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/source-map/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/test-result": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", + "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", + "dev": true, + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/test-sequencer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", + "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", + "dev": true, + "dependencies": { + "@jest/test-result": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-runtime": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", + "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", + "dev": true, + "dependencies": { + "@babel/core": "^7.1.0", + "@jest/types": "^27.5.1", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-util": "^27.5.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/transform/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/types/node_modules/@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, + "node_modules/@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==", + "dependencies": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + }, + "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==", + "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==", + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/@jridgewell/source-map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", + "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", + "dev": true, + "dependencies": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "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==" + }, + "node_modules/@jridgewell/trace-mapping": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "dependencies": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "node_modules/@leichtgewicht/ip-codec": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz", + "integrity": "sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg==", + "dev": true + }, + "node_modules/@malept/cross-spawn-promise": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", + "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/malept" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/subscription/pkg/npm-.malept-cross-spawn-promise?utm_medium=referral&utm_source=npm_fund" + } + ], + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@malept/flatpak-bundler": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz", + "integrity": "sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "fs-extra": "^9.0.0", + "lodash": "^4.17.15", + "tmp-promise": "^3.0.2" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@malept/flatpak-bundler/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@malept/flatpak-bundler/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/@malept/flatpak-bundler/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/@mantine/core": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@mantine/core/-/core-6.0.13.tgz", + "integrity": "sha512-FjVUGgat2qISV9WD1maVJa81y7H0JjKJ3m0cJj65PzgrXT20hzdEda7S3i4j+a8vUnx+836x5q/yS+RDHvoSlA==", + "dependencies": { + "@floating-ui/react": "^0.19.1", + "@mantine/styles": "6.0.13", + "@mantine/utils": "6.0.13", + "@radix-ui/react-scroll-area": "1.0.2", + "react-remove-scroll": "^2.5.5", + "react-textarea-autosize": "8.3.4" + }, + "peerDependencies": { + "@mantine/hooks": "6.0.13", + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@mantine/dates": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@mantine/dates/-/dates-6.0.13.tgz", + "integrity": "sha512-sWStU+sgblTZAfuuFlwG3w3WCFYHVf1L+sG2WdlXOljd9WpQVem214HTh6staJ894+vIQESIvseWvq6FDyQAaQ==", + "dependencies": { + "@mantine/utils": "6.0.13" + }, + "peerDependencies": { + "@mantine/core": "6.0.13", + "@mantine/hooks": "6.0.13", + "dayjs": ">=1.0.0", + "react": ">=16.8.0" + } + }, + "node_modules/@mantine/form": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@mantine/form/-/form-6.0.13.tgz", + "integrity": "sha512-oR/bnnJEd6T42N5pUhXYZ5RaKC4EZozEFW2jHCWDKIAJDjIgGUQrLL/tCjclQ2NwtghaoCTz+9zu32CuXer7TA==", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "klona": "^2.0.5" + }, + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@mantine/hooks": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-6.0.13.tgz", + "integrity": "sha512-fHuE3zXo5OP/Q1dMOTnegU6U+tI9GuhO2tgOz6szVuOxrrk0Hzuq1Na9NUSv27HShSRbAfQk+hvyIh+iVV7KXA==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@mantine/modals": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@mantine/modals/-/modals-6.0.13.tgz", + "integrity": "sha512-R/FfH+vzk1iKxl/HDgUC0CXZI7zvQ79J+VUSw9eQcNWgSTx9IwrDbFeEtWC2SvVNaCYmMSxgadCbgjKsaeqzWA==", + "dependencies": { + "@mantine/utils": "6.0.13" + }, + "peerDependencies": { + "@mantine/core": "6.0.13", + "@mantine/hooks": "6.0.13", + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@mantine/notifications": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@mantine/notifications/-/notifications-6.0.13.tgz", + "integrity": "sha512-d3BxNN7LEblvAsui0yGiI1q1Ji2OlhFLfe/cLdj7s5VMOtiKYRV14dICJxe4Jn/o+8Gg+UKw+aO/ZiQoT+BGIw==", + "dependencies": { + "@mantine/utils": "6.0.13", + "react-transition-group": "4.4.2" + }, + "peerDependencies": { + "@mantine/core": "6.0.13", + "@mantine/hooks": "6.0.13", + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@mantine/styles": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@mantine/styles/-/styles-6.0.13.tgz", + "integrity": "sha512-+27oX8ObiBv8jHHDxXKjqe+7cfTJyaAV/Ie00T49EE4LuHuS6nL4vlXHmqamFtDCj2ypEWBV0sdXDev/DNAXSg==", + "dependencies": { + "clsx": "1.1.1", + "csstype": "3.0.9" + }, + "peerDependencies": { + "@emotion/react": ">=11.9.0", + "react": ">=16.8.0", + "react-dom": ">=16.8.0" + } + }, + "node_modules/@mantine/styles/node_modules/csstype": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.9.tgz", + "integrity": "sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw==" + }, + "node_modules/@mantine/utils": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@mantine/utils/-/utils-6.0.13.tgz", + "integrity": "sha512-iqIU9wurqAeccVbWjM0yr1JGne5VP+ob55M03QAXOEN4+ck93VDTjCkZJR2RFhDcs5q0twQFoOmU/gULR8aKIA==", + "peerDependencies": { + "react": ">=16.8.0" + } + }, + "node_modules/@mdn/browser-compat-data": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-4.1.15.tgz", + "integrity": "sha512-OZx2PxHtJDc9NOHGR3T0ZtX1WYl5qH/xmiH3sKSmcd3o+vPMG1kVUYbZrMxH3fVKpkkkrQpwETCIDRXcMXAWTw==", + "dev": true + }, + "node_modules/@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "dev": true, + "dependencies": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@mrmlnc/readdir-enhanced/node_modules/glob-to-regexp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", + "integrity": "sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "@nodelib/fs.stat": "2.0.5", + "run-parallel": "^1.1.9" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@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==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@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==", + "dev": true, + "dependencies": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@pmmmwh/react-refresh-webpack-plugin": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.5.tgz", + "integrity": "sha512-RbG7h6TuP6nFFYKJwbcToA1rjC1FyPg25NR2noAZ0vKI+la01KTSRPkuVPE+U88jXv7javx2JHglUcL1MHcshQ==", + "dev": true, + "dependencies": { + "ansi-html-community": "^0.0.8", + "common-path-prefix": "^3.0.0", + "core-js-pure": "^3.8.1", + "error-stack-parser": "^2.0.6", + "find-up": "^5.0.0", + "html-entities": "^2.1.0", + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">= 10.13" + }, + "peerDependencies": { + "@types/webpack": "4.x || 5.x", + "react-refresh": ">=0.10.0 <1.0.0", + "sockjs-client": "^1.4.0", + "type-fest": ">=0.17.0 <3.0.0", + "webpack": ">=4.43.0 <6.0.0", + "webpack-dev-server": "3.x || 4.x", + "webpack-hot-middleware": "2.x", + "webpack-plugin-serve": "0.x || 1.x" + }, + "peerDependenciesMeta": { + "@types/webpack": { + "optional": true + }, + "sockjs-client": { + "optional": true + }, + "type-fest": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + }, + "webpack-hot-middleware": { + "optional": true + }, + "webpack-plugin-serve": { + "optional": true + } + } + }, + "node_modules/@polka/url": { + "version": "1.0.0-next.21", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", + "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==", + "dev": true + }, + "node_modules/@radix-ui/number": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.0.tgz", + "integrity": "sha512-Ofwh/1HX69ZfJRiRBMTy7rgjAzHmwe4kW9C9Y99HTRUcYLUuVT0KESFj15rPjRgKJs20GPq8Bm5aEDJ8DuA3vA==", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@radix-ui/primitive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.0.tgz", + "integrity": "sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@radix-ui/react-compose-refs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz", + "integrity": "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-context": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.0.tgz", + "integrity": "sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-dialog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.0.tgz", + "integrity": "sha512-Yn9YU+QlHYLWwV1XfKiqnGVpWYWk6MeBVM6x/bcoyPvxgjQGoeT35482viLPctTMWoMw0PoHgqfSox7Ig+957Q==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-dismissable-layer": "1.0.0", + "@radix-ui/react-focus-guards": "1.0.0", + "@radix-ui/react-focus-scope": "1.0.0", + "@radix-ui/react-id": "1.0.0", + "@radix-ui/react-portal": "1.0.0", + "@radix-ui/react-presence": "1.0.0", + "@radix-ui/react-primitive": "1.0.0", + "@radix-ui/react-slot": "1.0.0", + "@radix-ui/react-use-controllable-state": "1.0.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.4" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-primitive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.0.tgz", + "integrity": "sha512-EyXe6mnRlHZ8b6f4ilTDrXmkLShICIuOTTj0GX4w1rp+wSxf3+TD05u1UOITC8VsJ2a9nwHvdXtOXEOl0Cw/zQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-dialog/node_modules/@radix-ui/react-slot": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.0.tgz", + "integrity": "sha512-3mrKauI/tWXo1Ll+gN5dHcxDPdm/Df1ufcDLCecn+pnCIVcdWE7CujXo8QaXOWRJyZyQWWbpB8eFwHzWXlv5mQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-dialog/node_modules/react-remove-scroll": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.4.tgz", + "integrity": "sha512-xGVKJJr0SJGQVirVFAUZ2k1QLyO6m+2fy0l8Qawbp5Jgrv3DeLalrfMNBFSlmz5kriGGzsVBtGVnf4pTKIhhWA==", + "dependencies": { + "react-remove-scroll-bar": "^2.3.3", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-direction": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.0.tgz", + "integrity": "sha512-2HV05lGUgYcA6xgLQ4BKPDmtL+QbIZYH5fCOTAOOcJ5O0QbWS3i9lKaurLzliYUDhORI2Qr3pyjhJh44lKA3rQ==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.0.tgz", + "integrity": "sha512-n7kDRfx+LB1zLueRDvZ1Pd0bxdJWDUZNQ/GWoxDn2prnuJKRdxsjulejX/ePkOsLi2tTm6P24mDqlMSgQpsT6g==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-primitive": "1.0.0", + "@radix-ui/react-use-callback-ref": "1.0.0", + "@radix-ui/react-use-escape-keydown": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-dismissable-layer/node_modules/@radix-ui/react-primitive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.0.tgz", + "integrity": "sha512-EyXe6mnRlHZ8b6f4ilTDrXmkLShICIuOTTj0GX4w1rp+wSxf3+TD05u1UOITC8VsJ2a9nwHvdXtOXEOl0Cw/zQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-dismissable-layer/node_modules/@radix-ui/react-slot": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.0.tgz", + "integrity": "sha512-3mrKauI/tWXo1Ll+gN5dHcxDPdm/Df1ufcDLCecn+pnCIVcdWE7CujXo8QaXOWRJyZyQWWbpB8eFwHzWXlv5mQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-focus-guards": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.0.tgz", + "integrity": "sha512-UagjDk4ijOAnGu4WMUPj9ahi7/zJJqNZ9ZAiGPp7waUWJO0O1aWXi/udPphI0IUjvrhBsZJGSN66dR2dsueLWQ==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-focus-scope": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.0.tgz", + "integrity": "sha512-C4SWtsULLGf/2L4oGeIHlvWQx7Rf+7cX/vKOAD2dXW0A1b5QXwi3wWeaEgW+wn+SEVrraMUk05vLU9fZZz5HbQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-primitive": "1.0.0", + "@radix-ui/react-use-callback-ref": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-focus-scope/node_modules/@radix-ui/react-primitive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.0.tgz", + "integrity": "sha512-EyXe6mnRlHZ8b6f4ilTDrXmkLShICIuOTTj0GX4w1rp+wSxf3+TD05u1UOITC8VsJ2a9nwHvdXtOXEOl0Cw/zQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-focus-scope/node_modules/@radix-ui/react-slot": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.0.tgz", + "integrity": "sha512-3mrKauI/tWXo1Ll+gN5dHcxDPdm/Df1ufcDLCecn+pnCIVcdWE7CujXo8QaXOWRJyZyQWWbpB8eFwHzWXlv5mQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.0.tgz", + "integrity": "sha512-Q6iAB/U7Tq3NTolBBQbHTgclPmGWE3OlktGGqrClPozSw4vkQ1DfQAOtzgRPecKsMdJINE05iaoDUG8tRzCBjw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-portal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.0.tgz", + "integrity": "sha512-a8qyFO/Xb99d8wQdu4o7qnigNjTPG123uADNecz0eX4usnQEj7o+cG4ZX4zkqq98NYekT7UoEQIjxBNWIFuqTA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-portal/node_modules/@radix-ui/react-primitive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.0.tgz", + "integrity": "sha512-EyXe6mnRlHZ8b6f4ilTDrXmkLShICIuOTTj0GX4w1rp+wSxf3+TD05u1UOITC8VsJ2a9nwHvdXtOXEOl0Cw/zQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-portal/node_modules/@radix-ui/react-slot": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.0.tgz", + "integrity": "sha512-3mrKauI/tWXo1Ll+gN5dHcxDPdm/Df1ufcDLCecn+pnCIVcdWE7CujXo8QaXOWRJyZyQWWbpB8eFwHzWXlv5mQ==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-presence": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.0.tgz", + "integrity": "sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-use-layout-effect": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.1.tgz", + "integrity": "sha512-fHbmislWVkZaIdeF6GZxF0A/NH/3BjrGIYj+Ae6eTmTCr7EB0RQAAVEiqsXK6p3/JcRqVSBQoceZroj30Jj3XA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.1" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-scroll-area": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.0.2.tgz", + "integrity": "sha512-k8VseTxI26kcKJaX0HPwkvlNBPTs56JRdYzcZ/vzrNUkDlvXBy8sMc7WvCpYzZkHgb+hd72VW9MqkqecGtuNgg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/number": "1.0.0", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-direction": "1.0.0", + "@radix-ui/react-presence": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-use-callback-ref": "1.0.0", + "@radix-ui/react-use-layout-effect": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-slot": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.1.tgz", + "integrity": "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz", + "integrity": "sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.0.tgz", + "integrity": "sha512-FohDoZvk3mEXh9AWAVyRTYR4Sq7/gavuofglmiXB2g1aKyboUD4YtgWxKj8O5n+Uak52gXQ4wKz5IFST4vtJHg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.0.tgz", + "integrity": "sha512-JwfBCUIfhXRxKExgIqGa4CQsiMemo1Xt0W/B4ei3fpzpvPENKpMKQ8mZSB6Acj3ebrAEgi2xiQvcI1PAAodvyg==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.0" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.0.tgz", + "integrity": "sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ==", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "react": "^16.8 || ^17.0 || ^18.0" + } + }, + "node_modules/@remix-run/router": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.1.0.tgz", + "integrity": "sha512-rGl+jH/7x1KBCQScz9p54p0dtPLNeKGb3e0wD2H5/oZj41bwQUnXdzbj2TbUAFhvD7cp9EyEQA4dEgpUFa1O7Q==", + "engines": { + "node": ">=14" + } + }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true, + "engines": { + "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==", + "dev": true, + "dependencies": { + "type-detect": "4.0.8" + } + }, + "node_modules/@sinonjs/fake-timers": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "dev": true, + "dependencies": { + "@sinonjs/commons": "^1.7.0" + } + }, + "node_modules/@stylelint/postcss-css-in-js": { + "version": "0.38.0", + "resolved": "https://registry.npmjs.org/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.38.0.tgz", + "integrity": "sha512-XOz5CAe49kS95p5yRd+DAIWDojTjfmyAQ4bbDlXMdbZTQ5t0ThjSLvWI6JI2uiS7MFurVBkZ6zUqcimzcLTBoQ==", + "deprecated": "Package no longer supported. Contact Support at https://www.npmjs.com/support for more info.", + "dev": true, + "dependencies": { + "@babel/core": "^7.17.9" + }, + "peerDependencies": { + "postcss": ">=7.0.0", + "postcss-syntax": ">=0.36.2" + } + }, + "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==", + "dev": true, + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@tanstack/match-sorter-utils": { + "version": "8.7.2", + "resolved": "https://registry.npmjs.org/@tanstack/match-sorter-utils/-/match-sorter-utils-8.7.2.tgz", + "integrity": "sha512-bptNeoexeDB947fWoCPwUchPSx5FA9gwzU0bkXz0du5pT8Ud2+1ob+xOgHj6EF3VN0kdXtLhwjPyhY7/dJglkg==", + "dependencies": { + "remove-accents": "0.4.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/kentcdodds" + } + }, + "node_modules/@tanstack/query-core": { + "version": "4.29.5", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.29.5.tgz", + "integrity": "sha512-xXIiyQ/4r9KfaJ3k6kejqcaqFXXBTzN2aOJ5H1J6aTJE9hl/nbgAdfF6oiIu0CD5xowejJEJ6bBg8TO7BN4NuQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "4.29.5", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-4.29.5.tgz", + "integrity": "sha512-F87cibC3s3eG0Q90g2O+hqntpCrudKFnR8P24qkH9uccEhXErnJxBC/AAI4cJRV2bfMO8IeGZQYf3WyYgmSg0w==", + "dependencies": { + "@tanstack/query-core": "4.29.5", + "use-sync-external-store": "^1.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-native": "*" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/@tanstack/react-query-devtools": { + "version": "4.29.6", + "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-4.29.6.tgz", + "integrity": "sha512-qpYI41a69MWmrllcGiSE1KlpmnwJY/w0yKMnmp6VXn7nVy0i5TMMAT4u8D48F1Ipv/BKIDI1lqxPAvB4MqryBg==", + "dependencies": { + "@tanstack/match-sorter-utils": "^8.7.0", + "superjson": "^1.10.0", + "use-sync-external-store": "^1.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "@tanstack/react-query": "4.29.5", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/@teamsupercell/typings-for-css-modules-loader": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/@teamsupercell/typings-for-css-modules-loader/-/typings-for-css-modules-loader-2.5.2.tgz", + "integrity": "sha512-3sqH2B4itcm5XgV1IHENt4NOaW7bOC1CwJr63vrdKWWyKVxNxtBM+ABVhJZYFCCVAwNy7ulA64z6HyQqw96m4A==", + "dev": true, + "dependencies": { + "camelcase": "^5.3.1", + "loader-utils": "^1.4.2", + "schema-utils": "^2.0.1" + }, + "optionalDependencies": { + "prettier": "*" + } + }, + "node_modules/@teamsupercell/typings-for-css-modules-loader/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "node_modules/@teamsupercell/typings-for-css-modules-loader/node_modules/loader-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/@teamsupercell/typings-for-css-modules-loader/node_modules/schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 8.9.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/@testing-library/dom": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.13.0.tgz", + "integrity": "sha512-9VHgfIatKNXQNaZTtLnalIy0jNZzY35a4S3oi08YAt9Hv1VsfZ/DfA45lM8D/UhtHBGJ4/lGwp0PZkVndRkoOQ==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^4.2.0", + "aria-query": "^5.0.0", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.4.4", + "pretty-format": "^27.0.2" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@testing-library/jest-dom": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.4.tgz", + "integrity": "sha512-Gy+IoFutbMQcky0k+bqqumXZ1cTGswLsFqmNLzNdSKkU9KGV2u9oXhukCbbJ9/LRPKiqwxEE8VpV/+YZlfkPUA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.9.2", + "@types/testing-library__jest-dom": "^5.9.1", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.5.6", + "lodash": "^4.17.15", + "redent": "^3.0.0" + }, + "engines": { + "node": ">=8", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/@testing-library/jest-dom/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, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/@testing-library/react": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-13.0.0.tgz", + "integrity": "sha512-p0lYA1M7uoEmk2LnCbZLGmHJHyH59sAaZVXChTXlyhV/PRW9LoIh4mdf7tiXsO8BoNG+vN8UnFJff1hbZeXv+w==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.12.5", + "@testing-library/dom": "^8.5.0", + "@types/react-dom": "*" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.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==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/@ts-rest/core": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@ts-rest/core/-/core-3.23.0.tgz", + "integrity": "sha512-2vJwa682m9yS/xQPvPxZBluJfIZwNkt2HY9ER3UtGnu8Dijw+8iymSyIyjRLpFFWUyRnVp9IqrEi/d84bkNFIw==", + "peerDependencies": { + "zod": "^3.0.0" + }, + "peerDependenciesMeta": { + "zod": { + "optional": true + } + } + }, + "node_modules/@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true + }, + "node_modules/@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true + }, + "node_modules/@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true + }, + "node_modules/@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true + }, + "node_modules/@types/aria-query": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0", + "@types/babel__generator": "*", + "@types/babel__template": "*", + "@types/babel__traverse": "*" + } + }, + "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==", + "dev": true, + "dependencies": { + "@babel/types": "^7.0.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "node_modules/@types/babel__traverse": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", + "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", + "dev": true, + "dependencies": { + "@babel/types": "^7.3.0" + } + }, + "node_modules/@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "dependencies": { + "@types/connect": "*", + "@types/node": "*" + } + }, + "node_modules/@types/bonjour": { + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz", + "integrity": "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/cacheable-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", + "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", + "dev": true, + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "*", + "@types/node": "*", + "@types/responselike": "*" + } + }, + "node_modules/@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/connect-history-api-fallback": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz", + "integrity": "sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==", + "dev": true, + "dependencies": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "node_modules/@types/debug": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", + "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", + "dev": true, + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/@types/electron-localshortcut": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/electron-localshortcut/-/electron-localshortcut-3.1.0.tgz", + "integrity": "sha512-upKSXMxBPRdz5kmcXfdfn+hWH9PCAvwhyVozDXTIwwHQ1lUJcdSgGUfxOC1QBlnAPKPqcW/r4icWfMosKz8ibg==", + "dev": true, + "dependencies": { + "electron": "*" + } + }, + "node_modules/@types/eslint": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.2.tgz", + "integrity": "sha512-Z1nseZON+GEnFjJc04sv4NSALGjhFwy6K0HXt7qsn5ArfAKtb63dXNJHf+1YW6IpOIYRBGUbu3GwJdj8DGnCjA==", + "dev": true, + "dependencies": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "node_modules/@types/eslint-scope": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz", + "integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==", + "dev": true, + "dependencies": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "node_modules/@types/estree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "dev": true + }, + "node_modules/@types/express": { + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", + "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", + "dev": true, + "dependencies": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "node_modules/@types/express-serve-static-core": { + "version": "4.17.28", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", + "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "node_modules/@types/fs-extra": { + "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "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, + "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==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "dev": true, + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, + "node_modules/@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", + "dev": true + }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", + "dev": true + }, + "node_modules/@types/http-proxy": { + "version": "1.17.8", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.8.tgz", + "integrity": "sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "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 + }, + "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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-report": "*" + } + }, + "node_modules/@types/jest": { + "version": "27.4.1", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", + "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", + "dev": true, + "dependencies": { + "jest-matcher-utils": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, + "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 + }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "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==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/lodash": { + "version": "4.14.188", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.188.tgz", + "integrity": "sha512-zmEmF5OIM3rb7SbLCFYoQhO4dGt2FRM9AMkxvA3LaADOF1n8in/zGJlWji9fmafLoNyz+FoL6FE0SLtGIArD7w==", + "dev": true + }, + "node_modules/@types/md5": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/md5/-/md5-2.3.2.tgz", + "integrity": "sha512-v+JFDu96+UYJ3/UWzB0mEglIS//MZXgRaJ4ubUPwOM0gvLc/kcQ3TWNYwENEK7/EcXGQVrW8h/XqednSjBd/Og==", + "dev": true + }, + "node_modules/@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "dev": true + }, + "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/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/ms": { + "version": "0.7.31", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", + "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==", + "dev": true + }, + "node_modules/@types/node": { + "version": "17.0.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", + "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==", + "dev": true + }, + "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 + }, + "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==" + }, + "node_modules/@types/plist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.2.tgz", + "integrity": "sha512-ULqvZNGMv0zRFvqn8/4LSPtnmN4MfhlPNtJCTpKuIIxGVGZ2rYWzFXrvEBoh9CVyqSE7D6YFRJ1hydLHI6kbWw==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*", + "xmlbuilder": ">=11.0.1" + } + }, + "node_modules/@types/prettier": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.3.tgz", + "integrity": "sha512-ymZk3LEC/fsut+/Q5qejp6R9O1rMxz3XaRHDV6kX8MrGAhOSPqVARbDi+EZvInBpw+BnCX3TD240byVkOfQsHg==", + "dev": true + }, + "node_modules/@types/prop-types": { + "version": "15.7.4", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", + "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==", + "devOptional": true + }, + "node_modules/@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "node_modules/@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "node_modules/@types/react": { + "version": "18.0.26", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.26.tgz", + "integrity": "sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==", + "devOptional": true, + "dependencies": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/react-dom": { + "version": "18.0.9", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.9.tgz", + "integrity": "sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-test-renderer": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-17.0.1.tgz", + "integrity": "sha512-3Fi2O6Zzq/f3QR9dRnlnHso9bMl7weKCviFmfF6B4LS1Uat6Hkm15k0ZAQuDz+UBq6B3+g+NM6IT2nr5QgPzCw==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-virtualized-auto-sizer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.1.tgz", + "integrity": "sha512-GH8sAnBEM5GV9LTeiz56r4ZhMOUSrP43tAQNSRVxNexDjcNKLCEtnxusAItg1owFUFE6k0NslV26gqVClVvong==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-window": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.5.tgz", + "integrity": "sha512-V9q3CvhC9Jk9bWBOysPGaWy/Z0lxYcTXLtLipkt2cnRj1JOSFNF7wqGpkScSXMgBwC+fnVRg/7shwgddBG5ICw==", + "dev": true, + "dependencies": { + "@types/react": "*" + } + }, + "node_modules/@types/react-window-infinite-loader": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/react-window-infinite-loader/-/react-window-infinite-loader-1.0.6.tgz", + "integrity": "sha512-V8g8sBDLVeJJAfEENJS7VXZK+DRJ+jzPNtk8jpj2G+obhf+iqGNUDGwNWCbBhLiD+KpHhf3kWQlKBRi0tAeU4Q==", + "dev": true, + "dependencies": { + "@types/react": "*", + "@types/react-window": "*" + } + }, + "node_modules/@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/retry": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz", + "integrity": "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==", + "dev": true + }, + "node_modules/@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", + "devOptional": true + }, + "node_modules/@types/semver": { + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==" + }, + "node_modules/@types/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==", + "dev": true, + "dependencies": { + "@types/express": "*" + } + }, + "node_modules/@types/serve-static": { + "version": "1.13.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", + "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", + "dev": true, + "dependencies": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "node_modules/@types/sockjs": { + "version": "0.3.33", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz", + "integrity": "sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "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 + }, + "node_modules/@types/styled-components": { + "version": "5.1.26", + "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.26.tgz", + "integrity": "sha512-KuKJ9Z6xb93uJiIyxo/+ksS7yLjS1KzG6iv5i78dhVg/X3u5t1H7juRWqVmodIdz6wGVaIApo1u01kmFRdJHVw==", + "dev": true, + "dependencies": { + "@types/hoist-non-react-statics": "*", + "@types/react": "*", + "csstype": "^3.0.2" + } + }, + "node_modules/@types/symlink-or-copy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/symlink-or-copy/-/symlink-or-copy-1.2.0.tgz", + "integrity": "sha512-Lja2xYuuf2B3knEsga8ShbOdsfNOtzT73GyJmZyY7eGl2+ajOqrs8yM5ze0fsSoYwvA6bw7/Qr7OZ7PEEmYwWg==", + "dev": true + }, + "node_modules/@types/terser-webpack-plugin": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@types/terser-webpack-plugin/-/terser-webpack-plugin-5.2.0.tgz", + "integrity": "sha512-iHDR2pRfFjGyDqCALX2tgUgFtGoQf2AJhKpC2XD1IMBQVJF2bny6WChGRDKj9eaZJl4F2RmvBhxJNtVPj7aTRw==", + "deprecated": "This is a stub types definition. terser-webpack-plugin provides its own type definitions, so you do not need this installed.", + "dev": true, + "dependencies": { + "terser-webpack-plugin": "*" + } + }, + "node_modules/@types/testing-library__jest-dom": { + "version": "5.14.3", + "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.3.tgz", + "integrity": "sha512-oKZe+Mf4ioWlMuzVBaXQ9WDnEm1+umLx0InILg+yvZVBBDmzV5KfZyLrCvadtWcx8+916jLmHafcmqqffl+iIw==", + "dev": true, + "dependencies": { + "@types/jest": "*" + } + }, + "node_modules/@types/unist": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", + "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==", + "dev": true + }, + "node_modules/@types/verror": { + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.6.tgz", + "integrity": "sha512-NNm+gdePAX1VGvPcGZCDKQZKYSiAWigKhKaz5KF94hG6f2s8de9Ow5+7AbXoeKxL8gavZfk4UquSAygOF2duEQ==", + "dev": true, + "optional": true + }, + "node_modules/@types/vfile": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/vfile/-/vfile-3.0.2.tgz", + "integrity": "sha512-b3nLFGaGkJ9rzOcuXRfHkZMdjsawuDD0ENL9fzTophtBg8FJHSGbH7daXkEpcwy3v7Xol3pAvsmlYyFhR4pqJw==", + "dev": true, + "dependencies": { + "@types/node": "*", + "@types/unist": "*", + "@types/vfile-message": "*" + } + }, + "node_modules/@types/vfile-message": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/vfile-message/-/vfile-message-2.0.0.tgz", + "integrity": "sha512-GpTIuDpb9u4zIO165fUy9+fXcULdD8HFRNli04GehoMVbeNq7D6OBnqSmg3lxZnC+UvgUhEWKxdKiwYUkGltIw==", + "deprecated": "This is a stub types definition. vfile-message provides its own type definitions, so you do not need this installed.", + "dev": true, + "dependencies": { + "vfile-message": "*" + } + }, + "node_modules/@types/webpack-bundle-analyzer": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@types/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.4.1.tgz", + "integrity": "sha512-yQAj3l7bIYL+QRRlNJt6gyP+zrXZOlgaR4wsX0WY4yzZIbv41ZibREfZvuYjxY0iVtvQQlbhx0AeokkCuqUAQg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "tapable": "^2.2.0", + "webpack": "^5" + } + }, + "node_modules/@types/webpack-env": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.16.3.tgz", + "integrity": "sha512-9gtOPPkfyNoEqCQgx4qJKkuNm/x0R2hKR7fdl7zvTJyHnIisuE/LfvXOsYWL0o3qq6uiBnKZNNNzi3l0y/X+xw==", + "dev": true + }, + "node_modules/@types/ws": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", + "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@types/yargs": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", + "dev": true, + "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 + }, + "node_modules/@types/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "dev": true, + "optional": true, + "dependencies": { + "@types/node": "*" + } + }, + "node_modules/@typescript-eslint/eslint-plugin": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.47.1.tgz", + "integrity": "sha512-r4RZ2Jl9kcQN7K/dcOT+J7NAimbiis4sSM9spvWimsBvDegMhKLA5vri2jG19PmIPbDjPeWzfUPQ2hjEzA4Nmg==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.47.1", + "@typescript-eslint/type-utils": "5.47.1", + "@typescript-eslint/utils": "5.47.1", + "debug": "^4.3.4", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/experimental-utils": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", + "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.33.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/typescript-estree": "4.33.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + } + }, + "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/scope-manager": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", + "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/types": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", + "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", + "dev": true, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", + "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/experimental-utils/node_modules/@typescript-eslint/visitor-keys": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", + "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.33.0", + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/experimental-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==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/@typescript-eslint/parser": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.47.1.tgz", + "integrity": "sha512-9Vb+KIv29r6GPu4EboWOnQM7T+UjpjXvjCPhNORlgm40a9Ia9bvaPJswvtae1gip2QEeVeGh6YquqAzEgoRAlw==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "5.47.1", + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/typescript-estree": "5.47.1", + "debug": "^4.3.4" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/scope-manager": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.1.tgz", + "integrity": "sha512-9hsFDsgUwrdOoW1D97Ewog7DYSHaq4WKuNs0LHF9RiCmqB0Z+XRR4Pf7u7u9z/8CciHuJ6yxNws1XznI3ddjEw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/visitor-keys": "5.47.1" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.47.1.tgz", + "integrity": "sha512-/UKOeo8ee80A7/GJA427oIrBi/Gd4osk/3auBUg4Rn9EahFpevVV1mUK8hjyQD5lHPqX397x6CwOk5WGh1E/1w==", + "dev": true, + "dependencies": { + "@typescript-eslint/typescript-estree": "5.47.1", + "@typescript-eslint/utils": "5.47.1", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "*" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/types": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", + "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@typescript-eslint/typescript-estree": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.1.tgz", + "integrity": "sha512-4+ZhFSuISAvRi2xUszEj0xXbNTHceV9GbH9S8oAD2a/F9SW57aJNQVOCxG8GPfSWH/X4eOPdMEU2jYVuWKEpWA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/visitor-keys": "5.47.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@typescript-eslint/utils": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.47.1.tgz", + "integrity": "sha512-l90SdwqfmkuIVaREZ2ykEfCezepCLxzWMo5gVfcJsJCaT4jHT+QjgSkYhs5BMQmWqE9k3AtIfk4g211z/sTMVw==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.47.1", + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/typescript-estree": "5.47.1", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0", + "semver": "^7.3.7" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.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/visitor-keys": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", + "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.47.1", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/@webassemblyjs/ast": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "dev": true, + "dependencies": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "node_modules/@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "dependencies": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "node_modules/@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" + } + }, + "node_modules/@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "dependencies": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "node_modules/@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "dependencies": { + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "node_modules/@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "node_modules/@webassemblyjs/wast-printer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "dev": true, + "dependencies": { + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "node_modules/@webpack-cli/configtest": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.1.tgz", + "integrity": "sha512-1FBc1f9G4P/AxMqIgfZgeOTuRnwZMten8E7zap5zgpPInnCrP8D4Q81+4CWIch8i/Nf7nXjP0v6CjjbHOrXhKg==", + "dev": true, + "peerDependencies": { + "webpack": "4.x.x || 5.x.x", + "webpack-cli": "4.x.x" + } + }, + "node_modules/@webpack-cli/info": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.4.1.tgz", + "integrity": "sha512-PKVGmazEq3oAo46Q63tpMr4HipI3OPfP7LiNOEJg963RMgT0rqheag28NCML0o3GIzA3DmxP1ZIAv9oTX1CUIA==", + "dev": true, + "dependencies": { + "envinfo": "^7.7.3" + }, + "peerDependencies": { + "webpack-cli": "4.x.x" + } + }, + "node_modules/@webpack-cli/serve": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.1.tgz", + "integrity": "sha512-gNGTiTrjEVQ0OcVnzsRSqTxaBSr+dmTfm+qJsCDluky8uhdLWep7Gcr62QsAKHTMxjCS/8nEITsmFAhfIx+QSw==", + "dev": true, + "peerDependencies": { + "webpack-cli": "4.x.x" + }, + "peerDependenciesMeta": { + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "node_modules/@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "node_modules/7zip-bin": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.1.1.tgz", + "integrity": "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ==", + "dev": true + }, + "node_modules/abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "dev": true + }, + "node_modules/abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + } + }, + "node_modules/acorn-globals/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "dev": true, + "peerDependencies": { + "acorn": "^8" + } + }, + "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==", + "dev": true, + "peerDependencies": { + "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/address": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", + "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", + "dev": true, + "engines": { + "node": ">= 0.12.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, + "dependencies": { + "debug": "4" + }, + "engines": { + "node": ">= 6.0.0" + } + }, + "node_modules/agentkeepalive": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz", + "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "depd": "^1.1.2", + "humanize-ms": "^1.2.1" + }, + "engines": { + "node": ">= 8.0.0" + } + }, + "node_modules/aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "dependencies": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, + "node_modules/ajv-formats/node_modules/ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats/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==" + }, + "node_modules/ajv-keywords": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "peerDependencies": { + "ajv": "^6.9.1" + } + }, + "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, + "dependencies": { + "type-fest": "^0.21.3" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-escapes/node_modules/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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true, + "engines": [ + "node >= 0.8.0" + ], + "bin": { + "ansi-html": "bin/ansi-html" + } + }, + "node_modules/ansi-regex": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "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, + "dependencies": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/app-builder-bin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-4.0.0.tgz", + "integrity": "sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA==", + "dev": true + }, + "node_modules/app-builder-lib": { + "version": "24.0.0-alpha.13", + "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-24.0.0-alpha.13.tgz", + "integrity": "sha512-fQa3zDl948PS+EvDaAtPTM3UvrXKns9TEQ7dR3BYWJbpIs7s0e1FxlwVLrINYGLv7hxdLkhbJ0ewPxKyj/ahpQ==", + "dev": true, + "dependencies": { + "@develar/schema-utils": "~2.6.5", + "@electron/notarize": "^1.2.3", + "@electron/osx-sign": "^1.0.4", + "@electron/rebuild": "^3.2.10", + "@electron/universal": "1.3.4", + "@malept/flatpak-bundler": "^0.4.0", + "7zip-bin": "~5.1.1", + "async-exit-hook": "^2.0.1", + "bluebird-lst": "^1.0.9", + "builder-util": "24.0.0-alpha.13", + "builder-util-runtime": "9.2.0-alpha.3", + "chromium-pickle-js": "^0.2.0", + "debug": "^4.3.4", + "ejs": "^3.1.8", + "electron-publish": "24.0.0-alpha.13", + "form-data": "^4.0.0", + "fs-extra": "^10.1.0", + "hosted-git-info": "^4.1.0", + "is-ci": "^3.0.0", + "isbinaryfile": "^5.0.0", + "js-yaml": "^4.1.0", + "lazy-val": "^1.0.5", + "minimatch": "^5.1.1", + "read-config-file": "6.3.2", + "sanitize-filename": "^1.6.3", + "semver": "^7.3.8", + "tar": "^6.1.12", + "temp-file": "^3.4.0" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/app-builder-lib/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/app-builder-lib/node_modules/builder-util-runtime": { + "version": "9.2.0-alpha.3", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.0-alpha.3.tgz", + "integrity": "sha512-1pOggEqknxVyhdASumips0/RaMaXwSCQMzwhk2jeOGOotBQuOHQHVy25kH5OaeXSFx9L7PckZHXjwZauD72zRw==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/app-builder-lib/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/app-builder-lib/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/app-builder-lib/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/app-builder-lib/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/append-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", + "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", + "dev": true, + "dependencies": { + "buffer-equal": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "dev": true + }, + "node_modules/are-we-there-yet": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz", + "integrity": "sha512-0GWpv50YSOcLXaN6/FAKY3vfRbllXWV2xvfA/oKJF8pzFhWXPV+yjhJXDBbjscDYowv7Yw1A3uigpzn5iEGTyw==", + "dev": true, + "dependencies": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16" + } + }, + "node_modules/are-we-there-yet/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "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==" + }, + "node_modules/aria-hidden": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.2.tgz", + "integrity": "sha512-6y/ogyDTk/7YAe91T3E2PR1ALVKyM2QbTio5HwM+N1Q6CMlCKhvClyIjkckBswa0f2xJhjsfzIGa1yVSe1UMVA==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", + "react": "^16.9.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/aria-query": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.0.0.tgz", + "integrity": "sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-find": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-find/-/array-find-1.0.0.tgz", + "integrity": "sha1-bI4obRHtdoMn+OYuzuhzU8o+eLg=", + "dev": true + }, + "node_modules/array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "dev": true + }, + "node_modules/array-includes": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", + "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-union": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", + "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", + "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.tosorted": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz", + "integrity": "sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.1.3" + } + }, + "node_modules/arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "optional": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ast-metadata-inferer": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.7.0.tgz", + "integrity": "sha512-OkMLzd8xelb3gmnp6ToFvvsHLtS6CbagTkFQvQ+ZYFe3/AIl9iKikNR9G7pY3GfOR/2Xc222hwBjzI7HLkE76Q==", + "dev": true, + "dependencies": { + "@mdn/browser-compat-data": "^3.3.14" + } + }, + "node_modules/ast-metadata-inferer/node_modules/@mdn/browser-compat-data": { + "version": "3.3.14", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-3.3.14.tgz", + "integrity": "sha512-n2RC9d6XatVbWFdHLimzzUJxJ1KY8LdjqrW6YvGPiRmsHkhOUx74/Ct10x5Yo7bC/Jvqx7cDEW8IMPv/+vwEzA==", + "dev": true + }, + "node_modules/ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", + "dev": true + }, + "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, + "engines": { + "node": ">=8" + } + }, + "node_modules/async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", + "dev": true + }, + "node_modules/async-exit-hook": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", + "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", + "dev": true, + "engines": { + "node": ">=0.12.0" + } + }, + "node_modules/asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "node_modules/at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true, + "bin": { + "atob": "bin/atob.js" + }, + "engines": { + "node": ">= 4.5.0" + } + }, + "node_modules/atomically": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz", + "integrity": "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==", + "engines": { + "node": ">=10.12.0" + } + }, + "node_modules/autoprefixer": { + "version": "9.8.8", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz", + "integrity": "sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==", + "dev": true, + "dependencies": { + "browserslist": "^4.12.0", + "caniuse-lite": "^1.0.30001109", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "picocolors": "^0.2.1", + "postcss": "^7.0.32", + "postcss-value-parser": "^4.1.0" + }, + "bin": { + "autoprefixer": "bin/autoprefixer" + }, + "funding": { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/autoprefixer" + } + }, + "node_modules/autoprefixer/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "node_modules/autoprefixer/node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/autoprefixer/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/axe-core": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.6.1.tgz", + "integrity": "sha512-lCZN5XRuOnpG4bpMq8v0khrWtUOn+i8lZSb6wHZH56ZfbIEv6XwJV84AAueh9/zi7qPVJ/E4yz6fmsiyOmXR4w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/axios": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", + "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", + "dependencies": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axobject-query": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", + "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", + "dev": true + }, + "node_modules/babel-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "dev": true, + "dependencies": { + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.8.0" + } + }, + "node_modules/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, + "dependencies": { + "@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" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/babel-plugin-jest-hoist": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "dev": true, + "dependencies": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + } + }, + "node_modules/babel-plugin-styled-components": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.7.tgz", + "integrity": "sha512-i7YhvPgVqRKfoQ66toiZ06jPNA3p6ierpfUuEWxNF+fV27Uv5gxBkf8KZLHUCc1nFA9j6+80pYoIpqCeyW3/bA==", + "dependencies": { + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-module-imports": "^7.16.0", + "babel-plugin-syntax-jsx": "^6.18.0", + "lodash": "^4.17.11", + "picomatch": "^2.3.0" + }, + "peerDependencies": { + "styled-components": ">= 2" + } + }, + "node_modules/babel-plugin-syntax-jsx": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==" + }, + "node_modules/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, + "dependencies": { + "@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" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/babel-preset-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "dev": true, + "dependencies": { + "babel-plugin-jest-hoist": "^27.5.1", + "babel-preset-current-node-syntax": "^1.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": "^7.0.0" + } + }, + "node_modules/bail": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "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==", + "dev": true + }, + "node_modules/base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "dependencies": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "dev": true + }, + "node_modules/big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "dependencies": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + } + }, + "node_modules/bl/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "node_modules/bluebird-lst": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.9.tgz", + "integrity": "sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw==", + "dev": true, + "dependencies": { + "bluebird": "^3.5.5" + } + }, + "node_modules/body-parser": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", + "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "dev": true, + "dependencies": { + "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.10.3", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "node_modules/body-parser/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/body-parser/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/body-parser/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==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/body-parser/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/bonjour-service": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.0.11.tgz", + "integrity": "sha512-drMprzr2rDTCtgEE3VgdA9uUFaUHF+jXduwYSThHJnKMYM+FhI9Z3ph+TX3xy0LtgYHae6CHYPJ/2UnK8nQHcA==", + "dev": true, + "dependencies": { + "array-flatten": "^2.1.2", + "dns-equal": "^1.0.0", + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.4" + } + }, + "node_modules/boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, + "node_modules/boolean": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", + "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "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, + "dependencies": { + "fill-range": "^7.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/broccoli-node-api": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/broccoli-node-api/-/broccoli-node-api-1.7.0.tgz", + "integrity": "sha512-QIqLSVJWJUVOhclmkmypJJH9u9s/aWH4+FH6Q6Ju5l+Io4dtwqdPUNmDfw40o6sxhbZHhqGujDJuHTML1wG8Yw==", + "dev": true + }, + "node_modules/broccoli-node-info": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/broccoli-node-info/-/broccoli-node-info-2.2.0.tgz", + "integrity": "sha512-VabSGRpKIzpmC+r+tJueCE5h8k6vON7EIMMWu6d/FyPdtijwLQ7QvzShEw+m3mHoDzUaj/kiZsDYrS8X2adsBg==", + "dev": true, + "engines": { + "node": "8.* || >= 10.*" + } + }, + "node_modules/broccoli-output-wrapper": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/broccoli-output-wrapper/-/broccoli-output-wrapper-3.2.5.tgz", + "integrity": "sha512-bQAtwjSrF4Nu0CK0JOy5OZqw9t5U0zzv2555EA/cF8/a8SLDTIetk9UgrtMVw7qKLKdSpOZ2liZNeZZDaKgayw==", + "dev": true, + "dependencies": { + "fs-extra": "^8.1.0", + "heimdalljs-logger": "^0.1.10", + "symlink-or-copy": "^1.2.0" + }, + "engines": { + "node": "10.* || >= 12.*" + } + }, + "node_modules/broccoli-plugin": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/broccoli-plugin/-/broccoli-plugin-4.0.7.tgz", + "integrity": "sha512-a4zUsWtA1uns1K7p9rExYVYG99rdKeGRymW0qOCNkvDPHQxVi3yVyJHhQbM3EZwdt2E0mnhr5e0c/bPpJ7p3Wg==", + "dev": true, + "dependencies": { + "broccoli-node-api": "^1.7.0", + "broccoli-output-wrapper": "^3.2.5", + "fs-merger": "^3.2.1", + "promise-map-series": "^0.3.0", + "quick-temp": "^0.1.8", + "rimraf": "^3.0.2", + "symlink-or-copy": "^1.3.1" + }, + "engines": { + "node": "10.* || >= 12.*" + } + }, + "node_modules/browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true + }, + "node_modules/browserslist": { + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" + }, + "bin": { + "browserslist": "cli.js" + }, + "engines": { + "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" + } + }, + "node_modules/browserslist-config-erb": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/browserslist-config-erb/-/browserslist-config-erb-0.0.3.tgz", + "integrity": "sha512-y47DryCY92lxkKyRVMlaZvXAolIY7U33q9e4CS0MdWeJkoAht7OzsrkfdZFCBOP3H5q1EVUxS0L7VVsKM6gZCQ==", + "dev": true, + "peerDependencies": { + "electron": ">=12.0.0" + } + }, + "node_modules/bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "dependencies": { + "fast-json-stable-stringify": "2.x" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/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, + "dependencies": { + "node-int64": "^0.4.0" + } + }, + "node_modules/buffer": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "node_modules/buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/buffer-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", + "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/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==", + "dev": true + }, + "node_modules/builder-util": { + "version": "24.0.0-alpha.13", + "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-24.0.0-alpha.13.tgz", + "integrity": "sha512-S8u+ETQ9GV4hJdrxJgVh2V0Cp14WiTrXRy7NsRSlM+DXaNtCIO3VNJSlEg4Btn1cJLUhfo1Fse8FIryV3gRj0Q==", + "dev": true, + "dependencies": { + "@types/debug": "^4.1.6", + "@types/fs-extra": "^9.0.11", + "7zip-bin": "~5.1.1", + "app-builder-bin": "4.0.0", + "bluebird-lst": "^1.0.9", + "builder-util-runtime": "9.2.0-alpha.3", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.3", + "debug": "^4.3.4", + "fs-extra": "^10.1.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-ci": "^3.0.0", + "js-yaml": "^4.1.0", + "source-map-support": "^0.5.19", + "stat-mode": "^1.0.0", + "temp-file": "^3.4.0" + } + }, + "node_modules/builder-util-runtime": { + "version": "8.9.2", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.9.2.tgz", + "integrity": "sha512-rhuKm5vh7E0aAmT6i8aoSfEjxzdYEFX7zDApK+eNgOhjofnWb74d9SRJv0H/8nsgOkos0TZ4zxW0P8J4N7xQ2A==", + "dependencies": { + "debug": "^4.3.2", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/builder-util/node_modules/builder-util-runtime": { + "version": "9.2.0-alpha.3", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.0-alpha.3.tgz", + "integrity": "sha512-1pOggEqknxVyhdASumips0/RaMaXwSCQMzwhk2jeOGOotBQuOHQHVy25kH5OaeXSFx9L7PckZHXjwZauD72zRw==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/builder-util/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/builder-util/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/builder-util/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "dependencies": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", + "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "dev": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha512-wCyFsDQkKPwwF8BDwOiWNx/9K45L/hvggQiDbve+viMNMQnWhrlYIuBk09offfwCRtCO9P6XwUttufzU11WCVw==", + "dev": true + }, + "node_modules/caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", + "dev": true, + "dependencies": { + "callsites": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/caller-callsite/node_modules/callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", + "dev": true, + "dependencies": { + "caller-callsite": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "engines": { + "node": ">=6" + } + }, + "node_modules/camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dev": true, + "dependencies": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" + } + }, + "node_modules/camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true, + "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/camelcase-keys/node_modules/quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==", + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dev": true, + "dependencies": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "node_modules/caniuse-lite": { + "version": "1.0.30001439", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz", + "integrity": "sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] + }, + "node_modules/ccount": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", + "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/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, + "engines": { + "node": ">=10" + } + }, + "node_modules/character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-html4": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz", + "integrity": "sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", + "engines": { + "node": "*" + } + }, + "node_modules/cheerio": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz", + "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==", + "dev": true, + "dependencies": { + "cheerio-select": "^1.5.0", + "dom-serializer": "^1.3.2", + "domhandler": "^4.2.0", + "htmlparser2": "^6.1.0", + "parse5": "^6.0.1", + "parse5-htmlparser2-tree-adapter": "^6.0.1", + "tslib": "^2.2.0" + }, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" + } + }, + "node_modules/cheerio-select": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.6.0.tgz", + "integrity": "sha512-eq0GdBvxVFbqWgmCm7M3XGs1I8oLy/nExUnh6oLqmBditPO9AqQJrkslDpMun/hZ0yyTs8L0m85OHp4ho6Qm9g==", + "dev": true, + "dependencies": { + "css-select": "^4.3.0", + "css-what": "^6.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.3.1", + "domutils": "^2.8.0" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "funding": [ + { + "type": "individual", + "url": "https://paulmillr.com/funding/" + } + ], + "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": ">= 8.10.0" + }, + "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==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/chromium-pickle-js": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", + "integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==", + "dev": true + }, + "node_modules/ci-info": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", + "dev": true + }, + "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 + }, + "node_modules/class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { "is-buffer": "^1.1.5" - } + }, + "engines": { + "node": ">=0.10.0" } - } }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { + "node_modules/class-utils/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/class-utils/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { "is-buffer": "^1.1.5" - } + }, + "engines": { + "node": ">=0.10.0" } - } }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } + "node_modules/class-utils/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "clean-css": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.0.tgz", - "integrity": "sha512-YYuuxv4H/iNb1Z/5IbMRoxgrzjWGhOEFfd+groZ5dMCVkpENiMZmwspdrzBo9286JjM1gZJPAyL7ZIdzuvu2AQ==", - "dev": true, - "requires": { - "source-map": "~0.6.0" - }, - "dependencies": { - "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 - } - } - }, - "clean-stack": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", - "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", - "dev": true - }, - "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", - "dev": true, - "requires": { - "restore-cursor": "^3.1.0" - } - }, - "cli-spinners": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", - "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", - "dev": true - }, - "cli-truncate": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", - "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", - "dev": true, - "requires": { - "slice-ansi": "^3.0.0", - "string-width": "^4.2.0" - } - }, - "cliui": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", - "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", - "dev": true, - "requires": { - "string-width": "^4.2.0", - "strip-ansi": "^6.0.0", - "wrap-ansi": "^7.0.0" - } - }, - "clone": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", - "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", - "dev": true - }, - "clone-buffer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", - "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", - "dev": true - }, - "clone-deep": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", - "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4", - "kind-of": "^6.0.2", - "shallow-clone": "^3.0.0" - } - }, - "clone-regexp": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz", - "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==", - "dev": true, - "requires": { - "is-regexp": "^2.0.0" - } - }, - "clone-response": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", - "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", - "dev": true, - "requires": { - "mimic-response": "^1.0.0" - } - }, - "clone-stats": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", - "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", - "dev": true - }, - "cloneable-readable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", - "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "process-nextick-args": "^2.0.0", - "readable-stream": "^2.3.5" - } - }, - "clsx": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz", - "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==" - }, - "cmdk": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-0.2.0.tgz", - "integrity": "sha512-JQpKvEOb86SnvMZbYaFKYhvzFntWBeSZdyii0rZPhKJj9uwJBxu4DaVYDrRN7r3mPop56oPhRw+JYWTKs66TYw==", - "requires": { - "@radix-ui/react-dialog": "1.0.0", - "command-score": "0.1.2" - } - }, - "co": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", - "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", - "dev": true - }, - "collapse-white-space": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", - "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", - "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 - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "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==", - "dev": true, - "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==", - "dev": true - }, - "color-support": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", - "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", - "dev": true - }, - "colord": { - "version": "2.9.2", - "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.2.tgz", - "integrity": "sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ==", - "dev": true - }, - "colorette": { - "version": "2.0.16", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", - "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", - "dev": true - }, - "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" - } - }, - "command-score": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/command-score/-/command-score-0.1.2.tgz", - "integrity": "sha512-VtDvQpIJBvBatnONUsPzXYFVKQQAhuf3XTNOAsdBxCNO/QCtUUd8LSgjn0GVarBkCad6aJCZfXgrjYbl/KRr7w==" - }, - "commander": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", - "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", - "dev": true - }, - "common-path-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", - "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", - "dev": true - }, - "compare-version": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", - "integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compressible": { - "version": "2.0.18", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", - "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", - "dev": true, - "requires": { - "mime-db": ">= 1.43.0 < 2" - } - }, - "compression": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", - "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", - "dev": true, - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.16", - "debug": "2.6.9", - "on-headers": "~1.0.2", - "safe-buffer": "5.1.2", - "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==", - "dev": true, - "requires": { - "ms": "2.0.0" - } + "node_modules/class-utils/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", - "dev": true - }, - "concurrently": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.1.0.tgz", - "integrity": "sha512-Bz0tMlYKZRUDqJlNiF/OImojMB9ruKUz6GCfmhFnSapXgPe+3xzY4byqoKG9tUZ7L2PGEUjfLPOLfIX3labnmw==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "date-fns": "^2.16.1", - "lodash": "^4.17.21", - "rxjs": "^6.6.3", - "spawn-command": "^0.0.2-1", - "supports-color": "^8.1.0", - "tree-kill": "^1.2.2", - "yargs": "^16.2.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" - } - } - } - }, - "conf": { - "version": "10.2.0", - "resolved": "https://registry.npmjs.org/conf/-/conf-10.2.0.tgz", - "integrity": "sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==", - "requires": { - "ajv": "^8.6.3", - "ajv-formats": "^2.1.1", - "atomically": "^1.7.0", - "debounce-fn": "^4.0.0", - "dot-prop": "^6.0.1", - "env-paths": "^2.2.1", - "json-schema-typed": "^7.0.3", - "onetime": "^5.1.2", - "pkg-up": "^3.1.0", - "semver": "^7.3.5" - }, - "dependencies": { - "ajv": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", - "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", - "requires": { - "fast-deep-equal": "^3.1.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2", - "uri-js": "^4.2.2" - } + "node_modules/clean-css": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.0.tgz", + "integrity": "sha512-YYuuxv4H/iNb1Z/5IbMRoxgrzjWGhOEFfd+groZ5dMCVkpENiMZmwspdrzBo9286JjM1gZJPAyL7ZIdzuvu2AQ==", + "dev": true, + "dependencies": { + "source-map": "~0.6.0" + }, + "engines": { + "node": ">= 10.0" + } }, - "dot-prop": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", - "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", - "requires": { - "is-obj": "^2.0.0" - } + "node_modules/clean-css/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, + "engines": { + "node": ">=0.10.0" + } }, - "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==" - } - } - }, - "config-file-ts": { - "version": "0.2.4", - "resolved": "https://registry.npmjs.org/config-file-ts/-/config-file-ts-0.2.4.tgz", - "integrity": "sha512-cKSW0BfrSaAUnxpgvpXPLaaW/umg4bqg4k3GO1JqlRfpx+d5W0GDXznCMkWotJQek5Mmz1MJVChQnz3IVaeMZQ==", - "dev": true, - "requires": { - "glob": "^7.1.6", - "typescript": "^4.0.2" - } - }, - "confusing-browser-globals": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", - "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", - "dev": true - }, - "connect-history-api-fallback": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", - "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", - "dev": true - }, - "console-control-strings": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", - "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", - "dev": true - }, - "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==", - "dev": true, - "requires": { - "safe-buffer": "5.2.1" - }, - "dependencies": { - "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==", - "dev": true - } - } - }, - "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==", - "dev": true - }, - "convert-source-map": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", - "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "cookie": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", - "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", - "dev": true - }, - "cookie-signature": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", - "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", - "dev": true - }, - "copy-anything": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.2.tgz", - "integrity": "sha512-CzATjGXzUQ0EvuvgOCI6A4BGOo2bcVx8B+eC2nF862iv9fopnPQwlrbACakNCHRIJbCSBj+J/9JeDf60k64MkA==", - "requires": { - "is-what": "^4.1.6" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", - "dev": true - }, - "core-js": { - "version": "3.21.1", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.21.1.tgz", - "integrity": "sha512-FRq5b/VMrWlrmCzwRrpDYNxyHP9BcAZC+xHJaqTgIE5091ZV1NTmyh0sGOg5XqpnHvR0svdy0sv1gWA1zmhxig==", - "dev": true - }, - "core-js-pure": { - "version": "3.21.1", - "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.21.1.tgz", - "integrity": "sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ==", - "dev": true - }, - "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==", - "dev": true - }, - "cosmiconfig": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", - "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", - "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" - } - }, - "crc": { - "version": "3.8.0", - "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", - "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", - "dev": true, - "optional": true, - "requires": { - "buffer": "^5.1.0" - } - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "cross-env": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", - "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", - "dev": true, - "requires": { - "cross-spawn": "^7.0.1" - } - }, - "cross-spawn": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", - "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", - "dev": true, - "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": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=" - }, - "css": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", - "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", - "dev": true, - "requires": { - "inherits": "^2.0.4", - "source-map": "^0.6.1", - "source-map-resolve": "^0.6.0" - }, - "dependencies": { - "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 - } - } - }, - "css-color-keywords": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", - "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==" - }, - "css-declaration-sorter": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.2.2.tgz", - "integrity": "sha512-Ufadglr88ZLsrvS11gjeu/40Lw74D9Am/Jpr3LlYm5Q4ZP5KdlUhG+6u2EjyXeZcxmZ2h1ebCKngDjolpeLHpg==", - "dev": true, - "requires": {} - }, - "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 - }, - "css-loader": { - "version": "6.7.1", - "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.1.tgz", - "integrity": "sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw==", - "dev": true, - "requires": { - "icss-utils": "^5.1.0", - "postcss": "^8.4.7", - "postcss-modules-extract-imports": "^3.0.0", - "postcss-modules-local-by-default": "^4.0.0", - "postcss-modules-scope": "^3.0.0", - "postcss-modules-values": "^4.0.0", - "postcss-value-parser": "^4.2.0", - "semver": "^7.3.5" - } - }, - "css-minimizer-webpack-plugin": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz", - "integrity": "sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==", - "dev": true, - "requires": { - "cssnano": "^5.0.6", - "jest-worker": "^27.0.2", - "postcss": "^8.3.5", - "schema-utils": "^4.0.0", - "serialize-javascript": "^6.0.0", - "source-map": "^0.6.1" - }, - "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" - } + "node_modules/clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true, + "engines": { + "node": ">=6" + } }, - "ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.3" - } + "node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } }, - "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/cli-spinners": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", + "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", + "dev": true, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - } + "node_modules/cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "dependencies": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } }, - "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 - } - } - }, - "css-select": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", - "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", - "dev": true, - "requires": { - "boolbase": "^1.0.0", - "css-what": "^6.0.1", - "domhandler": "^4.3.1", - "domutils": "^2.8.0", - "nth-check": "^2.0.1" - } - }, - "css-to-react-native": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz", - "integrity": "sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==", - "requires": { - "camelize": "^1.0.0", - "css-color-keywords": "^1.0.0", - "postcss-value-parser": "^4.0.2" - } - }, - "css-tree": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", - "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", - "dev": true, - "requires": { - "mdn-data": "2.0.14", - "source-map": "^0.6.1" - }, - "dependencies": { - "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 - } - } - }, - "css-what": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", - "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", - "dev": true - }, - "css.escape": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", - "integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=", - "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 - }, - "cssnano": { - "version": "5.1.7", - "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.7.tgz", - "integrity": "sha512-pVsUV6LcTXif7lvKKW9ZrmX+rGRzxkEdJuVJcp5ftUjWITgwam5LMZOgaTvUrWPkcORBey6he7JKb4XAJvrpKg==", - "dev": true, - "requires": { - "cssnano-preset-default": "^5.2.7", - "lilconfig": "^2.0.3", - "yaml": "^1.10.2" - } - }, - "cssnano-preset-default": { - "version": "5.2.7", - "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.7.tgz", - "integrity": "sha512-JiKP38ymZQK+zVKevphPzNSGHSlTI+AOwlasoSRtSVMUU285O7/6uZyd5NbW92ZHp41m0sSHe6JoZosakj63uA==", - "dev": true, - "requires": { - "css-declaration-sorter": "^6.2.2", - "cssnano-utils": "^3.1.0", - "postcss-calc": "^8.2.3", - "postcss-colormin": "^5.3.0", - "postcss-convert-values": "^5.1.0", - "postcss-discard-comments": "^5.1.1", - "postcss-discard-duplicates": "^5.1.0", - "postcss-discard-empty": "^5.1.1", - "postcss-discard-overridden": "^5.1.0", - "postcss-merge-longhand": "^5.1.4", - "postcss-merge-rules": "^5.1.1", - "postcss-minify-font-values": "^5.1.0", - "postcss-minify-gradients": "^5.1.1", - "postcss-minify-params": "^5.1.2", - "postcss-minify-selectors": "^5.2.0", - "postcss-normalize-charset": "^5.1.0", - "postcss-normalize-display-values": "^5.1.0", - "postcss-normalize-positions": "^5.1.0", - "postcss-normalize-repeat-style": "^5.1.0", - "postcss-normalize-string": "^5.1.0", - "postcss-normalize-timing-functions": "^5.1.0", - "postcss-normalize-unicode": "^5.1.0", - "postcss-normalize-url": "^5.1.0", - "postcss-normalize-whitespace": "^5.1.1", - "postcss-ordered-values": "^5.1.1", - "postcss-reduce-initial": "^5.1.0", - "postcss-reduce-transforms": "^5.1.0", - "postcss-svgo": "^5.1.0", - "postcss-unique-selectors": "^5.1.1" - } - }, - "cssnano-utils": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", - "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", - "dev": true, - "requires": {} - }, - "csso": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", - "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", - "dev": true, - "requires": { - "css-tree": "^1.1.2" - } - }, - "cssom": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", - "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", - "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 - } - } - }, - "csstype": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz", - "integrity": "sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==" - }, - "currently-unhandled": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", - "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==", - "dev": true, - "requires": { - "array-find-index": "^1.0.1" - } - }, - "damerau-levenshtein": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", - "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", - "dev": true - }, - "data-urls": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", - "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", - "dev": true, - "requires": { - "abab": "^2.0.3", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.0.0" - } - }, - "date-fns": { - "version": "2.28.0", - "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz", - "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==", - "dev": true - }, - "dayjs": { - "version": "1.11.6", - "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.6.tgz", - "integrity": "sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ==" - }, - "de-indent": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", - "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=", - "dev": true - }, - "debounce-fn": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-4.0.0.tgz", - "integrity": "sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==", - "requires": { - "mimic-fn": "^3.0.0" - }, - "dependencies": { - "mimic-fn": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", - "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==" - } - } - }, - "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.3.1", - "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", - "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", - "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", - "dev": true - }, - "decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "dev": true, - "requires": { - "mimic-response": "^3.1.0" - }, - "dependencies": { - "mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "dev": true - } - } - }, - "dedent": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", - "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", - "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==", - "dev": true - }, - "deepmerge": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", - "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" - }, - "default-gateway": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", - "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", - "dev": true, - "requires": { - "execa": "^5.0.0" - } - }, - "defaults": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", - "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", - "dev": true, - "requires": { - "clone": "^1.0.2" - } - }, - "defer-to-connect": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", - "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", - "dev": true - }, - "define-lazy-prop": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", - "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", - "dev": true - }, - "define-properties": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", - "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", - "dev": true, - "requires": { - "has-property-descriptors": "^1.0.0", - "object-keys": "^1.1.1" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - } - }, - "delayed-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", - "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" - }, - "delegates": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", - "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", - "dev": true - }, - "depd": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", - "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", - "dev": true - }, - "destroy": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", - "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", - "dev": true - }, - "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==", - "dev": true - }, - "detect-node-es": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", - "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" - }, - "detect-port": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz", - "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==", - "dev": true, - "requires": { - "address": "^1.0.1", - "debug": "^2.6.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } + "node_modules/cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, - "diff-sequences": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", - "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", - "dev": true - }, - "dir-compare": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-3.3.0.tgz", - "integrity": "sha512-J7/et3WlGUCxjdnD3HAAzQ6nsnc0WL6DD7WcwJb7c39iH1+AWfg+9OqzJNaI6PkBwBvm1mhZNL9iY/nRiZXlPg==", - "dev": true, - "requires": { - "buffer-equal": "^1.0.0", - "minimatch": "^3.0.4" - } - }, - "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" - } - }, - "dmg-builder": { - "version": "24.0.0-alpha.13", - "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-24.0.0-alpha.13.tgz", - "integrity": "sha512-+2tnaKVKEboVjXeR+CcoOPy/cnTKY+QVPw4sgS2Z50/GO5tjKAttQJ7ZoCl7BUIqBuP9P7ZvCG7mUzhZKHofgQ==", - "dev": true, - "requires": { - "app-builder-lib": "24.0.0-alpha.13", - "builder-util": "24.0.0-alpha.13", - "builder-util-runtime": "9.2.0-alpha.3", - "dmg-license": "^1.0.11", - "fs-extra": "^10.1.0", - "iconv-lite": "^0.6.2", - "js-yaml": "^4.1.0" - }, - "dependencies": { - "builder-util-runtime": { - "version": "9.2.0-alpha.3", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.0-alpha.3.tgz", - "integrity": "sha512-1pOggEqknxVyhdASumips0/RaMaXwSCQMzwhk2jeOGOotBQuOHQHVy25kH5OaeXSFx9L7PckZHXjwZauD72zRw==", - "dev": true, - "requires": { - "debug": "^4.3.4", - "sax": "^1.2.4" - } + "node_modules/clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true, + "engines": { + "node": ">=0.8" + } }, - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } + "node_modules/clone-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", + "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", + "dev": true, + "engines": { + "node": ">= 0.10" + } }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } + "node_modules/clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + }, + "engines": { + "node": ">=6" + } }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } - } - }, - "dmg-license": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.11.tgz", - "integrity": "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==", - "dev": true, - "optional": true, - "requires": { - "@types/plist": "^3.0.1", - "@types/verror": "^1.10.3", - "ajv": "^6.10.0", - "crc": "^3.8.0", - "iconv-corefoundation": "^1.1.7", - "plist": "^3.0.4", - "smart-buffer": "^4.0.2", - "verror": "^1.10.0" - } - }, - "dns-equal": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", - "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", - "dev": true - }, - "dns-packet": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.0.tgz", - "integrity": "sha512-rza3UH1LwdHh9qyPXp8lkwpjSNk/AMD3dPytUoRoqnypDUhY0xvbdmVhWOfxO68frEfV9BU8V12Ez7ZsHGZpCQ==", - "dev": true, - "requires": { - "@leichtgewicht/ip-codec": "^2.0.1" - } - }, - "doctrine": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", - "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } - }, - "dom-accessibility-api": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.13.tgz", - "integrity": "sha512-R305kwb5CcMDIpSHUnLyIAp7SrSPBx6F0VfQFB3M75xVMHhXJJIdePYgbPPh1o57vCHNu5QztokWUPsLjWzFqw==", - "dev": true - }, - "dom-converter": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", - "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", - "dev": true, - "requires": { - "utila": "~0.4" - } - }, - "dom-helpers": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", - "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", - "requires": { - "@babel/runtime": "^7.8.7", - "csstype": "^3.0.2" - } - }, - "dom-serializer": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", - "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", - "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.2.0", - "entities": "^2.0.0" - } - }, - "domelementtype": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", - "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", - "dev": true - }, - "domexception": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", - "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", - "dev": true, - "requires": { - "webidl-conversions": "^5.0.0" - }, - "dependencies": { - "webidl-conversions": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", - "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", - "dev": true - } - } - }, - "domhandler": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", - "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", - "dev": true, - "requires": { - "domelementtype": "^2.2.0" - } - }, - "domutils": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", - "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", - "dev": true, - "requires": { - "dom-serializer": "^1.0.1", - "domelementtype": "^2.2.0", - "domhandler": "^4.2.0" - } - }, - "dot-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", - "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", - "dev": true, - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "dot-prop": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", - "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", - "dev": true, - "requires": { - "is-obj": "^2.0.0" - } - }, - "dotenv": { - "version": "9.0.2", - "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz", - "integrity": "sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==", - "dev": true - }, - "dotenv-expand": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", - "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", - "dev": true - }, - "duplexer": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", - "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", - "dev": true - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, - "ee-first": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", - "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", - "dev": true - }, - "ejs": { - "version": "3.1.9", - "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", - "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", - "dev": true, - "requires": { - "jake": "^10.8.5" - } - }, - "electron": { - "version": "22.3.1", - "resolved": "https://registry.npmjs.org/electron/-/electron-22.3.1.tgz", - "integrity": "sha512-iDltL9j12bINK3aOp8ZoGq4NFBFjJhw1AYHelbWj93XUCAIT4fdA+PRsq0aaTHg3bthLLlLRvIZVgNsZPqWcqg==", - "dev": true, - "requires": { - "@electron/get": "^2.0.0", - "@types/node": "^16.11.26", - "extract-zip": "^2.0.1" - }, - "dependencies": { - "@types/node": { - "version": "16.18.13", - "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.13.tgz", - "integrity": "sha512-l0/3XZ153UTlNOnZK8xSNoJlQda9/WnYgiTdcKKPJSZjdjI9MU+A9oMXOesAWLSnqAaaJhj3qfQsU07Dr8OUwg==", - "dev": true - } - } - }, - "electron-builder": { - "version": "24.0.0-alpha.13", - "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-24.0.0-alpha.13.tgz", - "integrity": "sha512-YLDlzySvfBZKoCp4hNf4cx849vrew+3jxfNx5malT2PGd3y2GPYKCEvFc15AGShmah2Pt0gGoVQRot/dC6Nb9g==", - "dev": true, - "requires": { - "@types/yargs": "^17.0.16", - "app-builder-lib": "24.0.0-alpha.13", - "builder-util": "24.0.0-alpha.13", - "builder-util-runtime": "9.2.0-alpha.3", - "chalk": "^4.1.2", - "dmg-builder": "24.0.0-alpha.13", - "fs-extra": "^10.1.0", - "is-ci": "^3.0.0", - "lazy-val": "^1.0.5", - "read-config-file": "6.3.2", - "simple-update-notifier": "^1.1.0", - "yargs": "^17.6.2" - }, - "dependencies": { - "builder-util-runtime": { - "version": "9.2.0-alpha.3", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.0-alpha.3.tgz", - "integrity": "sha512-1pOggEqknxVyhdASumips0/RaMaXwSCQMzwhk2jeOGOotBQuOHQHVy25kH5OaeXSFx9L7PckZHXjwZauD72zRw==", - "dev": true, - "requires": { - "debug": "^4.3.4", - "sax": "^1.2.4" - } + "node_modules/clone-regexp": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz", + "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==", + "dev": true, + "dependencies": { + "is-regexp": "^2.0.0" + }, + "engines": { + "node": ">=6" + } }, - "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" - } + "node_modules/clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + } }, - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } + "node_modules/clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } + "node_modules/cloneable-readable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", + "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "process-nextick-args": "^2.0.0", + "readable-stream": "^2.3.5" + } }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true + "node_modules/clsx": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz", + "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==", + "engines": { + "node": ">=6" + } }, - "yargs": { - "version": "17.6.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", - "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", - "dev": true, - "requires": { - "cliui": "^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.1.1" - } + "node_modules/cmdk": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-0.2.0.tgz", + "integrity": "sha512-JQpKvEOb86SnvMZbYaFKYhvzFntWBeSZdyii0rZPhKJj9uwJBxu4DaVYDrRN7r3mPop56oPhRw+JYWTKs66TYw==", + "dependencies": { + "@radix-ui/react-dialog": "1.0.0", + "command-score": "0.1.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } }, - "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 - } - } - }, - "electron-debug": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/electron-debug/-/electron-debug-3.2.0.tgz", - "integrity": "sha512-7xZh+LfUvJ52M9rn6N+tPuDw6oRAjxUj9SoxAZfJ0hVCXhZCsdkrSt7TgXOiWiEOBgEV8qwUIO/ScxllsPS7ow==", - "requires": { - "electron-is-dev": "^1.1.0", - "electron-localshortcut": "^3.1.0" - } - }, - "electron-devtools-installer": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/electron-devtools-installer/-/electron-devtools-installer-3.2.0.tgz", - "integrity": "sha512-t3UczsYugm4OAbqvdImMCImIMVdFzJAHgbwHpkl5jmfu1izVgUcP/mnrPqJIpEeCK1uZGpt+yHgWEN+9EwoYhQ==", - "dev": true, - "requires": { - "rimraf": "^3.0.2", - "semver": "^7.2.1", - "tslib": "^2.1.0", - "unzip-crx-3": "^0.2.0" - } - }, - "electron-is-accelerator": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/electron-is-accelerator/-/electron-is-accelerator-0.1.2.tgz", - "integrity": "sha1-UJ5RDCala1Xhf4Y6SwThEYRqsns=" - }, - "electron-is-dev": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-1.2.0.tgz", - "integrity": "sha512-R1oD5gMBPS7PVU8gJwH6CtT0e6VSoD0+SzSnYpNm+dBkcijgA+K7VAMHDfnRq/lkKPZArpzplTW6jfiMYosdzw==" - }, - "electron-localshortcut": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/electron-localshortcut/-/electron-localshortcut-3.2.1.tgz", - "integrity": "sha512-DWvhKv36GsdXKnaFFhEiK8kZZA+24/yFLgtTwJJHc7AFgDjNRIBJZ/jq62Y/dWv9E4ypYwrVWN2bVrCYw1uv7Q==", - "requires": { - "debug": "^4.0.1", - "electron-is-accelerator": "^0.1.0", - "keyboardevent-from-electron-accelerator": "^2.0.0", - "keyboardevents-areequal": "^0.2.1" - } - }, - "electron-log": { - "version": "4.4.6", - "resolved": "https://registry.npmjs.org/electron-log/-/electron-log-4.4.6.tgz", - "integrity": "sha512-nirYgRdY+F+vclr8ijdwy2vW03IzFpDHTaKNWu76dEN21Y76+smcES5knS7cgHUUB0qNLOi8vZO36taakjbSXA==" - }, - "electron-notarize": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-1.2.1.tgz", - "integrity": "sha512-u/ECWhIrhkSQpZM4cJzVZ5TsmkaqrRo5LDC/KMbGF0sPkm53Ng59+M0zp8QVaql0obfJy9vlVT+4iOkAi2UDlA==", - "dev": true, - "requires": { - "debug": "^4.1.1", - "fs-extra": "^9.0.1" - }, - "dependencies": { - "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", - "dev": true, - "requires": { - "at-least-node": "^1.0.0", - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } + "node_modules/co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true, + "engines": { + "iojs": ">= 1.0.0", + "node": ">= 0.12.0" + } }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } + "node_modules/collapse-white-space": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", + "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } - } - }, - "electron-publish": { - "version": "24.0.0-alpha.13", - "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-24.0.0-alpha.13.tgz", - "integrity": "sha512-ur3XrX/8vLfZV+UisnbFvinX2ETD+Jdq8mUqG1sKlgITsQdjjjt8vKLiBgE71YhgDqFylpmFeWF8MJT91sSPnQ==", - "dev": true, - "requires": { - "@types/fs-extra": "^9.0.11", - "builder-util": "24.0.0-alpha.13", - "builder-util-runtime": "9.2.0-alpha.3", - "chalk": "^4.1.2", - "fs-extra": "^10.1.0", - "lazy-val": "^1.0.5", - "mime": "^2.5.2" - }, - "dependencies": { - "builder-util-runtime": { - "version": "9.2.0-alpha.3", - "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.0-alpha.3.tgz", - "integrity": "sha512-1pOggEqknxVyhdASumips0/RaMaXwSCQMzwhk2jeOGOotBQuOHQHVy25kH5OaeXSFx9L7PckZHXjwZauD72zRw==", - "dev": true, - "requires": { - "debug": "^4.3.4", - "sax": "^1.2.4" - } + "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 }, - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } + "node_modules/collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", + "dev": true, + "dependencies": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } + "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==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } - } - }, - "electron-store": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-8.1.0.tgz", - "integrity": "sha512-2clHg/juMjOH0GT9cQ6qtmIvK183B39ZXR0bUoPwKwYHJsEF3quqyDzMFUAu+0OP8ijmN2CbPRAelhNbWUbzwA==", - "requires": { - "conf": "^10.2.0", - "type-fest": "^2.17.0" - }, - "dependencies": { - "type-fest": { - "version": "2.19.0", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", - "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==" - } - } - }, - "electron-to-chromium": { - "version": "1.4.284", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", - "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" - }, - "electron-updater": { - "version": "4.6.5", - "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-4.6.5.tgz", - "integrity": "sha512-kdTly8O9mSZfm9fslc1mnCY+mYOeaYRy7ERa2Fed240u01BKll3aiupzkd07qKw69KvhBSzuHroIW3mF0D8DWA==", - "requires": { - "@types/semver": "^7.3.6", - "builder-util-runtime": "8.9.2", - "fs-extra": "^10.0.0", - "js-yaml": "^4.1.0", - "lazy-val": "^1.0.5", - "lodash.escaperegexp": "^4.1.2", - "lodash.isequal": "^4.5.0", - "semver": "^7.3.5" - }, - "dependencies": { - "fs-extra": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", - "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } + "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==", + "dev": true }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } + "node_modules/color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true, + "bin": { + "color-support": "bin.js" + } }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" - } - } - }, - "electronmon": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/electronmon/-/electronmon-2.0.2.tgz", - "integrity": "sha512-Yw1CXEp5HJT9P6Sns3UP3Krwm5eb2JKqTRAVczKdsUa+U/dMTgONwKIHkPbKSSmtyTV+5JwobxkhFPiRgegObA==", - "dev": true, - "requires": { - "chalk": "^3.0.0", - "import-from": "^3.0.0", - "runtime-required": "^1.1.0", - "watchboy": "^0.4.3" - }, - "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" - } - } - } - }, - "emittery": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", - "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", - "dev": true - }, - "emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "emojis-list": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", - "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", - "dev": true - }, - "encodeurl": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", - "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", - "dev": true - }, - "encoding": { - "version": "0.1.13", - "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", - "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", - "dev": true, - "optional": true, - "requires": { - "iconv-lite": "^0.6.2" - } - }, - "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==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz", - "integrity": "sha1-TW5omzcl+GCQknzMhs2fFjW4ni4=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.2.0", - "tapable": "^0.1.8" - }, - "dependencies": { - "tapable": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.1.10.tgz", - "integrity": "sha1-KcNXB8K3DlDQdIK10gLo7URtr9Q=", - "dev": true - } - } - }, - "ensure-posix-path": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/ensure-posix-path/-/ensure-posix-path-1.1.1.tgz", - "integrity": "sha512-VWU0/zXzVbeJNXvME/5EmLuEj2TauvoaTz6aFYK1Z92JCBlDlZ3Gu0tuGR42kpW1754ywTs+QB0g5TP0oj9Zaw==", - "dev": true - }, - "entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "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==" - }, - "envinfo": { - "version": "7.8.1", - "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", - "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", - "dev": true - }, - "eol": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/eol/-/eol-0.9.1.tgz", - "integrity": "sha512-Ds/TEoZjwggRoz/Q2O7SE3i4Jm66mqTDfmdHdq/7DKVk3bro9Q8h6WdXKdPqFLMoqxrDK5SVRzHVPOS6uuGtrg==", - "dev": true - }, - "err-code": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", - "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", - "dev": 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==", - "requires": { - "is-arrayish": "^0.2.1" - } - }, - "error-stack-parser": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.7.tgz", - "integrity": "sha512-chLOW0ZGRf4s8raLrDxa5sdkvPec5YdvwbFnqJme4rk0rFajP8mPtrDL1+I+CwrQDCjswDA5sREX7jYQDQs9vA==", - "dev": true, - "requires": { - "stackframe": "^1.1.1" - } - }, - "es-abstract": { - "version": "1.20.5", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.5.tgz", - "integrity": "sha512-7h8MM2EQhsCA7pU/Nv78qOXFpD8Rhqd12gYiSJVkrH9+e8VuA8JlPJK/hQjjlLv6pJvx/z1iRFKzYb0XT/RuAQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "es-to-primitive": "^1.2.1", - "function-bind": "^1.1.1", - "function.prototype.name": "^1.1.5", - "get-intrinsic": "^1.1.3", - "get-symbol-description": "^1.0.0", - "gopd": "^1.0.1", - "has": "^1.0.3", - "has-property-descriptors": "^1.0.0", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "is-callable": "^1.2.7", - "is-negative-zero": "^2.0.2", - "is-regex": "^1.1.4", - "is-shared-array-buffer": "^1.0.2", - "is-string": "^1.0.7", - "is-weakref": "^1.0.2", - "object-inspect": "^1.12.2", - "object-keys": "^1.1.1", - "object.assign": "^4.1.4", - "regexp.prototype.flags": "^1.4.3", - "safe-regex-test": "^1.0.0", - "string.prototype.trimend": "^1.0.6", - "string.prototype.trimstart": "^1.0.6", - "unbox-primitive": "^1.0.2" - } - }, - "es-module-lexer": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.2.1.tgz", - "integrity": "sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg==", - "dev": true - }, - "es-shim-unscopables": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", - "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", - "dev": true, - "requires": { - "has": "^1.0.3" - } - }, - "es-to-primitive": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", - "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "es6-error": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", - "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", - "dev": true, - "optional": true - }, - "escalade": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", - "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" - }, - "escape-html": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", - "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", - "dev": true - }, - "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": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2", - "type-check": "~0.3.2" - } + "node_modules/colord": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.2.tgz", + "integrity": "sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ==", + "dev": true }, - "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" - } + "node_modules/colorette": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", + "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", + "dev": true }, - "prelude-ls": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", - "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", - "dev": true + "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==", + "dependencies": { + "delayed-stream": "~1.0.0" + }, + "engines": { + "node": ">= 0.8" + } }, - "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, - "optional": true + "node_modules/command-score": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/command-score/-/command-score-0.1.2.tgz", + "integrity": "sha512-VtDvQpIJBvBatnONUsPzXYFVKQQAhuf3XTNOAsdBxCNO/QCtUUd8LSgjn0GVarBkCad6aJCZfXgrjYbl/KRr7w==" }, - "type-check": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", - "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", - "dev": true, - "requires": { - "prelude-ls": "~1.1.2" - } - } - } - }, - "eslint": { - "version": "8.30.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.30.0.tgz", - "integrity": "sha512-MGADB39QqYuzEGov+F/qb18r4i7DohCDOfatHaxI2iGlPuC65bwG2gxgO+7DkyL38dRFaRH7RaRAgU6JKL9rMQ==", - "dev": true, - "requires": { - "@eslint/eslintrc": "^1.4.0", - "@humanwhocodes/config-array": "^0.11.8", - "@humanwhocodes/module-importer": "^1.0.1", - "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", - "chalk": "^4.0.0", - "cross-spawn": "^7.0.2", - "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.19.0", - "grapheme-splitter": "^1.0.4", - "ignore": "^5.2.0", - "import-fresh": "^3.0.0", - "imurmurhash": "^0.1.4", - "is-glob": "^4.0.0", - "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", - "js-yaml": "^4.1.0", - "json-stable-stringify-without-jsonify": "^1.0.1", - "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" - }, - "dependencies": { - "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==", - "dev": true, - "requires": { - "esrecurse": "^4.3.0", - "estraverse": "^5.2.0" - } - } - } - }, - "eslint-config-airbnb-base": { - "version": "15.0.0", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", - "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", - "dev": true, - "requires": { - "confusing-browser-globals": "^1.0.10", - "object.assign": "^4.1.2", - "object.entries": "^1.1.5", - "semver": "^6.3.0" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "eslint-config-erb": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-config-erb/-/eslint-config-erb-4.0.3.tgz", - "integrity": "sha512-qZeiUSQanpCKKazkLzIvVaoM9NZcNvqhO7gYZ2jaEpBmadCu1aOzzvMMtjsoxaDytRQt6mt+uXjWGyJNqUYusw==", - "dev": true, - "requires": { - "@typescript-eslint/eslint-plugin": "^4.29.2", - "@typescript-eslint/parser": "^4.29.3", - "eslint-config-airbnb": "^18.2.1", - "eslint-config-airbnb-typescript": "^13.0.0", - "eslint-config-prettier": "^8.3.0", - "eslint-import-resolver-webpack": "^0.13.1", - "eslint-plugin-compat": "^3.13.0", - "eslint-plugin-import": "^2.24.1", - "eslint-plugin-jest": "^24.4.0", - "eslint-plugin-jsx-a11y": "6.4.1", - "eslint-plugin-prettier": "^3.4.1", - "eslint-plugin-promise": "^5.1.0", - "eslint-plugin-react": "^7.24.0", - "eslint-plugin-react-hooks": "^4.2.0" - }, - "dependencies": { - "@mdn/browser-compat-data": { - "version": "3.3.14", - "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-3.3.14.tgz", - "integrity": "sha512-n2RC9d6XatVbWFdHLimzzUJxJ1KY8LdjqrW6YvGPiRmsHkhOUx74/Ct10x5Yo7bC/Jvqx7cDEW8IMPv/+vwEzA==", - "dev": true + "node_modules/commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true, + "engines": { + "node": ">= 6" + } }, - "@typescript-eslint/eslint-plugin": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", - "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", - "dev": true, - "requires": { - "@typescript-eslint/experimental-utils": "4.33.0", - "@typescript-eslint/scope-manager": "4.33.0", - "debug": "^4.3.1", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.1.0", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } + "node_modules/common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "dev": true }, - "@typescript-eslint/parser": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", - "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", - "dev": true, - "requires": { - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "debug": "^4.3.1" - } + "node_modules/compare-version": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", + "integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "@typescript-eslint/scope-manager": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" - } + "node_modules/component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true }, - "@typescript-eslint/types": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", - "dev": true + "node_modules/compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "dependencies": { + "mime-db": ">= 1.43.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } }, - "@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - } + "node_modules/compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "dependencies": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } }, - "@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", - "dev": true, - "requires": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" - } + "node_modules/compression/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } }, - "aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.10.2", - "@babel/runtime-corejs3": "^7.10.2" - } + "node_modules/compression/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true }, - "eslint-config-airbnb": { - "version": "18.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-18.2.1.tgz", - "integrity": "sha512-glZNDEZ36VdlZWoxn/bUR1r/sdFKPd1mHPbqUtkctgNG4yT2DLLtJ3D+yCV+jzZCc2V1nBVkmdknOJBZ5Hc0fg==", - "dev": true, - "requires": { - "eslint-config-airbnb-base": "^14.2.1", - "object.assign": "^4.1.2", - "object.entries": "^1.1.2" - }, - "dependencies": { - "eslint-config-airbnb-base": { - "version": "14.2.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz", - "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==", - "dev": true, - "requires": { + "node_modules/concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "node_modules/concurrently": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.1.0.tgz", + "integrity": "sha512-Bz0tMlYKZRUDqJlNiF/OImojMB9ruKUz6GCfmhFnSapXgPe+3xzY4byqoKG9tUZ7L2PGEUjfLPOLfIX3labnmw==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "date-fns": "^2.16.1", + "lodash": "^4.17.21", + "rxjs": "^6.6.3", + "spawn-command": "^0.0.2-1", + "supports-color": "^8.1.0", + "tree-kill": "^1.2.2", + "yargs": "^16.2.0" + }, + "bin": { + "concurrently": "dist/bin/concurrently.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.0 || >=16.0.0" + } + }, + "node_modules/concurrently/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/conf": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/conf/-/conf-10.2.0.tgz", + "integrity": "sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==", + "dependencies": { + "ajv": "^8.6.3", + "ajv-formats": "^2.1.1", + "atomically": "^1.7.0", + "debounce-fn": "^4.0.0", + "dot-prop": "^6.0.1", + "env-paths": "^2.2.1", + "json-schema-typed": "^7.0.3", + "onetime": "^5.1.2", + "pkg-up": "^3.1.0", + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/conf/node_modules/ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/conf/node_modules/dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/conf/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==" + }, + "node_modules/config-file-ts": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/config-file-ts/-/config-file-ts-0.2.4.tgz", + "integrity": "sha512-cKSW0BfrSaAUnxpgvpXPLaaW/umg4bqg4k3GO1JqlRfpx+d5W0GDXznCMkWotJQek5Mmz1MJVChQnz3IVaeMZQ==", + "dev": true, + "dependencies": { + "glob": "^7.1.6", + "typescript": "^4.0.2" + } + }, + "node_modules/confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", + "dev": true + }, + "node_modules/connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "safe-buffer": "5.2.1" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/content-disposition/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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/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==", + "dev": true, + "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==", + "dependencies": { + "safe-buffer": "~5.1.1" + } + }, + "node_modules/cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "node_modules/copy-anything": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.2.tgz", + "integrity": "sha512-CzATjGXzUQ0EvuvgOCI6A4BGOo2bcVx8B+eC2nF862iv9fopnPQwlrbACakNCHRIJbCSBj+J/9JeDf60k64MkA==", + "dependencies": { + "is-what": "^4.1.6" + }, + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/core-js": { + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.21.1.tgz", + "integrity": "sha512-FRq5b/VMrWlrmCzwRrpDYNxyHP9BcAZC+xHJaqTgIE5091ZV1NTmyh0sGOg5XqpnHvR0svdy0sv1gWA1zmhxig==", + "deprecated": "core-js@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js.", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "node_modules/core-js-pure": { + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.21.1.tgz", + "integrity": "sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ==", + "deprecated": "core-js-pure@<3.23.3 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Some versions have web compatibility issues. Please, upgrade your dependencies to the actual version of core-js-pure.", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, + "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==", + "dev": true + }, + "node_modules/cosmiconfig": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", + "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "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" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/crc": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", + "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", + "dev": true, + "optional": true, + "dependencies": { + "buffer": "^5.1.0" + } + }, + "node_modules/create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "node_modules/cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.1" + }, + "bin": { + "cross-env": "src/bin/cross-env.js", + "cross-env-shell": "src/bin/cross-env-shell.js" + }, + "engines": { + "node": ">=10.14", + "npm": ">=6", + "yarn": ">=1" + } + }, + "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==", + "dev": true, + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", + "engines": { + "node": "*" + } + }, + "node_modules/css": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", + "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.4", + "source-map": "^0.6.1", + "source-map-resolve": "^0.6.0" + } + }, + "node_modules/css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==", + "engines": { + "node": ">=4" + } + }, + "node_modules/css-declaration-sorter": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.2.2.tgz", + "integrity": "sha512-Ufadglr88ZLsrvS11gjeu/40Lw74D9Am/Jpr3LlYm5Q4ZP5KdlUhG+6u2EjyXeZcxmZ2h1ebCKngDjolpeLHpg==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14" + }, + "peerDependencies": { + "postcss": "^8.0.9" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=12.22" + } + }, + "node_modules/css-loader": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.1.tgz", + "integrity": "sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw==", + "dev": true, + "dependencies": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.7", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.3.5" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/css-minimizer-webpack-plugin": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz", + "integrity": "sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==", + "dev": true, + "dependencies": { + "cssnano": "^5.0.6", + "jest-worker": "^27.0.2", + "postcss": "^8.3.5", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "@parcel/css": { + "optional": true + }, + "clean-css": { + "optional": true + }, + "csso": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "dev": 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" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/css-minimizer-webpack-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/css-minimizer-webpack-plugin/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/css-minimizer-webpack-plugin/node_modules/schema-utils": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/css-minimizer-webpack-plugin/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css-to-react-native": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz", + "integrity": "sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==", + "dependencies": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, + "node_modules/css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dev": true, + "dependencies": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/css-tree/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true, + "engines": { + "node": ">= 6" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" + } + }, + "node_modules/css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=", + "dev": true + }, + "node_modules/css/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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, + "bin": { + "cssesc": "bin/cssesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/cssnano": { + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.7.tgz", + "integrity": "sha512-pVsUV6LcTXif7lvKKW9ZrmX+rGRzxkEdJuVJcp5ftUjWITgwam5LMZOgaTvUrWPkcORBey6he7JKb4XAJvrpKg==", + "dev": true, + "dependencies": { + "cssnano-preset-default": "^5.2.7", + "lilconfig": "^2.0.3", + "yaml": "^1.10.2" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/cssnano" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/cssnano-preset-default": { + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.7.tgz", + "integrity": "sha512-JiKP38ymZQK+zVKevphPzNSGHSlTI+AOwlasoSRtSVMUU285O7/6uZyd5NbW92ZHp41m0sSHe6JoZosakj63uA==", + "dev": true, + "dependencies": { + "css-declaration-sorter": "^6.2.2", + "cssnano-utils": "^3.1.0", + "postcss-calc": "^8.2.3", + "postcss-colormin": "^5.3.0", + "postcss-convert-values": "^5.1.0", + "postcss-discard-comments": "^5.1.1", + "postcss-discard-duplicates": "^5.1.0", + "postcss-discard-empty": "^5.1.1", + "postcss-discard-overridden": "^5.1.0", + "postcss-merge-longhand": "^5.1.4", + "postcss-merge-rules": "^5.1.1", + "postcss-minify-font-values": "^5.1.0", + "postcss-minify-gradients": "^5.1.1", + "postcss-minify-params": "^5.1.2", + "postcss-minify-selectors": "^5.2.0", + "postcss-normalize-charset": "^5.1.0", + "postcss-normalize-display-values": "^5.1.0", + "postcss-normalize-positions": "^5.1.0", + "postcss-normalize-repeat-style": "^5.1.0", + "postcss-normalize-string": "^5.1.0", + "postcss-normalize-timing-functions": "^5.1.0", + "postcss-normalize-unicode": "^5.1.0", + "postcss-normalize-url": "^5.1.0", + "postcss-normalize-whitespace": "^5.1.1", + "postcss-ordered-values": "^5.1.1", + "postcss-reduce-initial": "^5.1.0", + "postcss-reduce-transforms": "^5.1.0", + "postcss-svgo": "^5.1.0", + "postcss-unique-selectors": "^5.1.1" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/cssnano-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", + "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dev": true, + "dependencies": { + "css-tree": "^1.1.2" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "dev": true + }, + "node_modules/cssstyle": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-2.3.0.tgz", + "integrity": "sha512-AZL67abkUzIuvcHqk7c09cezpGNcxUxU4Ioi/05xHk4DQeTkWmGYftIE6ctU6AEt+Gn4n1lDStOtj7FKycP71A==", + "dev": true, + "dependencies": { + "cssom": "~0.3.6" + }, + "engines": { + "node": ">=8" + } + }, + "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/csstype": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz", + "integrity": "sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==" + }, + "node_modules/currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==", + "dev": true, + "dependencies": { + "array-find-index": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true + }, + "node_modules/data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dev": true, + "dependencies": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/date-fns": { + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz", + "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==", + "dev": true, + "engines": { + "node": ">=0.11" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/date-fns" + } + }, + "node_modules/dayjs": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.6.tgz", + "integrity": "sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ==" + }, + "node_modules/de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=", + "dev": true + }, + "node_modules/debounce-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-4.0.0.tgz", + "integrity": "sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==", + "dependencies": { + "mimic-fn": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/debounce-fn/node_modules/mimic-fn": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", + "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "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, + "engines": { + "node": ">=0.10.0" + } + }, + "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, + "dependencies": { + "decamelize": "^1.1.0", + "map-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/decimal.js": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", + "dev": true + }, + "node_modules/decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/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==", + "dev": 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": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "dev": 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==", + "dev": true + }, + "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==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dev": true, + "dependencies": { + "execa": "^5.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "node_modules/defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "dependencies": { + "clone": "^1.0.2" + } + }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "dev": true, + "dependencies": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=", + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "node_modules/depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true, + "engines": { + "node": ">= 0.8", + "npm": "1.2.8000 || >= 1.4.16" + } + }, + "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, + "engines": { + "node": ">=8" + } + }, + "node_modules/detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==", + "dev": true + }, + "node_modules/detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + }, + "node_modules/detect-port": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz", + "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==", + "dev": true, + "dependencies": { + "address": "^1.0.1", + "debug": "^2.6.0" + }, + "bin": { + "detect": "bin/detect-port", + "detect-port": "bin/detect-port" + }, + "engines": { + "node": ">= 4.2.1" + } + }, + "node_modules/detect-port/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/detect-port/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true, + "engines": { + "node": ">=0.3.1" + } + }, + "node_modules/diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/dir-compare": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-3.3.0.tgz", + "integrity": "sha512-J7/et3WlGUCxjdnD3HAAzQ6nsnc0WL6DD7WcwJb7c39iH1+AWfg+9OqzJNaI6PkBwBvm1mhZNL9iY/nRiZXlPg==", + "dev": true, + "dependencies": { + "buffer-equal": "^1.0.0", + "minimatch": "^3.0.4" + } + }, + "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, + "dependencies": { + "path-type": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dmg-builder": { + "version": "24.0.0-alpha.13", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-24.0.0-alpha.13.tgz", + "integrity": "sha512-+2tnaKVKEboVjXeR+CcoOPy/cnTKY+QVPw4sgS2Z50/GO5tjKAttQJ7ZoCl7BUIqBuP9P7ZvCG7mUzhZKHofgQ==", + "dev": true, + "dependencies": { + "app-builder-lib": "24.0.0-alpha.13", + "builder-util": "24.0.0-alpha.13", + "builder-util-runtime": "9.2.0-alpha.3", + "fs-extra": "^10.1.0", + "iconv-lite": "^0.6.2", + "js-yaml": "^4.1.0" + }, + "optionalDependencies": { + "dmg-license": "^1.0.11" + } + }, + "node_modules/dmg-builder/node_modules/builder-util-runtime": { + "version": "9.2.0-alpha.3", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.0-alpha.3.tgz", + "integrity": "sha512-1pOggEqknxVyhdASumips0/RaMaXwSCQMzwhk2jeOGOotBQuOHQHVy25kH5OaeXSFx9L7PckZHXjwZauD72zRw==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/dmg-builder/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/dmg-builder/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/dmg-builder/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/dmg-license": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.11.tgz", + "integrity": "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "@types/plist": "^3.0.1", + "@types/verror": "^1.10.3", + "ajv": "^6.10.0", + "crc": "^3.8.0", + "iconv-corefoundation": "^1.1.7", + "plist": "^3.0.4", + "smart-buffer": "^4.0.2", + "verror": "^1.10.0" + }, + "bin": { + "dmg-license": "bin/dmg-license.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", + "dev": true + }, + "node_modules/dns-packet": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.0.tgz", + "integrity": "sha512-rza3UH1LwdHh9qyPXp8lkwpjSNk/AMD3dPytUoRoqnypDUhY0xvbdmVhWOfxO68frEfV9BU8V12Ez7ZsHGZpCQ==", + "dev": true, + "dependencies": { + "@leichtgewicht/ip-codec": "^2.0.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/dom-accessibility-api": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.13.tgz", + "integrity": "sha512-R305kwb5CcMDIpSHUnLyIAp7SrSPBx6F0VfQFB3M75xVMHhXJJIdePYgbPPh1o57vCHNu5QztokWUPsLjWzFqw==", + "dev": true + }, + "node_modules/dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dev": true, + "dependencies": { + "utila": "~0.4" + } + }, + "node_modules/dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "dependencies": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "node_modules/dom-serializer": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" + } + }, + "node_modules/domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dev": true, + "dependencies": { + "webidl-conversions": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/domexception/node_modules/webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "dependencies": { + "domelementtype": "^2.2.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "dependencies": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "dependencies": { + "is-obj": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/dotenv": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz", + "integrity": "sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/dotenv-expand": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", + "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", + "dev": true + }, + "node_modules/duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "node_modules/duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "node_modules/eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "node_modules/ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "node_modules/ejs": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", + "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "dev": true, + "dependencies": { + "jake": "^10.8.5" + }, + "bin": { + "ejs": "bin/cli.js" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/electron": { + "version": "22.3.1", + "resolved": "https://registry.npmjs.org/electron/-/electron-22.3.1.tgz", + "integrity": "sha512-iDltL9j12bINK3aOp8ZoGq4NFBFjJhw1AYHelbWj93XUCAIT4fdA+PRsq0aaTHg3bthLLlLRvIZVgNsZPqWcqg==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@electron/get": "^2.0.0", + "@types/node": "^16.11.26", + "extract-zip": "^2.0.1" + }, + "bin": { + "electron": "cli.js" + }, + "engines": { + "node": ">= 12.20.55" + } + }, + "node_modules/electron-builder": { + "version": "24.0.0-alpha.13", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-24.0.0-alpha.13.tgz", + "integrity": "sha512-YLDlzySvfBZKoCp4hNf4cx849vrew+3jxfNx5malT2PGd3y2GPYKCEvFc15AGShmah2Pt0gGoVQRot/dC6Nb9g==", + "dev": true, + "dependencies": { + "@types/yargs": "^17.0.16", + "app-builder-lib": "24.0.0-alpha.13", + "builder-util": "24.0.0-alpha.13", + "builder-util-runtime": "9.2.0-alpha.3", + "chalk": "^4.1.2", + "dmg-builder": "24.0.0-alpha.13", + "fs-extra": "^10.1.0", + "is-ci": "^3.0.0", + "lazy-val": "^1.0.5", + "read-config-file": "6.3.2", + "simple-update-notifier": "^1.1.0", + "yargs": "^17.6.2" + }, + "bin": { + "electron-builder": "cli.js", + "install-app-deps": "install-app-deps.js" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/electron-builder/node_modules/builder-util-runtime": { + "version": "9.2.0-alpha.3", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.0-alpha.3.tgz", + "integrity": "sha512-1pOggEqknxVyhdASumips0/RaMaXwSCQMzwhk2jeOGOotBQuOHQHVy25kH5OaeXSFx9L7PckZHXjwZauD72zRw==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/electron-builder/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, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/electron-builder/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/electron-builder/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/electron-builder/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/electron-builder/node_modules/yargs": { + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "dev": true, + "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.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/electron-builder/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, + "engines": { + "node": ">=12" + } + }, + "node_modules/electron-debug": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/electron-debug/-/electron-debug-3.2.0.tgz", + "integrity": "sha512-7xZh+LfUvJ52M9rn6N+tPuDw6oRAjxUj9SoxAZfJ0hVCXhZCsdkrSt7TgXOiWiEOBgEV8qwUIO/ScxllsPS7ow==", + "dependencies": { + "electron-is-dev": "^1.1.0", + "electron-localshortcut": "^3.1.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/electron-devtools-installer": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/electron-devtools-installer/-/electron-devtools-installer-3.2.0.tgz", + "integrity": "sha512-t3UczsYugm4OAbqvdImMCImIMVdFzJAHgbwHpkl5jmfu1izVgUcP/mnrPqJIpEeCK1uZGpt+yHgWEN+9EwoYhQ==", + "dev": true, + "dependencies": { + "rimraf": "^3.0.2", + "semver": "^7.2.1", + "tslib": "^2.1.0", + "unzip-crx-3": "^0.2.0" + } + }, + "node_modules/electron-is-accelerator": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/electron-is-accelerator/-/electron-is-accelerator-0.1.2.tgz", + "integrity": "sha1-UJ5RDCala1Xhf4Y6SwThEYRqsns=" + }, + "node_modules/electron-is-dev": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-1.2.0.tgz", + "integrity": "sha512-R1oD5gMBPS7PVU8gJwH6CtT0e6VSoD0+SzSnYpNm+dBkcijgA+K7VAMHDfnRq/lkKPZArpzplTW6jfiMYosdzw==" + }, + "node_modules/electron-localshortcut": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/electron-localshortcut/-/electron-localshortcut-3.2.1.tgz", + "integrity": "sha512-DWvhKv36GsdXKnaFFhEiK8kZZA+24/yFLgtTwJJHc7AFgDjNRIBJZ/jq62Y/dWv9E4ypYwrVWN2bVrCYw1uv7Q==", + "dependencies": { + "debug": "^4.0.1", + "electron-is-accelerator": "^0.1.0", + "keyboardevent-from-electron-accelerator": "^2.0.0", + "keyboardevents-areequal": "^0.2.1" + } + }, + "node_modules/electron-log": { + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/electron-log/-/electron-log-4.4.6.tgz", + "integrity": "sha512-nirYgRdY+F+vclr8ijdwy2vW03IzFpDHTaKNWu76dEN21Y76+smcES5knS7cgHUUB0qNLOi8vZO36taakjbSXA==" + }, + "node_modules/electron-notarize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-1.2.1.tgz", + "integrity": "sha512-u/ECWhIrhkSQpZM4cJzVZ5TsmkaqrRo5LDC/KMbGF0sPkm53Ng59+M0zp8QVaql0obfJy9vlVT+4iOkAi2UDlA==", + "deprecated": "Please use @electron/notarize moving forward. There is no API change, just a package name change", + "dev": true, + "dependencies": { + "debug": "^4.1.1", + "fs-extra": "^9.0.1" + }, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/electron-notarize/node_modules/fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "dependencies": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/electron-notarize/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/electron-notarize/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/electron-publish": { + "version": "24.0.0-alpha.13", + "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-24.0.0-alpha.13.tgz", + "integrity": "sha512-ur3XrX/8vLfZV+UisnbFvinX2ETD+Jdq8mUqG1sKlgITsQdjjjt8vKLiBgE71YhgDqFylpmFeWF8MJT91sSPnQ==", + "dev": true, + "dependencies": { + "@types/fs-extra": "^9.0.11", + "builder-util": "24.0.0-alpha.13", + "builder-util-runtime": "9.2.0-alpha.3", + "chalk": "^4.1.2", + "fs-extra": "^10.1.0", + "lazy-val": "^1.0.5", + "mime": "^2.5.2" + } + }, + "node_modules/electron-publish/node_modules/builder-util-runtime": { + "version": "9.2.0-alpha.3", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.0-alpha.3.tgz", + "integrity": "sha512-1pOggEqknxVyhdASumips0/RaMaXwSCQMzwhk2jeOGOotBQuOHQHVy25kH5OaeXSFx9L7PckZHXjwZauD72zRw==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "sax": "^1.2.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/electron-publish/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/electron-publish/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/electron-publish/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/electron-store": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-8.1.0.tgz", + "integrity": "sha512-2clHg/juMjOH0GT9cQ6qtmIvK183B39ZXR0bUoPwKwYHJsEF3quqyDzMFUAu+0OP8ijmN2CbPRAelhNbWUbzwA==", + "dependencies": { + "conf": "^10.2.0", + "type-fest": "^2.17.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/electron-store/node_modules/type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==", + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/electron-to-chromium": { + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" + }, + "node_modules/electron-updater": { + "version": "4.6.5", + "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-4.6.5.tgz", + "integrity": "sha512-kdTly8O9mSZfm9fslc1mnCY+mYOeaYRy7ERa2Fed240u01BKll3aiupzkd07qKw69KvhBSzuHroIW3mF0D8DWA==", + "dependencies": { + "@types/semver": "^7.3.6", + "builder-util-runtime": "8.9.2", + "fs-extra": "^10.0.0", + "js-yaml": "^4.1.0", + "lazy-val": "^1.0.5", + "lodash.escaperegexp": "^4.1.2", + "lodash.isequal": "^4.5.0", + "semver": "^7.3.5" + } + }, + "node_modules/electron-updater/node_modules/fs-extra": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", + "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/electron-updater/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/electron-updater/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/electron/node_modules/@types/node": { + "version": "16.18.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.13.tgz", + "integrity": "sha512-l0/3XZ153UTlNOnZK8xSNoJlQda9/WnYgiTdcKKPJSZjdjI9MU+A9oMXOesAWLSnqAaaJhj3qfQsU07Dr8OUwg==", + "dev": true + }, + "node_modules/electronmon": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/electronmon/-/electronmon-2.0.2.tgz", + "integrity": "sha512-Yw1CXEp5HJT9P6Sns3UP3Krwm5eb2JKqTRAVczKdsUa+U/dMTgONwKIHkPbKSSmtyTV+5JwobxkhFPiRgegObA==", + "dev": true, + "dependencies": { + "chalk": "^3.0.0", + "import-from": "^3.0.0", + "runtime-required": "^1.1.0", + "watchboy": "^0.4.3" + }, + "bin": { + "electronmon": "bin/cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/electronmon/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, + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/emittery": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/emittery?sponsor=1" + } + }, + "node_modules/emoji-regex": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "node_modules/emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "optional": true, + "dependencies": { + "iconv-lite": "^0.6.2" + } + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "once": "^1.4.0" + } + }, + "node_modules/enhanced-resolve": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz", + "integrity": "sha1-TW5omzcl+GCQknzMhs2fFjW4ni4=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.2.0", + "tapable": "^0.1.8" + }, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/enhanced-resolve/node_modules/tapable": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.1.10.tgz", + "integrity": "sha1-KcNXB8K3DlDQdIK10gLo7URtr9Q=", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/ensure-posix-path": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ensure-posix-path/-/ensure-posix-path-1.1.1.tgz", + "integrity": "sha512-VWU0/zXzVbeJNXvME/5EmLuEj2TauvoaTz6aFYK1Z92JCBlDlZ3Gu0tuGR42kpW1754ywTs+QB0g5TP0oj9Zaw==", + "dev": true + }, + "node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/env-paths": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz", + "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==", + "engines": { + "node": ">=6" + } + }, + "node_modules/envinfo": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", + "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "dev": true, + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/eol": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/eol/-/eol-0.9.1.tgz", + "integrity": "sha512-Ds/TEoZjwggRoz/Q2O7SE3i4Jm66mqTDfmdHdq/7DKVk3bro9Q8h6WdXKdPqFLMoqxrDK5SVRzHVPOS6uuGtrg==", + "dev": true + }, + "node_modules/err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": true + }, + "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==", + "dependencies": { + "is-arrayish": "^0.2.1" + } + }, + "node_modules/error-stack-parser": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.7.tgz", + "integrity": "sha512-chLOW0ZGRf4s8raLrDxa5sdkvPec5YdvwbFnqJme4rk0rFajP8mPtrDL1+I+CwrQDCjswDA5sREX7jYQDQs9vA==", + "dev": true, + "dependencies": { + "stackframe": "^1.1.1" + } + }, + "node_modules/es-abstract": { + "version": "1.20.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.5.tgz", + "integrity": "sha512-7h8MM2EQhsCA7pU/Nv78qOXFpD8Rhqd12gYiSJVkrH9+e8VuA8JlPJK/hQjjlLv6pJvx/z1iRFKzYb0XT/RuAQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.3", + "get-symbol-description": "^1.0.0", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.2", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "unbox-primitive": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-module-lexer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.2.1.tgz", + "integrity": "sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg==", + "dev": true + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "dependencies": { + "has": "^1.0.3" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true, + "optional": true + }, + "node_modules/escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "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": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "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==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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, + "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" + }, + "engines": { + "node": ">=6.0" + }, + "optionalDependencies": { + "source-map": "~0.6.1" + } + }, + "node_modules/escodegen/node_modules/levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/node_modules/optionator": { + "version": "0.8.3", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", + "integrity": "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA==", + "dev": true, + "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" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "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": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/escodegen/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, + "optional": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "dependencies": { + "prelude-ls": "~1.1.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/eslint": { + "version": "8.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.30.0.tgz", + "integrity": "sha512-MGADB39QqYuzEGov+F/qb18r4i7DohCDOfatHaxI2iGlPuC65bwG2gxgO+7DkyL38dRFaRH7RaRAgU6JKL9rMQ==", + "dev": true, + "dependencies": { + "@eslint/eslintrc": "^1.4.0", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "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.19.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "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" + }, + "bin": { + "eslint": "bin/eslint.js" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" + } + }, + "node_modules/eslint-config-airbnb-base": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", + "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", + "dev": true, + "dependencies": { + "confusing-browser-globals": "^1.0.10", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5", + "semver": "^6.3.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "peerDependencies": { + "eslint": "^7.32.0 || ^8.2.0", + "eslint-plugin-import": "^2.25.2" + } + }, + "node_modules/eslint-config-airbnb-base/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-config-erb": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-config-erb/-/eslint-config-erb-4.0.3.tgz", + "integrity": "sha512-qZeiUSQanpCKKazkLzIvVaoM9NZcNvqhO7gYZ2jaEpBmadCu1aOzzvMMtjsoxaDytRQt6mt+uXjWGyJNqUYusw==", + "dev": true, + "dependencies": { + "@typescript-eslint/eslint-plugin": "^4.29.2", + "@typescript-eslint/parser": "^4.29.3", + "eslint-config-airbnb": "^18.2.1", + "eslint-config-airbnb-typescript": "^13.0.0", + "eslint-config-prettier": "^8.3.0", + "eslint-import-resolver-webpack": "^0.13.1", + "eslint-plugin-compat": "^3.13.0", + "eslint-plugin-import": "^2.24.1", + "eslint-plugin-jest": "^24.4.0", + "eslint-plugin-jsx-a11y": "6.4.1", + "eslint-plugin-prettier": "^3.4.1", + "eslint-plugin-promise": "^5.1.0", + "eslint-plugin-react": "^7.24.0", + "eslint-plugin-react-hooks": "^4.2.0" + }, + "peerDependencies": { + "eslint": ">=7", + "jest": ">=26.0.1", + "react": ">=16.13.1" + } + }, + "node_modules/eslint-config-erb/node_modules/@mdn/browser-compat-data": { + "version": "3.3.14", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-3.3.14.tgz", + "integrity": "sha512-n2RC9d6XatVbWFdHLimzzUJxJ1KY8LdjqrW6YvGPiRmsHkhOUx74/Ct10x5Yo7bC/Jvqx7cDEW8IMPv/+vwEzA==", + "dev": true + }, + "node_modules/eslint-config-erb/node_modules/@typescript-eslint/eslint-plugin": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", + "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "4.33.0", + "@typescript-eslint/scope-manager": "4.33.0", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^4.0.0", + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-config-erb/node_modules/@typescript-eslint/parser": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", + "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", + "dev": true, + "dependencies": { + "@typescript-eslint/scope-manager": "4.33.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/typescript-estree": "4.33.0", + "debug": "^4.3.1" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-config-erb/node_modules/@typescript-eslint/scope-manager": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", + "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-config-erb/node_modules/@typescript-eslint/types": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", + "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", + "dev": true, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-config-erb/node_modules/@typescript-eslint/typescript-estree": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", + "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-config-erb/node_modules/@typescript-eslint/visitor-keys": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", + "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "4.33.0", + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^8.10.0 || ^10.13.0 || >=11.10.1" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-config-erb/node_modules/aria-query": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/eslint-config-erb/node_modules/eslint-config-airbnb": { + "version": "18.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-18.2.1.tgz", + "integrity": "sha512-glZNDEZ36VdlZWoxn/bUR1r/sdFKPd1mHPbqUtkctgNG4yT2DLLtJ3D+yCV+jzZCc2V1nBVkmdknOJBZ5Hc0fg==", + "dev": true, + "dependencies": { + "eslint-config-airbnb-base": "^14.2.1", + "object.assign": "^4.1.2", + "object.entries": "^1.1.2" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "eslint": "^5.16.0 || ^6.8.0 || ^7.2.0", + "eslint-plugin-import": "^2.22.1", + "eslint-plugin-jsx-a11y": "^6.4.1", + "eslint-plugin-react": "^7.21.5", + "eslint-plugin-react-hooks": "^4 || ^3 || ^2.3.0 || ^1.7.0" + } + }, + "node_modules/eslint-config-erb/node_modules/eslint-config-airbnb-typescript": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-13.0.1.tgz", + "integrity": "sha512-n7fGBDNV3xSKbWDUES2FfsNAJhuqADcwzshX6ci6qoszUnH6p4dzrLnSFqYkw5Sn7M+aarp2BTf7JDOK88M+bg==", + "dev": true, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^4.4.1", + "@typescript-eslint/parser": "^4.4.1" + } + }, + "node_modules/eslint-config-erb/node_modules/eslint-config-airbnb/node_modules/eslint-config-airbnb-base": { + "version": "14.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz", + "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==", + "dev": true, + "dependencies": { "confusing-browser-globals": "^1.0.10", "object.assign": "^4.1.2", "object.entries": "^1.1.2" - } + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "eslint": "^5.16.0 || ^6.8.0 || ^7.2.0", + "eslint-plugin-import": "^2.22.1" } - } }, - "eslint-config-airbnb-typescript": { - "version": "13.0.1", - "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-13.0.1.tgz", - "integrity": "sha512-n7fGBDNV3xSKbWDUES2FfsNAJhuqADcwzshX6ci6qoszUnH6p4dzrLnSFqYkw5Sn7M+aarp2BTf7JDOK88M+bg==", - "dev": true, - "requires": {} + "node_modules/eslint-config-erb/node_modules/eslint-plugin-compat": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-3.13.0.tgz", + "integrity": "sha512-cv8IYMuTXm7PIjMVDN2y4k/KVnKZmoNGHNq27/9dLstOLydKblieIv+oe2BN2WthuXnFNhaNvv3N1Bvl4dbIGA==", + "dev": true, + "dependencies": { + "@mdn/browser-compat-data": "^3.3.14", + "ast-metadata-inferer": "^0.7.0", + "browserslist": "^4.16.8", + "caniuse-lite": "^1.0.30001251", + "core-js": "^3.16.2", + "find-up": "^5.0.0", + "lodash.memoize": "4.1.2", + "semver": "7.3.5" + }, + "engines": { + "node": ">=9.x" + }, + "peerDependencies": { + "eslint": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" + } }, - "eslint-plugin-compat": { - "version": "3.13.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-3.13.0.tgz", - "integrity": "sha512-cv8IYMuTXm7PIjMVDN2y4k/KVnKZmoNGHNq27/9dLstOLydKblieIv+oe2BN2WthuXnFNhaNvv3N1Bvl4dbIGA==", - "dev": true, - "requires": { - "@mdn/browser-compat-data": "^3.3.14", - "ast-metadata-inferer": "^0.7.0", - "browserslist": "^4.16.8", - "caniuse-lite": "^1.0.30001251", - "core-js": "^3.16.2", - "find-up": "^5.0.0", - "lodash.memoize": "4.1.2", - "semver": "7.3.5" - } + "node_modules/eslint-config-erb/node_modules/eslint-plugin-jest": { + "version": "24.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.7.0.tgz", + "integrity": "sha512-wUxdF2bAZiYSKBclsUMrYHH6WxiBreNjyDxbRv345TIvPeoCEgPNEn3Sa+ZrSqsf1Dl9SqqSREXMHExlMMu1DA==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "^4.0.1" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": ">= 4", + "eslint": ">=5" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + } + } }, - "eslint-plugin-jest": { - "version": "24.7.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.7.0.tgz", - "integrity": "sha512-wUxdF2bAZiYSKBclsUMrYHH6WxiBreNjyDxbRv345TIvPeoCEgPNEn3Sa+ZrSqsf1Dl9SqqSREXMHExlMMu1DA==", - "dev": true, - "requires": { - "@typescript-eslint/experimental-utils": "^4.0.1" - } + "node_modules/eslint-config-erb/node_modules/eslint-plugin-jsx-a11y": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.4.1.tgz", + "integrity": "sha512-0rGPJBbwHoGNPU73/QCLP/vveMlM1b1Z9PponxO87jfr6tuH5ligXbDT6nHSSzBC8ovX2Z+BQu7Bk5D/Xgq9zg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.11.2", + "aria-query": "^4.2.2", + "array-includes": "^3.1.1", + "ast-types-flow": "^0.0.7", + "axe-core": "^4.0.2", + "axobject-query": "^2.2.0", + "damerau-levenshtein": "^1.0.6", + "emoji-regex": "^9.0.0", + "has": "^1.0.3", + "jsx-ast-utils": "^3.1.0", + "language-tags": "^1.0.5" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7" + } }, - "eslint-plugin-jsx-a11y": { - "version": "6.4.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.4.1.tgz", - "integrity": "sha512-0rGPJBbwHoGNPU73/QCLP/vveMlM1b1Z9PponxO87jfr6tuH5ligXbDT6nHSSzBC8ovX2Z+BQu7Bk5D/Xgq9zg==", - "dev": true, - "requires": { - "@babel/runtime": "^7.11.2", - "aria-query": "^4.2.2", - "array-includes": "^3.1.1", - "ast-types-flow": "^0.0.7", - "axe-core": "^4.0.2", - "axobject-query": "^2.2.0", - "damerau-levenshtein": "^1.0.6", - "emoji-regex": "^9.0.0", - "has": "^1.0.3", - "jsx-ast-utils": "^3.1.0", - "language-tags": "^1.0.5" - } + "node_modules/eslint-config-erb/node_modules/eslint-plugin-promise": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.2.0.tgz", + "integrity": "sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw==", + "dev": true, + "engines": { + "node": "^10.12.0 || >=12.0.0" + }, + "peerDependencies": { + "eslint": "^7.0.0" + } }, - "eslint-plugin-promise": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.2.0.tgz", - "integrity": "sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw==", - "dev": true, - "requires": {} + "node_modules/eslint-config-erb/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==", + "dev": true, + "engines": { + "node": ">=10" + } }, - "eslint-visitor-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", - "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", - "dev": true + "node_modules/eslint-config-erb/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } }, - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.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-import-resolver-node": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", - "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "resolve": "^1.20.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "eslint-import-resolver-typescript": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-2.7.1.tgz", - "integrity": "sha512-00UbgGwV8bSgUv34igBDbTOtKhqoRMy9bFjNehT40bXg6585PNIct8HhXZ0SybqB9rWtXj9crcku8ndDn/gIqQ==", - "dev": true, - "requires": { - "debug": "^4.3.4", - "glob": "^7.2.0", - "is-glob": "^4.0.3", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" - } - }, - "eslint-import-resolver-webpack": { - "version": "0.13.2", - "resolved": "https://registry.npmjs.org/eslint-import-resolver-webpack/-/eslint-import-resolver-webpack-0.13.2.tgz", - "integrity": "sha512-XodIPyg1OgE2h5BDErz3WJoK7lawxKTJNhgPNafRST6csC/MZC+L5P6kKqsZGRInpbgc02s/WZMrb4uGJzcuRg==", - "dev": true, - "requires": { - "array-find": "^1.0.0", - "debug": "^3.2.7", - "enhanced-resolve": "^0.9.1", - "find-root": "^1.1.0", - "has": "^1.0.3", - "interpret": "^1.4.0", - "is-core-module": "^2.7.0", - "is-regex": "^1.1.4", - "lodash": "^4.17.21", - "resolve": "^1.20.0", - "semver": "^5.7.1" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } + "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==", + "dev": true, + "bin": { + "eslint-config-prettier": "bin/cli.js" + }, + "peerDependencies": { + "eslint": ">=7.0.0" + } }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - } - } - }, - "eslint-module-utils": { - "version": "2.7.3", - "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", - "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", - "dev": true, - "requires": { - "debug": "^3.2.7", - "find-up": "^2.1.0" - }, - "dependencies": { - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } + "node_modules/eslint-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + } }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } + "node_modules/eslint-import-resolver-typescript": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-2.7.1.tgz", + "integrity": "sha512-00UbgGwV8bSgUv34igBDbTOtKhqoRMy9bFjNehT40bXg6585PNIct8HhXZ0SybqB9rWtXj9crcku8ndDn/gIqQ==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "glob": "^7.2.0", + "is-glob": "^4.0.3", + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*" + } }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } + "node_modules/eslint-import-resolver-webpack": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-webpack/-/eslint-import-resolver-webpack-0.13.2.tgz", + "integrity": "sha512-XodIPyg1OgE2h5BDErz3WJoK7lawxKTJNhgPNafRST6csC/MZC+L5P6kKqsZGRInpbgc02s/WZMrb4uGJzcuRg==", + "dev": true, + "dependencies": { + "array-find": "^1.0.0", + "debug": "^3.2.7", + "enhanced-resolve": "^0.9.1", + "find-root": "^1.1.0", + "has": "^1.0.3", + "interpret": "^1.4.0", + "is-core-module": "^2.7.0", + "is-regex": "^1.1.4", + "lodash": "^4.17.21", + "resolve": "^1.20.0", + "semver": "^5.7.1" + }, + "engines": { + "node": ">= 6" + }, + "peerDependencies": { + "eslint-plugin-import": ">=1.4.0", + "webpack": ">=1.11.0" + } }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } + "node_modules/eslint-import-resolver-webpack/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true + "node_modules/eslint-import-resolver-webpack/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - } - } - }, - "eslint-plugin-compat": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-4.0.2.tgz", - "integrity": "sha512-xqvoO54CLTVaEYGMzhu35Wzwk/As7rCvz/2dqwnFiWi0OJccEtGIn+5qq3zqIu9nboXlpdBN579fZcItC73Ycg==", - "dev": true, - "requires": { - "@mdn/browser-compat-data": "^4.1.5", - "ast-metadata-inferer": "^0.7.0", - "browserslist": "^4.16.8", - "caniuse-lite": "^1.0.30001304", - "core-js": "^3.16.2", - "find-up": "^5.0.0", - "lodash.memoize": "4.1.2", - "semver": "7.3.5" - }, - "dependencies": { - "semver": { - "version": "7.3.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", - "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", - "dev": true, - "requires": { - "lru-cache": "^6.0.0" - } - } - } - }, - "eslint-plugin-import": { - "version": "2.26.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", - "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", - "dev": true, - "requires": { - "array-includes": "^3.1.4", - "array.prototype.flat": "^1.2.5", - "debug": "^2.6.9", - "doctrine": "^2.1.0", - "eslint-import-resolver-node": "^0.3.6", - "eslint-module-utils": "^2.7.3", - "has": "^1.0.3", - "is-core-module": "^2.8.1", - "is-glob": "^4.0.3", - "minimatch": "^3.1.2", - "object.values": "^1.1.5", - "resolve": "^1.22.0", - "tsconfig-paths": "^3.14.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } + "node_modules/eslint-module-utils": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", + "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "find-up": "^2.1.0" + }, + "engines": { + "node": ">=4" + } }, - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "eslint-plugin-jest": { - "version": "26.1.3", - "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.1.3.tgz", - "integrity": "sha512-Pju+T7MFpo5VFhFlwrkK/9jRUu18r2iugvgyrWOnnGRaVTFFmFXp+xFJpHyqmjjLmGJPKLeEFLVTAxezkApcpQ==", - "dev": true, - "requires": { - "@typescript-eslint/utils": "^5.10.0" - } - }, - "eslint-plugin-jsx-a11y": { - "version": "6.6.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz", - "integrity": "sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==", - "dev": true, - "requires": { - "@babel/runtime": "^7.18.9", - "aria-query": "^4.2.2", - "array-includes": "^3.1.5", - "ast-types-flow": "^0.0.7", - "axe-core": "^4.4.3", - "axobject-query": "^2.2.0", - "damerau-levenshtein": "^1.0.8", - "emoji-regex": "^9.2.2", - "has": "^1.0.3", - "jsx-ast-utils": "^3.3.2", - "language-tags": "^1.0.5", - "minimatch": "^3.1.2", - "semver": "^6.3.0" - }, - "dependencies": { - "aria-query": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", - "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", - "dev": true, - "requires": { - "@babel/runtime": "^7.10.2", - "@babel/runtime-corejs3": "^7.10.2" - } + "node_modules/eslint-module-utils/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "eslint-plugin-prettier": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", - "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", - "dev": true, - "requires": { - "prettier-linter-helpers": "^1.0.0" - } - }, - "eslint-plugin-promise": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", - "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", - "dev": true, - "requires": {} - }, - "eslint-plugin-react": { - "version": "7.31.11", - "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.11.tgz", - "integrity": "sha512-TTvq5JsT5v56wPa9OYHzsrOlHzKZKjV+aLgS+55NJP/cuzdiQPC7PfYoUjMoxlffKtvijpk7vA/jmuqRb9nohw==", - "dev": true, - "requires": { - "array-includes": "^3.1.6", - "array.prototype.flatmap": "^1.3.1", - "array.prototype.tosorted": "^1.1.1", - "doctrine": "^2.1.0", - "estraverse": "^5.3.0", - "jsx-ast-utils": "^2.4.1 || ^3.0.0", - "minimatch": "^3.1.2", - "object.entries": "^1.1.6", - "object.fromentries": "^2.0.6", - "object.hasown": "^1.1.2", - "object.values": "^1.1.6", - "prop-types": "^15.8.1", - "resolve": "^2.0.0-next.3", - "semver": "^6.3.0", - "string.prototype.matchall": "^4.0.8" - }, - "dependencies": { - "doctrine": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", - "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", - "dev": true, - "requires": { - "esutils": "^2.0.2" - } + "node_modules/eslint-module-utils/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } }, - "resolve": { - "version": "2.0.0-next.3", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", - "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", - "dev": true, - "requires": { - "is-core-module": "^2.2.0", - "path-parse": "^1.0.6" - } + "node_modules/eslint-module-utils/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } }, - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "eslint-plugin-react-hooks": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", - "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", - "dev": true, - "requires": {} - }, - "eslint-plugin-sort-keys-fix": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/eslint-plugin-sort-keys-fix/-/eslint-plugin-sort-keys-fix-1.1.2.tgz", - "integrity": "sha512-DNPHFGCA0/hZIsfODbeLZqaGY/+q3vgtshF85r+YWDNCQ2apd9PNs/zL6ttKm0nD1IFwvxyg3YOTI7FHl4unrw==", - "dev": true, - "requires": { - "espree": "^6.1.2", - "esutils": "^2.0.2", - "natural-compare": "^1.4.0", - "requireindex": "~1.2.0" - }, - "dependencies": { - "acorn": { - "version": "7.4.1", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", - "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", - "dev": true + "node_modules/eslint-module-utils/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } }, - "eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "dev": true + "node_modules/eslint-module-utils/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true, + "engines": { + "node": ">=4" + } }, - "espree": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", - "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", - "dev": true, - "requires": { - "acorn": "^7.1.1", - "acorn-jsx": "^5.2.0", - "eslint-visitor-keys": "^1.1.0" - } - } - } - }, - "eslint-plugin-typescript-sort-keys": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-typescript-sort-keys/-/eslint-plugin-typescript-sort-keys-2.1.0.tgz", - "integrity": "sha512-ET7ABypdz19m47QnKynzNfWPi4CTNQ5jQQC1X5d0gojIwblkbGiCa5IilsqzBTmqxZ0yXDqKBO/GBkBFQCOFsg==", - "dev": true, - "requires": { - "@typescript-eslint/experimental-utils": "^5.0.0", - "json-schema": "^0.4.0", - "natural-compare-lite": "^1.4.0" - }, - "dependencies": { - "@typescript-eslint/experimental-utils": { - "version": "5.25.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.25.0.tgz", - "integrity": "sha512-YTe9rmslCh1xAvNa3X+uZe4L2lsyb8V3WIeK9z46nNiPswk/V/0SGLJSfo8W9Hj4R7ak7bolazXGn3DErmb8QA==", - "dev": true, - "requires": { - "@typescript-eslint/utils": "5.25.0" - } + "node_modules/eslint-module-utils/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true, + "engines": { + "node": ">=4" + } }, - "@typescript-eslint/scope-manager": { - "version": "5.25.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.25.0.tgz", - "integrity": "sha512-p4SKTFWj+2VpreUZ5xMQsBMDdQ9XdRvODKXN4EksyBjFp2YvQdLkyHqOffakYZPuWJUDNu3jVXtHALDyTv3cww==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.25.0", - "@typescript-eslint/visitor-keys": "5.25.0" - } + "node_modules/eslint-plugin-compat": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-4.0.2.tgz", + "integrity": "sha512-xqvoO54CLTVaEYGMzhu35Wzwk/As7rCvz/2dqwnFiWi0OJccEtGIn+5qq3zqIu9nboXlpdBN579fZcItC73Ycg==", + "dev": true, + "dependencies": { + "@mdn/browser-compat-data": "^4.1.5", + "ast-metadata-inferer": "^0.7.0", + "browserslist": "^4.16.8", + "caniuse-lite": "^1.0.30001304", + "core-js": "^3.16.2", + "find-up": "^5.0.0", + "lodash.memoize": "4.1.2", + "semver": "7.3.5" + }, + "engines": { + "node": ">=9.x" + }, + "peerDependencies": { + "eslint": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0" + } }, - "@typescript-eslint/types": { - "version": "5.25.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.25.0.tgz", - "integrity": "sha512-7fWqfxr0KNHj75PFqlGX24gWjdV/FDBABXL5dyvBOWHpACGyveok8Uj4ipPX/1fGU63fBkzSIycEje4XsOxUFA==", - "dev": true + "node_modules/eslint-plugin-compat/node_modules/semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } }, - "@typescript-eslint/typescript-estree": { - "version": "5.25.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.25.0.tgz", - "integrity": "sha512-MrPODKDych/oWs/71LCnuO7NyR681HuBly2uLnX3r5i4ME7q/yBqC4hW33kmxtuauLTM0OuBOhhkFaxCCOjEEw==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.25.0", - "@typescript-eslint/visitor-keys": "5.25.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - } + "node_modules/eslint-plugin-import": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.3", + "has": "^1.0.3", + "is-core-module": "^2.8.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.5", + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } }, - "@typescript-eslint/utils": { - "version": "5.25.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.25.0.tgz", - "integrity": "sha512-qNC9bhnz/n9Kba3yI6HQgQdBLuxDoMgdjzdhSInZh6NaDnFpTUlwNGxplUFWfY260Ya0TRPvkg9dd57qxrJI9g==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.9", - "@typescript-eslint/scope-manager": "5.25.0", - "@typescript-eslint/types": "5.25.0", - "@typescript-eslint/typescript-estree": "5.25.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - } + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } }, - "@typescript-eslint/visitor-keys": { - "version": "5.25.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.25.0.tgz", - "integrity": "sha512-yd26vFgMsC4h2dgX4+LR+GeicSKIfUvZREFLf3DDjZPtqgLx5AJZr6TetMNwFP9hcKreTTeztQYBTNbNoOycwA==", - "dev": true, - "requires": { - "@typescript-eslint/types": "5.25.0", - "eslint-visitor-keys": "^3.3.0" - } - } - } - }, - "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" - }, - "dependencies": { - "estraverse": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", - "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", - "dev": true - } - } - }, - "eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "dev": true, - "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==", - "dev": true - } - } - }, - "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==", - "dev": true - }, - "espree": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", - "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", - "dev": true, - "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==", - "dev": true, - "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==", - "dev": true, - "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==", - "dev": true - }, - "esutils": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", - "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", - "dev": true - }, - "etag": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", - "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", - "dev": true - }, - "eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true - }, - "events": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", - "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", - "dev": true - }, - "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 - } - } - }, - "execall": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz", - "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==", - "dev": true, - "requires": { - "clone-regexp": "^2.1.0" - } - }, - "exit": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", - "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", - "dev": true - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } + "node_modules/eslint-plugin-import/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } + "node_modules/eslint-plugin-jest": { + "version": "26.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.1.3.tgz", + "integrity": "sha512-Pju+T7MFpo5VFhFlwrkK/9jRUu18r2iugvgyrWOnnGRaVTFFmFXp+xFJpHyqmjjLmGJPKLeEFLVTAxezkApcpQ==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "^5.10.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "@typescript-eslint/eslint-plugin": "^5.0.0", + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + }, + "peerDependenciesMeta": { + "@typescript-eslint/eslint-plugin": { + "optional": true + }, + "jest": { + "optional": true + } + } }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { + "node_modules/eslint-plugin-jsx-a11y": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz", + "integrity": "sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.18.9", + "aria-query": "^4.2.2", + "array-includes": "^3.1.5", + "ast-types-flow": "^0.0.7", + "axe-core": "^4.4.3", + "axobject-query": "^2.2.0", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "has": "^1.0.3", + "jsx-ast-utils": "^3.3.2", + "language-tags": "^1.0.5", + "minimatch": "^3.1.2", + "semver": "^6.3.0" + }, + "engines": { + "node": ">=4.0" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/aria-query": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" + }, + "engines": { + "node": ">=6.0" + } + }, + "node_modules/eslint-plugin-jsx-a11y/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-prettier": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", + "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", + "dev": true, + "dependencies": { + "prettier-linter-helpers": "^1.0.0" + }, + "engines": { + "node": ">=6.0.0" + }, + "peerDependencies": { + "eslint": ">=5.0.0", + "prettier": ">=1.13.0" + }, + "peerDependenciesMeta": { + "eslint-config-prettier": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-promise": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", + "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-plugin-react": { + "version": "7.31.11", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.11.tgz", + "integrity": "sha512-TTvq5JsT5v56wPa9OYHzsrOlHzKZKjV+aLgS+55NJP/cuzdiQPC7PfYoUjMoxlffKtvijpk7vA/jmuqRb9nohw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "array.prototype.tosorted": "^1.1.1", + "doctrine": "^2.1.0", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "object.hasown": "^1.1.2", + "object.values": "^1.1.6", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.3", + "semver": "^6.3.0", + "string.prototype.matchall": "^4.0.8" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8" + } + }, + "node_modules/eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "dev": true, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0" + } + }, + "node_modules/eslint-plugin-react/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-react/node_modules/resolve": { + "version": "2.0.0-next.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", + "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", + "dev": true, + "dependencies": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/eslint-plugin-react/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/eslint-plugin-sort-keys-fix": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-sort-keys-fix/-/eslint-plugin-sort-keys-fix-1.1.2.tgz", + "integrity": "sha512-DNPHFGCA0/hZIsfODbeLZqaGY/+q3vgtshF85r+YWDNCQ2apd9PNs/zL6ttKm0nD1IFwvxyg3YOTI7FHl4unrw==", + "dev": true, + "dependencies": { + "espree": "^6.1.2", + "esutils": "^2.0.2", + "natural-compare": "^1.4.0", + "requireindex": "~1.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-sort-keys-fix/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true, + "bin": { + "acorn": "bin/acorn" + }, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/eslint-plugin-sort-keys-fix/node_modules/eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/eslint-plugin-sort-keys-fix/node_modules/espree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", + "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "dev": true, + "dependencies": { + "acorn": "^7.1.1", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.1.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/eslint-plugin-typescript-sort-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-typescript-sort-keys/-/eslint-plugin-typescript-sort-keys-2.1.0.tgz", + "integrity": "sha512-ET7ABypdz19m47QnKynzNfWPi4CTNQ5jQQC1X5d0gojIwblkbGiCa5IilsqzBTmqxZ0yXDqKBO/GBkBFQCOFsg==", + "dev": true, + "dependencies": { + "@typescript-eslint/experimental-utils": "^5.0.0", + "json-schema": "^0.4.0", + "natural-compare-lite": "^1.4.0" + }, + "engines": { + "node": "10 - 12 || >= 13.9" + }, + "peerDependencies": { + "@typescript-eslint/parser": "^1 || ^2 || ^3 || ^4 || ^5", + "eslint": "^5 || ^6 || ^7 || ^8", + "typescript": "^3 || ^4" + } + }, + "node_modules/eslint-plugin-typescript-sort-keys/node_modules/@typescript-eslint/experimental-utils": { + "version": "5.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.25.0.tgz", + "integrity": "sha512-YTe9rmslCh1xAvNa3X+uZe4L2lsyb8V3WIeK9z46nNiPswk/V/0SGLJSfo8W9Hj4R7ak7bolazXGn3DErmb8QA==", + "dev": true, + "dependencies": { + "@typescript-eslint/utils": "5.25.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-plugin-typescript-sort-keys/node_modules/@typescript-eslint/scope-manager": { + "version": "5.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.25.0.tgz", + "integrity": "sha512-p4SKTFWj+2VpreUZ5xMQsBMDdQ9XdRvODKXN4EksyBjFp2YvQdLkyHqOffakYZPuWJUDNu3jVXtHALDyTv3cww==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.25.0", + "@typescript-eslint/visitor-keys": "5.25.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-typescript-sort-keys/node_modules/@typescript-eslint/types": { + "version": "5.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.25.0.tgz", + "integrity": "sha512-7fWqfxr0KNHj75PFqlGX24gWjdV/FDBABXL5dyvBOWHpACGyveok8Uj4ipPX/1fGU63fBkzSIycEje4XsOxUFA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "node_modules/eslint-plugin-typescript-sort-keys/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.25.0.tgz", + "integrity": "sha512-MrPODKDych/oWs/71LCnuO7NyR681HuBly2uLnX3r5i4ME7q/yBqC4hW33kmxtuauLTM0OuBOhhkFaxCCOjEEw==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.25.0", + "@typescript-eslint/visitor-keys": "5.25.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/eslint-plugin-typescript-sort-keys/node_modules/@typescript-eslint/utils": { + "version": "5.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.25.0.tgz", + "integrity": "sha512-qNC9bhnz/n9Kba3yI6HQgQdBLuxDoMgdjzdhSInZh6NaDnFpTUlwNGxplUFWfY260Ya0TRPvkg9dd57qxrJI9g==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.25.0", + "@typescript-eslint/types": "5.25.0", + "@typescript-eslint/typescript-estree": "5.25.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-plugin-typescript-sort-keys/node_modules/@typescript-eslint/visitor-keys": { + "version": "5.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.25.0.tgz", + "integrity": "sha512-yd26vFgMsC4h2dgX4+LR+GeicSKIfUvZREFLf3DDjZPtqgLx5AJZr6TetMNwFP9hcKreTTeztQYBTNbNoOycwA==", + "dev": true, + "dependencies": { + "@typescript-eslint/types": "5.25.0", + "eslint-visitor-keys": "^3.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/typescript-eslint" + } + }, + "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/eslint-scope/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" + } + }, + "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==", + "dev": true, + "dependencies": { + "eslint-visitor-keys": "^2.0.0" + }, + "engines": { + "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + }, + "peerDependencies": { + "eslint": ">=5" + } + }, + "node_modules/eslint-utils/node_modules/eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/eslint-visitor-keys": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", + "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "dev": true, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/eslint/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==", + "dev": true, + "dependencies": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/espree": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "dev": true, + "dependencies": { + "acorn": "^8.8.0", + "acorn-jsx": "^5.3.2", + "eslint-visitor-keys": "^3.3.0" + }, + "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==", + "dev": true, + "bin": { + "esparse": "bin/esparse.js", + "esvalidate": "bin/esvalidate.js" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/esquery": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.4.0.tgz", + "integrity": "sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "estraverse": "^5.2.0" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/estraverse": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz", + "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==", + "dev": true, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "node_modules/events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true, + "engines": { + "node": ">=0.8.x" + } + }, + "node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "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" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/execa/node_modules/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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/execall": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz", + "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==", + "dev": true, + "dependencies": { + "clone-regexp": "^2.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", + "dev": true, + "dependencies": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/expand-brackets/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { "is-buffer": "^1.1.5" - } + }, + "engines": { + "node": ">=0.10.0" } - } }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { + "node_modules/expand-brackets/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/expand-brackets/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { "is-buffer": "^1.1.5" - } + }, + "engines": { + "node": ">=0.10.0" } - } }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } + "node_modules/expand-brackets/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true + "node_modules/expand-brackets/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true + "node_modules/expand-brackets/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true + "node_modules/expand-brackets/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/express": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.0.tgz", + "integrity": "sha512-EJEXxiTQJS3lIPrU1AE2vRuT7X7E+0KBbpm5GSoK524yl0K8X+er8zS2P14E64eqsVNoWbMCT7MpmQ+ErAhgRg==", + "dev": true, + "dependencies": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.0", + "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.10.3", + "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" + }, + "engines": { + "node": ">= 0.10.0" + } + }, + "node_modules/express/node_modules/array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "node_modules/express/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/express/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/express/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/express/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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/express/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "node_modules/extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "dependencies": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "dependencies": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extglob/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "dependencies": { + "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/extsprintf": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", + "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==", + "dev": true, + "engines": [ + "node >=0.6.0" + ], + "optional": true + }, + "node_modules/fast-average-color": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/fast-average-color/-/fast-average-color-9.3.0.tgz", + "integrity": "sha512-FlPROSqDMOnoBgkFhWMHJODPvpS0Od0WDpedcKq4U/t0JVapGAkblNwxOr75qT+ZNd0dQM4qlgqrtnXbCJ8cNg==", + "engines": { + "node": ">= 12" + } + }, + "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==" + }, + "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 + }, + "node_modules/fast-fifo": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.1.0.tgz", + "integrity": "sha512-Kl29QoNbNvn4nhDsLYjyIAaIqaJB6rBx5p3sL9VjaefJ+eMFBWVZiaoguaoZfzEKr5RhAti0UgM8703akGPJ6g==", + "dev": true + }, + "node_modules/fast-glob": { + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "dev": true, + "dependencies": { + "@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" + }, + "engines": { + "node": ">=8.6.0" + } + }, + "node_modules/fast-glob/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==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "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==", + "dev": true + }, + "node_modules/fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "node_modules/fastest-levenshtein": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "reusify": "^1.0.4" + } + }, + "node_modules/faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "dependencies": { + "websocket-driver": ">=0.5.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "dev": true, + "dependencies": { + "bser": "2.1.1" + } + }, + "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==", + "dev": true, + "dependencies": { + "pend": "~1.2.0" + } + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "flat-cache": "^3.0.4" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "dev": true, + "dependencies": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "dependencies": { + "minimatch": "^5.0.1" + } + }, + "node_modules/filelist/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/filelist/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=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, + "dependencies": { + "to-regex-range": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/finalhandler": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.2.0.tgz", + "integrity": "sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==", + "dev": true, + "dependencies": { + "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" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/finalhandler/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/finalhandler/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/finalhandler/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" + }, + "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==", + "dev": true, + "dependencies": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/flat-cache": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "dependencies": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + }, + "engines": { + "node": "^10.12.0 || >=12.0.0" + } + }, + "node_modules/flatted": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "dev": true + }, + "node_modules/flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "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==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, + "node_modules/for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/format-duration": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/format-duration/-/format-duration-2.0.0.tgz", + "integrity": "sha512-ARqJ9qXm71pw3SGAY7bibf8lRLvltOXLjWjzzR3UrUjHu1zdeYpA/Z+u+ltdhrfRa440OjEsHNzdmuZViqqQWQ==" + }, + "node_modules/forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", + "dev": true, + "dependencies": { + "map-cache": "^0.2.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/framer-motion": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-9.1.7.tgz", + "integrity": "sha512-nKxBkIO4IPkMEqcBbbATxsVjwPYShKl051yhBv9628iAH6JLeHD0siBHxkL62oQzMC1+GNX73XtPjgP753ufuw==", + "dependencies": { + "tslib": "^2.4.0" + }, + "optionalDependencies": { + "@emotion/is-prop-valid": "^0.8.2" + }, + "peerDependencies": { + "react": "^18.0.0", + "react-dom": "^18.0.0" + } + }, + "node_modules/framer-motion/node_modules/@emotion/is-prop-valid": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", + "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "optional": true, + "dependencies": { + "@emotion/memoize": "0.7.4" + } + }, + "node_modules/framer-motion/node_modules/@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", + "optional": true + }, + "node_modules/fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + }, + "engines": { + "node": ">=6 <7 || >=8" + } + }, + "node_modules/fs-merger": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/fs-merger/-/fs-merger-3.2.1.tgz", + "integrity": "sha512-AN6sX12liy0JE7C2evclwoo0aCG3PFulLjrTLsJpWh/2mM+DinhpSGqYLbHBBbIW1PLRNcFhJG8Axtz8mQW3ug==", + "dev": true, + "dependencies": { + "broccoli-node-api": "^1.7.0", + "broccoli-node-info": "^2.1.0", + "fs-extra": "^8.0.1", + "fs-tree-diff": "^2.0.1", + "walk-sync": "^2.2.0" + } + }, + "node_modules/fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/fs-mkdirp-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", + "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.11", + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/fs-mkdirp-stream/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/fs-monkey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", + "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", + "dev": true + }, + "node_modules/fs-tree-diff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fs-tree-diff/-/fs-tree-diff-2.0.1.tgz", + "integrity": "sha512-x+CfAZ/lJHQqwlD64pYM5QxWjzWhSjroaVsr8PW831zOApL55qPibed0c+xebaLWVr2BnHFoHdrwOv8pzt8R5A==", + "dev": true, + "dependencies": { + "@types/symlink-or-copy": "^1.2.0", + "heimdalljs-logger": "^0.1.7", + "object-assign": "^4.1.0", + "path-posix": "^1.0.0", + "symlink-or-copy": "^1.1.8" + }, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "node_modules/function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "node_modules/function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "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==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/fuse.js": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-6.6.2.tgz", + "integrity": "sha512-cJaJkxCCxC8qIIcPBF9yGxY0W/tVZS3uEISDxhYIdtk8OL93pe+6Zj7LjCqVV4dzbqcriOZ+kQ/NE4RXZHsIGA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/gauge": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "dev": true, + "dependencies": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16.0.0" + } + }, + "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==", + "engines": { + "node": ">=6.9.0" + } + }, + "node_modules/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, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "node_modules/get-intrinsic": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz", + "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==", + "engines": { + "node": ">=6" + } + }, + "node_modules/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, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/get-stdin": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "dependencies": { + "pump": "^3.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "is-glob": "^4.0.3" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/glob-stream": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", + "integrity": "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==", + "dev": true, + "dependencies": { + "extend": "^3.0.0", + "glob": "^7.1.1", + "glob-parent": "^3.1.0", + "is-negated-glob": "^1.0.0", + "ordered-read-streams": "^1.0.0", + "pumpify": "^1.3.5", + "readable-stream": "^2.1.5", + "remove-trailing-separator": "^1.0.1", + "to-absolute-glob": "^2.0.0", + "unique-stream": "^2.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/glob-stream/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "dev": true, + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/glob-stream/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "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==", + "dev": true, + "optional": true, + "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" + }, + "engines": { + "node": ">=10.0" + } + }, + "node_modules/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, + "dependencies": { + "global-prefix": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/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, + "dependencies": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/global-prefix/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/globals": { + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "dev": true, + "dependencies": { + "type-fest": "^0.20.2" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "optional": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/globby": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", + "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==", + "dev": true, + "dependencies": { + "array-union": "^2.1.0", + "dir-glob": "^3.0.1", + "fast-glob": "^3.2.9", + "ignore": "^5.2.0", + "merge2": "^1.4.1", + "slash": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/globjoin": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globjoin/-/globjoin-0.1.4.tgz", + "integrity": "sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==", + "dev": true + }, + "node_modules/gonzales-pe": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", + "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5" + }, + "bin": { + "gonzales": "bin/gonzales.js" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.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": ">=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==" + }, + "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==", + "dev": true + }, + "node_modules/gulp-sort": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/gulp-sort/-/gulp-sort-2.0.0.tgz", + "integrity": "sha1-xnYqLx8N4KP8WVohWZ0/rI26Gso=", + "dev": true, + "dependencies": { + "through2": "^2.0.1" + } + }, + "node_modules/gulp-sort/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "dev": true, + "dependencies": { + "duplexer": "^0.1.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "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" + } + }, + "node_modules/harmony-reflect": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", + "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==", + "dev": true + }, + "node_modules/has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dependencies": { + "function-bind": "^1.1.1" + }, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true + }, + "node_modules/has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", + "dev": true, + "dependencies": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/has-values/node_modules/kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true, + "bin": { + "he": "bin/he" + } + }, + "node_modules/heimdalljs": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/heimdalljs/-/heimdalljs-0.2.6.tgz", + "integrity": "sha512-o9bd30+5vLBvBtzCPwwGqpry2+n0Hi6H1+qwt6y+0kwRHGGF8TFIhJPmnuM0xO97zaKrDZMwO/V56fAnn8m/tA==", + "dev": true, + "dependencies": { + "rsvp": "~3.2.1" + } + }, + "node_modules/heimdalljs-logger": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/heimdalljs-logger/-/heimdalljs-logger-0.1.10.tgz", + "integrity": "sha512-pO++cJbhIufVI/fmB/u2Yty3KJD0TqNPecehFae0/eps0hkZ3b4Zc/PezUMOpYuHFQbA7FxHZxa305EhmjLj4g==", + "dev": true, + "dependencies": { + "debug": "^2.2.0", + "heimdalljs": "^0.2.6" + } + }, + "node_modules/heimdalljs-logger/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/heimdalljs-logger/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/heimdalljs/node_modules/rsvp": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.2.1.tgz", + "integrity": "sha1-B8tKXfJa3Z6Cbrxn3Mn9idsn2Eo=", + "dev": true + }, + "node_modules/history": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz", + "integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==", + "dependencies": { + "@babel/runtime": "^7.7.6" + } + }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "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, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "dev": true, + "dependencies": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "node_modules/html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dev": true, + "dependencies": { + "whatwg-encoding": "^1.0.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/html-entities": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", + "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==", + "dev": true + }, + "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==" + }, + "node_modules/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "dev": true, + "dependencies": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "bin": { + "html-minifier-terser": "cli.js" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/html-minifier-terser/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/html-parse-stringify": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", + "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", + "dependencies": { + "void-elements": "3.1.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/html-webpack-plugin": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz", + "integrity": "sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==", + "dev": true, + "dependencies": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/html-webpack-plugin" + }, + "peerDependencies": { + "webpack": "^5.20.0" + } + }, + "node_modules/htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "dev": true, + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "node_modules/http-cache-semantics": { + "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==", + "dev": true + }, + "node_modules/http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", + "dev": 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==", + "dev": true, + "dependencies": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-errors/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/http-parser-js": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.6.tgz", + "integrity": "sha512-vDlkRPDJn93swjcjqMSaGSPABbIarsr1TLAui/gLDXzV5VsJNdXNzMYDyNBLQkjWQCJ1uizu8T2oDMhmGt0PRA==", + "dev": true + }, + "node_modules/http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "dependencies": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "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, + "dependencies": { + "@tootallnate/once": "2", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/http-proxy-middleware": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.4.tgz", + "integrity": "sha512-m/4FxX17SUvz4lJ5WPXOHDUuCwIqXLfLHs1s0uZ3oYjhoXlx9csYxaOa0ElDEJ+h8Q4iJ1s+lTMbiCa4EXIJqg==", + "dev": true, + "dependencies": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "@types/express": "^4.17.13" + }, + "peerDependenciesMeta": { + "@types/express": { + "optional": true + } + } + }, + "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==", + "dev": 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, + "dependencies": { + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/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, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", + "dev": true, + "dependencies": { + "ms": "^2.0.0" + } + }, + "node_modules/husky": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.4.tgz", + "integrity": "sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==", + "dev": true, + "bin": { + "husky": "lib/bin.js" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/typicode" + } + }, + "node_modules/i18next": { + "version": "21.6.16", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-21.6.16.tgz", + "integrity": "sha512-xJlzrVxG9CyAGsbMP1aKuiNr1Ed2m36KiTB7hjGMG2Zo4idfw3p9THUEu+GjBwIgEZ7F11ZbCzJcfv4uyfKNuw==", + "funding": [ + { + "type": "individual", + "url": "https://locize.com" + }, + { + "type": "individual", + "url": "https://locize.com/i18next.html" + }, + { + "type": "individual", + "url": "https://www.i18next.com/how-to/faq#i18next-is-awesome.-how-can-i-support-the-project" + } + ], + "dependencies": { + "@babel/runtime": "^7.17.2" + } + }, + "node_modules/i18next-parser": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/i18next-parser/-/i18next-parser-6.6.0.tgz", + "integrity": "sha512-yA3W6PL+7epCyUFTpUDdztKArfpeGMWRUOnB/4FZRodfXkjCIBcBg728h6b/lrBTbva4OlFjVgv1kCXbvZVRWQ==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.15.4", + "broccoli-plugin": "^4.0.7", + "cheerio": "^1.0.0-rc.2", + "colors": "1.4.0", + "commander": "~9.4.1", + "concat-stream": "~2.0.0", + "eol": "^0.9.1", + "fs-extra": "^10.0.0", + "gulp-sort": "^2.0.0", + "i18next": "^21.2.0", + "js-yaml": "4.1.0", + "rsvp": "^4.8.2", + "sort-keys": "^5.0.0", + "through2": "~4.0.2", + "typescript": "^4.2.4", + "vinyl": "~3.0.0", + "vinyl-fs": "^3.0.2", + "vue-template-compiler": "^2.6.11" + }, + "bin": { + "i18next": "bin/cli.js" + }, + "engines": { + "node": "^14.13.1 || >=16.0.0 || >=18.0.0", + "npm": ">=6", + "yarn": ">=1" + } + }, + "node_modules/i18next-parser/node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/i18next-parser/node_modules/colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true, + "engines": { + "node": ">=0.1.90" + } + }, + "node_modules/i18next-parser/node_modules/commander": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", + "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", + "dev": true, + "engines": { + "node": "^12.20.0 || >=14" + } + }, + "node_modules/i18next-parser/node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "dev": true, + "engines": [ + "node >= 6.0" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/i18next-parser/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/i18next-parser/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/i18next-parser/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/i18next-parser/node_modules/replace-ext": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", + "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/i18next-parser/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/i18next-parser/node_modules/vinyl": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", + "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", + "dev": true, + "dependencies": { + "clone": "^2.1.2", + "clone-stats": "^1.0.0", + "remove-trailing-separator": "^1.1.0", + "replace-ext": "^2.0.0", + "teex": "^1.0.1" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/iconv-corefoundation": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz", + "integrity": "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==", + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "dependencies": { + "cli-truncate": "^2.1.0", + "node-addon-api": "^1.6.3" + }, + "engines": { + "node": "^8.11.2 || >=10" + } + }, + "node_modules/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==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/identity-obj-proxy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", + "integrity": "sha1-lNK9qWCERT7zb7xarsN+D3nx/BQ=", + "dev": true, + "dependencies": { + "harmony-reflect": "^1.4.6" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", + "dev": true + }, + "node_modules/immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, + "node_modules/immutable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz", + "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==", + "dev": true + }, + "node_modules/import-fresh": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz", + "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==", + "dependencies": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/import-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-3.0.0.tgz", + "integrity": "sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ==", + "dev": true, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-from/node_modules/resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/import-local": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-3.1.0.tgz", + "integrity": "sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==", + "dev": true, + "dependencies": { + "pkg-dir": "^4.2.0", + "resolve-cwd": "^3.0.0" + }, + "bin": { + "import-local-fixture": "fixtures/cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true, + "engines": { + "node": ">=0.8.19" + } + }, + "node_modules/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, + "engines": { + "node": ">=8" + } + }, + "node_modules/indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==", + "dev": true + }, + "node_modules/infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "node_modules/inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "dependencies": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "node_modules/inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "node_modules/ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "node_modules/internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/interpret": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dependencies": { + "loose-envify": "^1.0.0" + } + }, + "node_modules/ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "node_modules/ipaddr.js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz", + "integrity": "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "dependencies": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-alphanumeric": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz", + "integrity": "sha512-ZmRL7++ZkcMOfDuWZuMJyIVLr2keE1o/DeNWh1EmgqGhUcV+9BIVsx0BcSBOHTZqzjs4+dISzr2KAeBEWGgXeA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dev": true, + "dependencies": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "dependencies": { + "binary-extensions": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dev": true, + "dependencies": { + "ci-info": "^3.2.0" + }, + "bin": { + "is-ci": "bin.js" + } + }, + "node_modules/is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dependencies": { + "has": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true, + "bin": { + "is-docker": "cli.js" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-electron": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-electron/-/is-electron-2.2.2.tgz", + "integrity": "sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg==" + }, + "node_modules/is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "dependencies": { + "is-plain-object": "^2.0.4" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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, + "engines": { + "node": ">=8" + } + }, + "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, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-glob": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz", + "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=", + "dev": true + }, + "node_modules/is-negated-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "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, + "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==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/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 + }, + "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==", + "dev": true, + "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-regexp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz", + "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "dependencies": { + "is-unc-path": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "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==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-supported-regexp-flag": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-supported-regexp-flag/-/is-supported-regexp-flag-1.0.1.tgz", + "integrity": "sha512-3vcJecUUrpgCqc/ca0aWeNu64UGgxcvO60K/Fkr1N6RSvfGCTU60UKN68JDmKokgba0rFFJs12EnzOQa14ubKQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "node_modules/is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "dependencies": { + "unc-path-regex": "^0.1.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "node_modules/is-valid-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", + "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-what": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.7.tgz", + "integrity": "sha512-DBVOQNiPKnGMxRMLIYSwERAS5MVY1B7xYiGnpgctsOFvVDz9f9PFXXxMcTOHuoqYp4NK9qFYQaIC1NRRxLMpBQ==", + "engines": { + "node": ">=12.13" + }, + "funding": { + "url": "https://github.com/sponsors/mesqueeb" + } + }, + "node_modules/is-whitespace-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", + "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/is-word-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", + "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "dependencies": { + "is-docker": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "node_modules/isbinaryfile": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.0.tgz", + "integrity": "sha512-UDdnyGvMajJUWCkib7Cei/dvyJrrvo4FIrsvSFWdPpXSUorzXrDJ0S+X5Q4ZlasfPjca4yqCNNsjbCeiy8FFeg==", + "dev": true, + "engines": { + "node": ">= 14.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/gjtorikian/" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "node_modules/isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/istanbul-lib-instrument": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", + "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", + "dev": true, + "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/istanbul-lib-instrument/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/istanbul-lib-report": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", + "integrity": "sha512-wcdi+uAKzfiGT2abPpKZ0hSU1rGQjUQnLvtY5MpQ7QCTahD3VODhcu4wcfY1YtkGaDD5yuydOLINXsfbus9ROw==", + "dev": true, + "dependencies": { + "istanbul-lib-coverage": "^3.0.0", + "make-dir": "^3.0.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/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, + "dependencies": { + "debug": "^4.1.1", + "istanbul-lib-coverage": "^3.0.0", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/istanbul-lib-source-maps/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/istanbul-reports": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", + "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", + "dev": true, + "dependencies": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jake": { + "version": "10.8.5", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", + "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", + "dev": true, + "dependencies": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + }, + "bin": { + "jake": "bin/cli.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", + "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", + "dev": true, + "dependencies": { + "@jest/core": "^27.5.1", + "import-local": "^3.0.2", + "jest-cli": "^27.5.1" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-changed-files": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", + "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "execa": "^5.0.0", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-circus": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", + "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-cli": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", + "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", + "dev": true, + "dependencies": { + "@jest/core": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "prompts": "^2.0.1", + "yargs": "^16.2.0" + }, + "bin": { + "jest": "bin/jest.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "node-notifier": "^8.0.1 || ^9.0.0 || ^10.0.0" + }, + "peerDependenciesMeta": { + "node-notifier": { + "optional": true + } + } + }, + "node_modules/jest-config": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", + "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.8.0", + "@jest/test-sequencer": "^27.5.1", + "@jest/types": "^27.5.1", + "babel-jest": "^27.5.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.9", + "jest-circus": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-jasmine2": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "ts-node": ">=9.0.0" + }, + "peerDependenciesMeta": { + "ts-node": { + "optional": true + } + } + }, + "node_modules/jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-docblock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", + "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", + "dev": true, + "dependencies": { + "detect-newline": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-each": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", + "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-jsdom": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", + "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1", + "jsdom": "^16.6.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-environment-node": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", + "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-haste-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", + "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^27.5.1", + "jest-serializer": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "optionalDependencies": { + "fsevents": "^2.3.2" + } + }, + "node_modules/jest-jasmine2": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", + "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-leak-detector": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", + "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", + "dev": true, + "dependencies": { + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "dev": true, + "dependencies": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-mock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-pnp-resolver": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", + "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", + "dev": true, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "jest-resolve": "*" + }, + "peerDependenciesMeta": { + "jest-resolve": { + "optional": true + } + } + }, + "node_modules/jest-regex-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", + "dev": true, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", + "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-resolve-dependencies": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", + "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-snapshot": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runner": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", + "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", + "dev": true, + "dependencies": { + "@jest/console": "^27.5.1", + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-leak-detector": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "source-map-support": "^0.5.6", + "throat": "^6.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-runtime": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", + "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", + "dev": true, + "dependencies": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/globals": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-serializer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", + "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", + "dev": true, + "dependencies": { + "@types/node": "*", + "graceful-fs": "^4.2.9" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-snapshot": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", + "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", + "dev": true, + "dependencies": { + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^27.5.1", + "semver": "^7.3.2" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-validate": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", + "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "leven": "^3.1.0", + "pretty-format": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-watcher": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", + "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", + "dev": true, + "dependencies": { + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^27.5.1", + "string-length": "^4.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "dependencies": { + "@types/node": "*", + "merge-stream": "^2.0.0", + "supports-color": "^8.0.0" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/jest-worker/node_modules/supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/js-sdsl": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", + "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/js-sdsl" + } + }, + "node_modules/js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "dev": true, + "dependencies": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "canvas": "^2.5.0" + }, + "peerDependenciesMeta": { + "canvas": { + "optional": true + } + } + }, + "node_modules/jsdom/node_modules/@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jsdom/node_modules/form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jsdom/node_modules/http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "dependencies": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "bin": { + "jsesc": "bin/jsesc" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "node_modules/json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "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==" + }, + "node_modules/json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true + }, + "node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "node_modules/json-schema-typed": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-7.0.3.tgz", + "integrity": "sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==" + }, + "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": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "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==", + "dev": true, + "optional": true + }, + "node_modules/json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==", + "bin": { + "json5": "lib/cli.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/jsx-ast-utils": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", + "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.5", + "object.assign": "^4.1.3" + }, + "engines": { + "node": ">=4.0" + } + }, + "node_modules/jszip": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.9.1.tgz", + "integrity": "sha512-H9A60xPqJ1CuC4Ka6qxzXZeU8aNmgOeP5IFqwJbQQwtu2EUYxota3LdsiZWplF7Wgd9tkAd0mdu36nceSaPuYw==", + "dev": true, + "dependencies": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "set-immediate-shim": "~1.0.1" + } + }, + "node_modules/keyboardevent-from-electron-accelerator": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/keyboardevent-from-electron-accelerator/-/keyboardevent-from-electron-accelerator-2.0.0.tgz", + "integrity": "sha512-iQcmNA0M4ETMNi0kG/q0h/43wZk7rMeKYrXP7sqKIJbHkTU8Koowgzv+ieR/vWJbOwxx5nDC3UnudZ0aLSu4VA==" + }, + "node_modules/keyboardevents-areequal": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/keyboardevents-areequal/-/keyboardevents-areequal-0.2.2.tgz", + "integrity": "sha512-Nv+Kr33T0mEjxR500q+I6IWisOQ0lK1GGOncV0kWE6n4KFmpcu7RUX5/2B0EUtX51Cb0HjZ9VJsSY3u4cBa0kw==" + }, + "node_modules/keyv": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", + "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, + "node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/kleur": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz", + "integrity": "sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/klona": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz", + "integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==", + "engines": { + "node": ">= 8" + } + }, + "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 + }, + "node_modules/language-subtag-registry": { + "version": "0.3.21", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz", + "integrity": "sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg==", + "dev": true + }, + "node_modules/language-tags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", + "integrity": "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=", + "dev": true, + "dependencies": { + "language-subtag-registry": "~0.3.2" + } + }, + "node_modules/lazy-val": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz", + "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==" + }, + "node_modules/lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.5" + }, + "engines": { + "node": ">= 0.6.3" + } + }, + "node_modules/lead": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", + "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", + "dev": true, + "dependencies": { + "flush-write-stream": "^1.0.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "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, + "engines": { + "node": ">=6" + } + }, + "node_modules/levn": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz", + "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dev": true, + "dependencies": { + "immediate": "~3.0.5" + } + }, + "node_modules/lilconfig": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.5.tgz", + "integrity": "sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "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==" + }, + "node_modules/lint-staged": { + "version": "12.3.7", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-12.3.7.tgz", + "integrity": "sha512-/S4D726e2GIsDVWIk1XGvheCaDm1SJRQp8efamZFWJxQMVEbOwSysp7xb49Oo73KYCdy97mIWinhlxcoNqIfIQ==", + "dev": true, + "dependencies": { + "cli-truncate": "^3.1.0", + "colorette": "^2.0.16", + "commander": "^8.3.0", + "debug": "^4.3.3", + "execa": "^5.1.1", + "lilconfig": "2.0.4", + "listr2": "^4.0.1", + "micromatch": "^4.0.4", + "normalize-path": "^3.0.0", + "object-inspect": "^1.12.0", + "pidtree": "^0.5.0", + "string-argv": "^0.3.1", + "supports-color": "^9.2.1", + "yaml": "^1.10.2" + }, + "bin": { + "lint-staged": "bin/lint-staged.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/lint-staged" + } + }, + "node_modules/lint-staged/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, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/ansi-styles": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.1.0.tgz", + "integrity": "sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/cli-truncate": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", + "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", + "dev": true, + "dependencies": { + "slice-ansi": "^5.0.0", + "string-width": "^5.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true, + "engines": { + "node": ">= 12" + } + }, + "node_modules/lint-staged/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, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/lilconfig": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.4.tgz", + "integrity": "sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "node_modules/lint-staged/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, + "dependencies": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/slice-ansi?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/lint-staged/node_modules/strip-ansi": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", + "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/lint-staged/node_modules/supports-color": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.2.2.tgz", + "integrity": "sha512-XC6g/Kgux+rJXmwokjm9ECpD6k/smUoS5LKlUCcsYr4IY3rW0XyAympon2RmxGrlnZURMpg5T18gWDP9CsHXFA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/listr2": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.5.tgz", + "integrity": "sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA==", + "dev": true, + "dependencies": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.5.5", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + }, + "peerDependencies": { + "enquirer": ">= 2.3.0 < 3" + }, + "peerDependenciesMeta": { + "enquirer": { + "optional": true + } + } + }, + "node_modules/listr2/node_modules/rxjs": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", + "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "dev": true, + "dependencies": { + "tslib": "^2.1.0" + } + }, + "node_modules/load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-json-file/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/load-script": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz", + "integrity": "sha1-BJGTngvuVkPuSUp+PaPSuscMbKQ=" + }, + "node_modules/loader-runner": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", + "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", + "dev": true, + "engines": { + "node": ">=6.11.5" + } + }, + "node_modules/loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "dependencies": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + }, + "engines": { + "node": ">=8.9.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "p-locate": "^5.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", + "dev": true + }, + "node_modules/lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=" + }, + "node_modules/lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + }, + "node_modules/lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "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==", + "dev": true + }, + "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/lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "dev": true + }, + "node_modules/log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/log-update/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, + "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/log-update/node_modules/wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/longest-streak": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", + "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": { + "js-tokens": "^3.0.0 || ^4.0.0" + }, + "bin": { + "loose-envify": "cli.js" + } + }, + "node_modules/loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ==", + "dev": true, + "dependencies": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "dependencies": { + "tslib": "^2.0.3" + } + }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/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==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/lz-string": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", + "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=", + "dev": true, + "bin": { + "lz-string": "bin/bin.js" + } + }, + "node_modules/lzma-native": { + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/lzma-native/-/lzma-native-8.0.6.tgz", + "integrity": "sha512-09xfg67mkL2Lz20PrrDeNYZxzeW7ADtpYFbwSQh9U8+76RIzx5QsJBMy8qikv3hbUPfpy6hqwxt6FcGK81g9AA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "node-addon-api": "^3.1.0", + "node-gyp-build": "^4.2.1", + "readable-stream": "^3.6.0" + }, + "bin": { + "lzmajs": "bin/lzmajs" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/lzma-native/node_modules/node-addon-api": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", + "dev": true + }, + "node_modules/lzma-native/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "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==", + "dev": true, + "dependencies": { + "semver": "^6.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/make-dir/node_modules/semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "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" + } + }, + "node_modules/map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", + "dev": true, + "dependencies": { + "object-visit": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/markdown-escapes": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", + "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/markdown-table": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", + "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", + "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==", + "dev": true, + "optional": true, + "dependencies": { + "escape-string-regexp": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/matcher-collection": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/matcher-collection/-/matcher-collection-2.0.1.tgz", + "integrity": "sha512-daE62nS2ZQsDg9raM0IlZzLmI2u+7ZapXBwdoeBUKAYERPDDIc0qNqA8E0Rp2D+gspKR7BgIFP52GeujaGXWeQ==", + "dev": true, + "dependencies": { + "@types/minimatch": "^3.0.3", + "minimatch": "^3.0.2" + }, + "engines": { + "node": "6.* || 8.* || >= 10.*" + } + }, + "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, + "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" + } + }, + "node_modules/mdast-util-compact": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.4.tgz", + "integrity": "sha512-3YDMQHI5vRiS2uygEFYaqckibpJtKq5Sj2c8JioeOQBU6INpKbdWzfyLqFFnDwEcEnRFIdMsguzs5pC1Jp4Isg==", + "dev": true, + "dependencies": { + "unist-util-visit": "^1.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "dev": true + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/memfs": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.1.tgz", + "integrity": "sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==", + "dev": true, + "dependencies": { + "fs-monkey": "1.0.3" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" + }, + "node_modules/memory-fs": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz", + "integrity": "sha1-8rslNovBIeORwlIN6Slpyu4KApA=", + "dev": true + }, + "node_modules/meow": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-9.0.0.tgz", + "integrity": "sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==", + "dev": true, + "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" + }, + "engines": { + "node": ">=10" + }, + "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==", + "dev": true, + "engines": { + "node": ">=10" + }, + "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": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "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==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromatch": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", + "dev": true, + "dependencies": { + "braces": "^3.0.2", + "picomatch": "^2.3.1" + }, + "engines": { + "node": ">=8.6" + } + }, + "node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "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==", + "engines": { + "node": ">= 0.6" + } + }, + "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==", + "dependencies": { + "mime-db": "1.52.0" + }, + "engines": { + "node": ">= 0.6" + } + }, + "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==", + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/mini-css-extract-plugin": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.0.tgz", + "integrity": "sha512-ndG8nxCEnAemsg4FSgS+yNyHKgkTB4nPKqCOgh65j3/30qqC5RaSQQXMm++Y6sb6E1zRSxPkztj9fqxhS1Eo6w==", + "dev": true, + "dependencies": { + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "dev": 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" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/mini-css-extract-plugin/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/mini-css-extract-plugin/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/mini-css-extract-plugin/node_modules/schema-utils": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "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, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/minimist": { + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz", + "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==", + "dev": 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==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0", + "kind-of": "^6.0.3" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/minimist-options/node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/minipass": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", + "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", + "dev": true, + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "dependencies": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "dependencies": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "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==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mktemp": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/mktemp/-/mktemp-0.4.0.tgz", + "integrity": "sha1-bQUVYRyKjITkhKogABKbmOmB/ws=", + "dev": true, + "engines": { + "node": ">0.9" + } + }, + "node_modules/mrmime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.0.tgz", + "integrity": "sha512-a70zx7zFfVO7XpnQ2IX1Myh9yY4UYvfld/dikWRnsXxbyvMcfz+u6UfgNAtH+k2QqtJuzVpv6eLTx1G2+WKZbQ==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "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/multicast-dns": { + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.4.tgz", + "integrity": "sha512-XkCYOU+rr2Ft3LI6w4ye51M3VK31qJXFIxu0XLw169PtKG0Zx47OrXeVW/GCYOfpC9s1yyyf1S+L8/4LY0J9Zw==", + "dev": true, + "dependencies": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + }, + "bin": { + "multicast-dns": "cli.js" + } + }, + "node_modules/nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "bin": { + "nanoid": "bin/nanoid.cjs" + }, + "engines": { + "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" + } + }, + "node_modules/nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "node_modules/natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha1-F7CVgZiJef3a/gIB6TG6kzyWy7Q=", + "dev": true + }, + "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==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/neo-async": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz", + "integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==", + "dev": true + }, + "node_modules/net": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/net/-/net-1.0.2.tgz", + "integrity": "sha512-kbhcj2SVVR4caaVnGLJKmlk2+f+oLkjqdKeQlmUtz6nGzOpbcobwVIeSURNgraV/v3tlmGIX82OcPCl0K6RbHQ==" + }, + "node_modules/no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "dependencies": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node_modules/node-abi": { + "version": "3.33.0", + "resolved": "https://registry.yarnpkg.com/node-abi/-/node-abi-3.33.0.tgz#8b23a0cec84e1c5f5411836de6a9b84bccf26e7f", + "integrity": "sha512-7GGVawqyHF4pfd0YFybhv/eM9JwTtPqx0mAanQ146O3FlSh3pA24zf9IRQTOsfTSqXTNzPSP5iagAJ94jjuVog==", + "dev": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/node-addon-api": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", + "dev": true, + "optional": true + }, + "node_modules/node-api-version": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.1.4.tgz", + "integrity": "sha512-KGXihXdUChwJAOHO53bv9/vXcLmdUsZ6jIptbvYvkpKfth+r7jw44JkVxQFA3kX5nQjzjmGu1uAu/xNNLNlI5g==", + "dev": true, + "dependencies": { + "semver": "^7.3.5" + } + }, + "node_modules/node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true, + "engines": { + "node": ">= 6.13.0" + } + }, + "node_modules/node-gyp-build": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz", + "integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==", + "dev": true, + "bin": { + "node-gyp-build": "bin.js", + "node-gyp-build-optional": "optional.js", + "node-gyp-build-test": "build-test.js" + } + }, + "node_modules/node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node_modules/node-mpv": { + "version": "2.0.0-beta.3", + "resolved": "git+ssh://git@github.com/jeffvli/Node-MPV.git#c7f84d7966b82e5916c3b4bb47cac667bb895c22" + }, + "node_modules/node-releases": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", + "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==" + }, + "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, + "dependencies": { + "hosted-git-info": "^4.0.1", + "is-core-module": "^2.5.0", + "semver": "^7.3.4", + "validate-npm-package-license": "^3.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/normalize-selector": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz", + "integrity": "sha512-dxvWdI8gw6eAvk9BlPffgEoGfM7AdijoCwOEJge3e3ulT2XLgmU7KvvxprOaCu05Q1uGRHmOhHe1r6emZoKyFw==", + "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==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/now-and-later": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", + "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", + "dev": true, + "dependencies": { + "once": "^1.3.2" + }, + "engines": { + "node": ">= 0.10" + } + }, + "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, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/npmlog": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.1.tgz", + "integrity": "sha512-BTHDvY6nrRHuRfyjt1MAufLxYdVXZfd099H4+i1f0lPywNQyI4foeNXJRObB/uy+TYqUW0vAD9gbdSOXPst7Eg==", + "dev": true, + "dependencies": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.0", + "set-blocking": "^2.0.0" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16" + } + }, + "node_modules/nth-check": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", + "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", + "dev": true, + "dependencies": { + "boolbase": "^1.0.0" + }, + "funding": { + "url": "https://github.com/fb55/nth-check?sponsor=1" + } + }, + "node_modules/num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==", + "dev": true + }, + "node_modules/nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "dev": true + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", + "dev": true, + "dependencies": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/is-descriptor/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object-copy/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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==", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", + "dev": true, + "dependencies": { + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.entries": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", + "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", + "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.hasown": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", + "integrity": "sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", + "dev": true, + "dependencies": { + "isobject": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/object.values": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", + "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "ee-first": "1.1.1" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "dependencies": { + "wrappy": "1" + } + }, + "node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/open": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", + "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", + "dev": true, + "dependencies": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true, + "bin": { + "opener": "bin/opener-bin.js" + } + }, + "node_modules/optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "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" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "dependencies": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/ordered-read-streams": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", + "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", + "dev": true, + "dependencies": { + "readable-stream": "^2.0.1" + } + }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "dependencies": { + "yocto-queue": "^0.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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==", + "dev": true, + "dependencies": { + "p-limit": "^3.0.2" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "dependencies": { + "aggregate-error": "^3.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/p-retry": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.1.tgz", + "integrity": "sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA==", + "dev": true, + "dependencies": { + "@types/retry": "^0.12.0", + "retry": "^0.13.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/p-retry/node_modules/retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "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==", + "engines": { + "node": ">=6" + } + }, + "node_modules/pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "node_modules/param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dev": true, + "dependencies": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "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==", + "dependencies": { + "callsites": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/parse-entities": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", + "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==", + "dev": true, + "dependencies": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, + "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==", + "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" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dev": true, + "dependencies": { + "parse5": "^6.0.1" + } + }, + "node_modules/parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "dependencies": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "node_modules/pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": 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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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==" + }, + "node_modules/path-posix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-posix/-/path-posix-1.0.0.tgz", + "integrity": "sha1-BrJhE/Vr6rBCVFojv6iAA8ysJg8=", + "dev": true + }, + "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": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "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==", + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true + }, + "node_modules/picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "node_modules/picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", + "engines": { + "node": ">=8.6" + }, + "funding": { + "url": "https://github.com/sponsors/jonschlinkert" + } + }, + "node_modules/pidtree": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.5.0.tgz", + "integrity": "sha512-9nxspIM7OpZuhBxPg73Zvyq7j1QMPMPsGKTqRc2XOaFQauDvoNz9fM1Wdkjmeo7l9GXOZiRs97sPkuayl39wjA==", + "dev": true, + "bin": { + "pidtree": "bin/pidtree.js" + }, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/pirates": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", + "integrity": "sha512-8V9+HQPupnaXMA23c5hvl69zXvTwTzyAYasnkb0Tts4XvO4CliqONMOnvlq26rkhLC3nWDFBJf73LU1e1VZLaQ==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "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, + "dependencies": { + "find-up": "^4.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, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "dependencies": { + "find-up": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/pkg-up/node_modules/find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dependencies": { + "locate-path": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dependencies": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/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==", + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/pkg-up/node_modules/p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dependencies": { + "p-limit": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/pkg-up/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "engines": { + "node": ">=4" + } + }, + "node_modules/plist": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.6.tgz", + "integrity": "sha512-WiIVYyrp8TD4w8yCvyeIr+lkmrGRd5u0VbRnU+tP/aRLxP/YadJUYOMZJ/6hIa3oUyVCsycXvtNRgd5XBJIbiA==", + "dev": true, + "dependencies": { + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/portfinder": { + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", + "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", + "dev": true, + "dependencies": { + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.5" + }, + "engines": { + "node": ">= 0.12.0" + } + }, + "node_modules/portfinder/node_modules/async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "dependencies": { + "lodash": "^4.17.14" + } + }, + "node_modules/portfinder/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss": { + "version": "8.4.20", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz", + "integrity": "sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==", + "dev": true, + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/postcss" + } + ], + "dependencies": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + }, + "engines": { + "node": "^10 || ^12 || >=14" + } + }, + "node_modules/postcss-calc": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", + "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.9", + "postcss-value-parser": "^4.2.0" + }, + "peerDependencies": { + "postcss": "^8.2.2" + } + }, + "node_modules/postcss-colormin": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.0.tgz", + "integrity": "sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg==", + "dev": true, + "dependencies": { + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0", + "colord": "^2.9.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-convert-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.0.tgz", + "integrity": "sha512-GkyPbZEYJiWtQB0KZ0X6qusqFHUepguBCNFi9t5JJc7I2OTXG7C0twbTLvCfaKOLl3rSXmpAwV7W5txd91V84g==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-comments": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.1.tgz", + "integrity": "sha512-5JscyFmvkUxz/5/+TB3QTTT9Gi9jHkcn8dcmmuN68JQcv3aQg4y88yEHHhwFB52l/NkaJ43O0dbksGMAo49nfQ==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-duplicates": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", + "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-empty": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", + "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-discard-overridden": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", + "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-html": { + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-0.36.0.tgz", + "integrity": "sha512-HeiOxGcuwID0AFsNAL0ox3mW6MHH5cstWN1Z3Y+n6H+g12ih7LHdYxWwEA/QmrebctLjo79xz9ouK3MroHwOJw==", + "dev": true, + "dependencies": { + "htmlparser2": "^3.10.0" + }, + "peerDependencies": { + "postcss": ">=5.0.0", + "postcss-syntax": ">=0.36.0" + } + }, + "node_modules/postcss-html/node_modules/dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dev": true, + "dependencies": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + } + }, + "node_modules/postcss-html/node_modules/dom-serializer/node_modules/domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ] + }, + "node_modules/postcss-html/node_modules/dom-serializer/node_modules/entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, + "node_modules/postcss-html/node_modules/domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "node_modules/postcss-html/node_modules/domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "dependencies": { + "domelementtype": "1" + } + }, + "node_modules/postcss-html/node_modules/domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "dependencies": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "node_modules/postcss-html/node_modules/entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "node_modules/postcss-html/node_modules/htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dev": true, + "dependencies": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "node_modules/postcss-html/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/postcss-jsx": { + "version": "0.36.4", + "resolved": "https://registry.npmjs.org/postcss-jsx/-/postcss-jsx-0.36.4.tgz", + "integrity": "sha512-jwO/7qWUvYuWYnpOb0+4bIIgJt7003pgU3P6nETBLaOyBXuTD55ho21xnals5nBrlpTIFodyd3/jBi6UO3dHvA==", + "dev": true, + "dependencies": { + "@babel/core": ">=7.2.2" + }, + "peerDependencies": { + "postcss": ">=5.0.0", + "postcss-syntax": ">=0.36.0" + } + }, + "node_modules/postcss-less": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-3.1.4.tgz", + "integrity": "sha512-7TvleQWNM2QLcHqvudt3VYjULVB49uiW6XzEUFmvwHzvsOEF5MwBrIXZDJQvJNFGjJQTzSzZnDoCJ8h/ljyGXA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.14" + }, + "engines": { + "node": ">=6.14.4" + } + }, + "node_modules/postcss-less/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "node_modules/postcss-less/node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-less/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-markdown": { + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/postcss-markdown/-/postcss-markdown-0.36.0.tgz", + "integrity": "sha512-rl7fs1r/LNSB2bWRhyZ+lM/0bwKv9fhl38/06gF6mKMo/NPnp55+K1dSTosSVjFZc0e1ppBlu+WT91ba0PMBfQ==", + "dev": true, + "dependencies": { + "remark": "^10.0.1", + "unist-util-find-all-after": "^1.0.2" + }, + "peerDependencies": { + "postcss": ">=5.0.0", + "postcss-syntax": ">=0.36.0" + } + }, + "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-merge-longhand": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.4.tgz", + "integrity": "sha512-hbqRRqYfmXoGpzYKeW0/NCZhvNyQIlQeWVSao5iKWdyx7skLvCfQFGIUsP9NUs3dSbPac2IC4Go85/zG+7MlmA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^5.1.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-merge-rules": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.1.tgz", + "integrity": "sha512-8wv8q2cXjEuCcgpIB1Xx1pIy8/rhMPIQqYKNzEdyx37m6gpq83mQQdCxgIkFgliyEnKvdwJf/C61vN4tQDq4Ww==", + "dev": true, + "dependencies": { + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^3.1.0", + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-font-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", + "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-gradients": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", + "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", + "dev": true, + "dependencies": { + "colord": "^2.9.1", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-params": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.2.tgz", + "integrity": "sha512-aEP+p71S/urY48HWaRHasyx4WHQJyOYaKpQ6eXl8k0kxg66Wt/30VR6/woh8THgcpRbonJD5IeD+CzNhPi1L8g==", + "dev": true, + "dependencies": { + "browserslist": "^4.16.6", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-minify-selectors": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.0.tgz", + "integrity": "sha512-vYxvHkW+iULstA+ctVNx0VoRAR4THQQRkG77o0oa4/mBS0OzGvvzLIvHDv/nNEM0crzN2WIyFU5X7wZhaUK3RA==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-modules-extract-imports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-local-by-default": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", + "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-scope": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "dependencies": { + "icss-utils": "^5.0.0" + }, + "engines": { + "node": "^10 || ^12 || >= 14" + }, + "peerDependencies": { + "postcss": "^8.1.0" + } + }, + "node_modules/postcss-normalize-charset": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", + "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", + "dev": true, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-display-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", + "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-positions": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.0.tgz", + "integrity": "sha512-8gmItgA4H5xiUxgN/3TVvXRoJxkAWLW6f/KKhdsH03atg0cB8ilXnrB5PpSshwVu/dD2ZsRFQcR1OEmSBDAgcQ==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-repeat-style": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.0.tgz", + "integrity": "sha512-IR3uBjc+7mcWGL6CtniKNQ4Rr5fTxwkaDHwMBDGGs1x9IVRkYIT/M4NelZWkAOBdV6v3Z9S46zqaKGlyzHSchw==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-string": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", + "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-timing-functions": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", + "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-unicode": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.0.tgz", + "integrity": "sha512-J6M3MizAAZ2dOdSjy2caayJLQT8E8K9XjLce8AUQMwOrCvjCHv24aLC/Lps1R1ylOfol5VIDMaM/Lo9NGlk1SQ==", + "dev": true, + "dependencies": { + "browserslist": "^4.16.6", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", + "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", + "dev": true, + "dependencies": { + "normalize-url": "^6.0.1", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-normalize-whitespace": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", + "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-ordered-values": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.1.tgz", + "integrity": "sha512-7lxgXF0NaoMIgyihL/2boNAEZKiW0+HkMhdKMTD93CjW8TdCy2hSdj8lsAo+uwm7EDG16Da2Jdmtqpedl0cMfw==", + "dev": true, + "dependencies": { + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-reduce-initial": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.0.tgz", + "integrity": "sha512-5OgTUviz0aeH6MtBjHfbr57tml13PuedK/Ecg8szzd4XRMbYxH4572JFG067z+FqBIf6Zp/d+0581glkvvWMFw==", + "dev": true, + "dependencies": { + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-reduce-transforms": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", + "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-reporter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-6.0.1.tgz", + "integrity": "sha512-LpmQjfRWyabc+fRygxZjpRxfhRf9u/fdlKf4VHG4TSPbV2XNsuISzYW1KL+1aQzx53CAppa1bKG4APIB/DOXXw==", + "dev": true, + "dependencies": { + "chalk": "^2.4.1", + "lodash": "^4.17.11", + "log-symbols": "^2.2.0", + "postcss": "^7.0.7" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/postcss-reporter/node_modules/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, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-reporter/node_modules/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, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-reporter/node_modules/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, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/postcss-reporter/node_modules/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 + }, + "node_modules/postcss-reporter/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, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/postcss-reporter/node_modules/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, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-reporter/node_modules/log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "dependencies": { + "chalk": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-reporter/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "node_modules/postcss-reporter/node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-reporter/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-reporter/node_modules/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, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "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/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, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.3.3" + } + }, + "node_modules/postcss-sass": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.3.5.tgz", + "integrity": "sha512-B5z2Kob4xBxFjcufFnhQ2HqJQ2y/Zs/ic5EZbCywCkxKd756Q40cIQ/veRDwSrw1BF6+4wUgmpm0sBASqVi65A==", + "dev": true, + "dependencies": { + "gonzales-pe": "^4.2.3", + "postcss": "^7.0.1" + } + }, + "node_modules/postcss-sass/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "node_modules/postcss-sass/node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/postcss-sass/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postcss-scss": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.4.tgz", + "integrity": "sha512-aBBbVyzA8b3hUL0MGrpydxxXKXFZc5Eqva0Q3V9qsBOLEMsjb6w49WfpsoWzpEgcqJGW4t7Rio8WXVU9Gd8vWg==", + "dev": true, + "engines": { + "node": ">=12.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + }, + "peerDependencies": { + "postcss": "^8.3.3" + } + }, + "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==", + "dev": true, + "dependencies": { + "cssesc": "^3.0.0", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss-sorting": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-7.0.1.tgz", + "integrity": "sha512-iLBFYz6VRYyLJEJsBJ8M3TCqNcckVzz4wFounSc5Oez35ogE/X+aoC5fFu103Ot7NyvjU3/xqIXn93Gp3kJk4g==", + "dev": true, + "peerDependencies": { + "postcss": "^8.3.9" + } + }, + "node_modules/postcss-svgo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", + "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", + "dev": true, + "dependencies": { + "postcss-value-parser": "^4.2.0", + "svgo": "^2.7.0" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/postcss-syntax": { + "version": "0.36.2", + "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz", + "integrity": "sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==", + "dev": true, + "peerDependencies": { + "postcss": ">=5.0.0" + } + }, + "node_modules/postcss-unique-selectors": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", + "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", + "dev": true, + "dependencies": { + "postcss-selector-parser": "^6.0.5" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "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==" + }, + "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==", + "dev": true, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/prettier": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz", + "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==", + "dev": true, + "bin": { + "prettier": "bin-prettier.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, + "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, + "dependencies": { + "fast-diff": "^1.1.2" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/pretty-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "node_modules/pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "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, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "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==", + "dev": true + }, + "node_modules/progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true, + "engines": { + "node": ">=0.4.0" + } + }, + "node_modules/promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "node_modules/promise-map-series": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/promise-map-series/-/promise-map-series-0.3.0.tgz", + "integrity": "sha512-3npG2NGhTc8BWBolLLf8l/92OxMGaRLbqvIh9wjCHhDXNvk4zsxaTaCpiCunW09qWPrN2zeNSNwRLVBrQQtutA==", + "dev": true, + "engines": { + "node": "10.* || >= 12.*" + } + }, + "node_modules/promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "dependencies": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + }, + "engines": { + "node": ">=10" + } + }, + "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" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "dependencies": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + } + }, + "node_modules/prop-types/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "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==", + "dev": true, + "dependencies": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-addr/node_modules/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==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, + "node_modules/psl": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "node_modules/pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "dependencies": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + } + }, + "node_modules/pumpify/node_modules/pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "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==", + "engines": { + "node": ">=6" + } + }, + "node_modules/qs": { + "version": "6.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dev": true, + "dependencies": { + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">=0.6" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ] + }, + "node_modules/queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "dev": true + }, + "node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/quick-temp": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/quick-temp/-/quick-temp-0.1.8.tgz", + "integrity": "sha1-urAqJCq4+w3XWKPJd2sy+aXZRAg=", + "dev": true, + "dependencies": { + "mktemp": "~0.4.0", + "rimraf": "^2.5.4", + "underscore.string": "~3.3.4" + } + }, + "node_modules/quick-temp/node_modules/rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.1.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==", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "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==", + "dev": true, + "dependencies": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "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==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "dependencies": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "peerDependencies": { + "react": "^18.2.0" + } + }, + "node_modules/react-dom/node_modules/scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/react-error-boundary": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz", + "integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==", + "dependencies": { + "@babel/runtime": "^7.12.5" + }, + "engines": { + "node": ">=10", + "npm": ">=6" + }, + "peerDependencies": { + "react": ">=16.13.1" + } + }, + "node_modules/react-fast-compare": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" + }, + "node_modules/react-i18next": { + "version": "11.16.7", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.16.7.tgz", + "integrity": "sha512-7yotILJLnKfvUfrl/nt9eK9vFpVFjZPLWAwBzWL6XppSZZEvlmlKk0GBGDCAPfLfs8oND7WAbry8wGzdoiW5Nw==", + "dependencies": { + "@babel/runtime": "^7.14.5", + "html-escaper": "^2.0.2", + "html-parse-stringify": "^3.0.1" + }, + "peerDependencies": { + "i18next": ">= 19.0.0", + "react": ">= 16.8.0" + }, + "peerDependenciesMeta": { + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + } + } + }, + "node_modules/react-icons": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.8.0.tgz", + "integrity": "sha512-N6+kOLcihDiAnj5Czu637waJqSnwlMNROzVZMhfX68V/9bu9qHaMIJC4UdozWoOk57gahFCNHwVvWzm0MTzRjg==", + "peerDependencies": { + "react": "*" + } + }, + "node_modules/react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + }, + "node_modules/react-player": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/react-player/-/react-player-2.11.0.tgz", + "integrity": "sha512-fIrwpuXOBXdEg1FiyV9isKevZOaaIsAAtZy5fcjkQK9Nhmk1I2NXzY/hkPos8V0zb/ZX416LFy8gv7l/1k3a5w==", + "dependencies": { + "deepmerge": "^4.0.0", + "load-script": "^1.0.0", + "memoize-one": "^5.1.1", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.0.1" + }, + "peerDependencies": { + "react": ">=16.6.0" + } + }, + "node_modules/react-player/node_modules/memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" + }, + "node_modules/react-refresh": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.12.0.tgz", + "integrity": "sha512-suLIhrU2IHKL5JEKR/fAwJv7bbeq4kJ+pJopf77jHwuR+HmJS/HbrPIGsTBUVfw7tXPOmYv7UJ7PCaN49e8x4A==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/react-refresh-typescript": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/react-refresh-typescript/-/react-refresh-typescript-2.0.4.tgz", + "integrity": "sha512-ySsBExEFik5Jjf7NoXtFbzUk2rYWM4gF5gg+wRTNmp9p7B2uMpAAa339FHWqmB8EAr0e6mzzskAXxc0Jd04fBw==", + "dev": true, + "peerDependencies": { + "react-refresh": "0.10.x || 0.11.x || 0.12.x", + "typescript": "^4" + } + }, + "node_modules/react-remove-scroll": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", + "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", + "dependencies": { + "react-remove-scroll-bar": "^2.3.3", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-remove-scroll-bar": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz", + "integrity": "sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==", + "dependencies": { + "react-style-singleton": "^2.2.1", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-router": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.5.0.tgz", + "integrity": "sha512-fqqUSU0NC0tSX0sZbyuxzuAzvGqbjiZItBQnyicWlOUmzhAU8YuLgRbaCL2hf3sJdtRy4LP/WBrWtARkMvdGPQ==", + "dependencies": { + "@remix-run/router": "1.1.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": ">=16.8" + } + }, + "node_modules/react-router-dom": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.5.0.tgz", + "integrity": "sha512-/XzRc5fq80gW1ctiIGilyKFZC/j4kfe75uivMsTChFbkvrK4ZrF3P3cGIc1f/SSkQ4JiJozPrf+AwUHHWVehVg==", + "dependencies": { + "@remix-run/router": "1.1.0", + "react-router": "6.5.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/react-shallow-renderer": { + "version": "16.15.0", + "resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz", + "integrity": "sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA==", + "dev": true, + "dependencies": { + "object-assign": "^4.1.1", + "react-is": "^16.12.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependencies": { + "react": "^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-simple-img": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-simple-img/-/react-simple-img-3.0.0.tgz", + "integrity": "sha512-I0sG/GgY9c+04BgWf1YRlipWBQxR3oG2s/bagU8EO7zals3/Vkfk1PJMeYh/wHfjxJtUmal+y7HWEBm4MzXVsQ==", + "peerDependencies": { + "react": ">= 16.3.0", + "react-dom": ">= 16.3.0" + } + }, + "node_modules/react-style-singleton": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", + "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", + "dependencies": { + "get-nonce": "^1.0.0", + "invariant": "^2.2.4", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/react-test-renderer": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-18.0.0.tgz", + "integrity": "sha512-SyZTP/FSkwfiKOZuTZiISzsrC8A80KNlQ8PyyoGoOq+VzMAab6Em1POK/CiX3+XyXG6oiJa1C53zYDbdrJu9fw==", + "dev": true, + "dependencies": { + "react-is": "^18.0.0", + "react-shallow-renderer": "^16.13.1", + "scheduler": "^0.21.0" + }, + "peerDependencies": { + "react": "^18.0.0" + } + }, + "node_modules/react-test-renderer/node_modules/react-is": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.0.0.tgz", + "integrity": "sha512-yUcBYdBBbo3QiPsgYDcfQcIkGZHfxOaoE6HLSnr1sPzMhdyxusbfKOSUbSd/ocGi32dxcj366PsTj+5oggeKKw==", + "dev": true + }, + "node_modules/react-textarea-autosize": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.4.tgz", + "integrity": "sha512-CdtmP8Dc19xL8/R6sWvtknD/eCXkQr30dtvC4VmGInhRsfF8X/ihXCq6+9l9qbxmKRiq407/7z5fxE7cVWQNgQ==", + "dependencies": { + "@babel/runtime": "^7.10.2", + "use-composed-ref": "^1.3.0", + "use-latest": "^1.2.1" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-transition-group": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", + "integrity": "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==", + "dependencies": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + }, + "peerDependencies": { + "react": ">=16.6.0", + "react-dom": ">=16.6.0" + } + }, + "node_modules/react-virtualized-auto-sizer": { + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.17.tgz", + "integrity": "sha512-XtojyZHGo/iYmGkOEL8psTQsr5XI4fd+QxCD16ru00mnJhuvXFXcPLHXj5cKJh/xUttxPCglnpUI8d2u6gUgzw==", + "peerDependencies": { + "react": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc", + "react-dom": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0-rc" + } + }, + "node_modules/react-window": { + "version": "1.8.9", + "resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.9.tgz", + "integrity": "sha512-+Eqx/fj1Aa5WnhRfj9dJg4VYATGwIUP2ItwItiJ6zboKWA6EX3lYDAXfGF2hyNqplEprhbtjbipiADEcwQ823Q==", + "dependencies": { + "@babel/runtime": "^7.0.0", + "memoize-one": ">=3.1.1 <6" + }, + "engines": { + "node": ">8.0.0" + }, + "peerDependencies": { + "react": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0", + "react-dom": "^15.0.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-window-infinite-loader": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/react-window-infinite-loader/-/react-window-infinite-loader-1.0.9.tgz", + "integrity": "sha512-5Hg89IdU4Vrp0RT8kZYKeTIxWZYhNkVXeI1HbKo01Vm/Z7qztDvXljwx16sMzsa9yapRJQW3ODZfMUw38SOWHw==", + "engines": { + "node": ">8.0.0" + }, + "peerDependencies": { + "react": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0", + "react-dom": "^15.3.0 || ^16.0.0-alpha || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/react-window/node_modules/memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" + }, + "node_modules/read-config-file": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-6.3.2.tgz", + "integrity": "sha512-M80lpCjnE6Wt6zb98DoW8WHR09nzMSpu8XHtPkiTHrJ5Az9CybfeQhTJ8D7saeBHpGhLPIVyA8lcL6ZmdKwY6Q==", + "dev": true, + "dependencies": { + "config-file-ts": "^0.2.4", + "dotenv": "^9.0.2", + "dotenv-expand": "^5.1.0", + "js-yaml": "^4.1.0", + "json5": "^2.2.0", + "lazy-val": "^1.0.4" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "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, + "dependencies": { + "@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/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, + "dependencies": { + "find-up": "^4.1.0", + "read-pkg": "^5.2.0", + "type-fest": "^0.8.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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, + "dependencies": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "dependencies": { + "p-locate": "^4.1.0" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "dependencies": { + "p-try": "^2.0.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "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, + "dependencies": { + "p-limit": "^2.2.0" + }, + "engines": { + "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==", + "dev": true, + "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, + "bin": { + "semver": "bin/semver" + } + }, + "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, + "engines": { + "node": ">=8" + } + }, + "node_modules/readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": 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/readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "dependencies": { + "picomatch": "^2.2.1" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/rechoir": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", + "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "dev": true, + "dependencies": { + "resolve": "^1.9.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "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/regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + }, + "node_modules/regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/mysticatea" + } + }, + "node_modules/relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/remark": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/remark/-/remark-10.0.1.tgz", + "integrity": "sha512-E6lMuoLIy2TyiokHprMjcWNJ5UxfGQjaMSMhV+f4idM625UjjK4j798+gPs5mfjzDE6vL0oFKVeZM6gZVSVrzQ==", + "dev": true, + "dependencies": { + "remark-parse": "^6.0.0", + "remark-stringify": "^6.0.0", + "unified": "^7.0.0" + } + }, + "node_modules/remark-parse": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-6.0.3.tgz", + "integrity": "sha512-QbDXWN4HfKTUC0hHa4teU463KclLAnwpn/FBn87j9cKYJWWawbiLgMfP2Q4XwhxxuuuOxHlw+pSN0OKuJwyVvg==", + "dev": true, + "dependencies": { + "collapse-white-space": "^1.0.2", + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "is-word-character": "^1.0.0", + "markdown-escapes": "^1.0.0", + "parse-entities": "^1.1.0", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "trim": "0.0.1", + "trim-trailing-lines": "^1.0.0", + "unherit": "^1.0.4", + "unist-util-remove-position": "^1.0.0", + "vfile-location": "^2.0.0", + "xtend": "^4.0.1" + } + }, + "node_modules/remark-stringify": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-6.0.4.tgz", + "integrity": "sha512-eRWGdEPMVudijE/psbIDNcnJLRVx3xhfuEsTDGgH4GsFF91dVhw5nhmnBppafJ7+NWINW6C7ZwWbi30ImJzqWg==", + "dev": true, + "dependencies": { + "ccount": "^1.0.0", + "is-alphanumeric": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "longest-streak": "^2.0.1", + "markdown-escapes": "^1.0.0", + "markdown-table": "^1.1.0", + "mdast-util-compact": "^1.0.0", + "parse-entities": "^1.0.2", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "stringify-entities": "^1.0.1", + "unherit": "^1.0.4", + "xtend": "^4.0.1" + } + }, + "node_modules/remove-accents": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz", + "integrity": "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA==" + }, + "node_modules/remove-bom-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", + "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5", + "is-utf8": "^0.2.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/remove-bom-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", + "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", + "dev": true, + "dependencies": { + "remove-bom-buffer": "^3.0.0", + "safe-buffer": "^5.1.0", + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/remove-bom-stream/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "node_modules/renderkid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "dev": true, + "dependencies": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "node_modules/repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true, + "engines": { + "node": ">=0.10" + } + }, + "node_modules/replace-ext": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", + "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true, + "engines": { + "node": ">=0.10.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==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", + "dev": true, + "engines": { + "node": ">=0.10.5" + } + }, + "node_modules/requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "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==", + "dependencies": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": 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, + "dependencies": { + "resolve-from": "^5.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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, + "engines": { + "node": ">=8" + } + }, + "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==", + "engines": { + "node": ">=4" + } + }, + "node_modules/resolve-options": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", + "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", + "dev": true, + "dependencies": { + "value-or-function": "^3.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "deprecated": "https://github.com/lydell/resolve-url#deprecated", + "dev": true + }, + "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/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true, + "engines": { + "iojs": ">=1.0.0", + "node": ">=0.10.0" + } + }, + "node_modules/rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, + "node_modules/rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "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==", + "dev": true, + "optional": true, + "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" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "dev": true, + "engines": { + "node": "6.* || >= 7.*" + } + }, + "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==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "queue-microtask": "^1.2.2" + } + }, + "node_modules/runtime-required": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/runtime-required/-/runtime-required-1.1.0.tgz", + "integrity": "sha512-yX97f5E0WfNpcQnfVjap6vzQcvErkYYCx6eTK4siqGEdC8lglwypUFgZVTX7ShvIlgfkC4XGFl9O1KTYcff0pw==", + "dev": true, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "dependencies": { + "tslib": "^1.9.0" + }, + "engines": { + "npm": ">=2.0.0" + } + }, + "node_modules/rxjs/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "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==" + }, + "node_modules/safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "dependencies": { + "ret": "~0.1.10" + } + }, + "node_modules/safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "node_modules/sanitize-filename": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", + "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", + "dev": true, + "dependencies": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "node_modules/sass": { + "version": "1.50.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.50.0.tgz", + "integrity": "sha512-cLsD6MEZ5URXHStxApajEh7gW189kkjn4Rc8DQweMyF+o5HF5nfEz8QYLMlPsTOD88DknatTmBWkOcw5/LnJLQ==", + "dev": true, + "dependencies": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + }, + "bin": { + "sass": "sass.js" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/sass-loader": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz", + "integrity": "sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==", + "dev": true, + "dependencies": { + "klona": "^2.0.4", + "neo-async": "^2.6.2" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "fibers": ">= 3.1.0", + "node-sass": "^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0", + "sass": "^1.3.0", + "sass-embedded": "*", + "webpack": "^5.0.0" + }, + "peerDependenciesMeta": { + "fibers": { + "optional": true + }, + "node-sass": { + "optional": true + }, + "sass": { + "optional": true + }, + "sass-embedded": { + "optional": true + } + } + }, + "node_modules/sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "node_modules/saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "dependencies": { + "xmlchars": "^2.2.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/scheduler": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", + "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", + "dev": true, + "dependencies": { + "loose-envify": "^1.1.0" + } + }, + "node_modules/schema-utils": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz", + "integrity": "sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", + "dev": true + }, + "node_modules/selfsigned": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.0.1.tgz", + "integrity": "sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ==", + "dev": true, + "dependencies": { + "node-forge": "^1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": true, + "optional": true + }, + "node_modules/send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "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" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "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==", + "dev": true, + "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": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/send/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/send/node_modules/mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4" + } + }, + "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==", + "dev": true + }, + "node_modules/send/node_modules/statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "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==", + "dev": true, + "optional": true, + "dependencies": { + "type-fest": "^0.13.1" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-error/node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "dev": true, + "dependencies": { + "randombytes": "^2.1.0" + } + }, + "node_modules/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "dev": true, + "dependencies": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/serve-index/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/serve-index/node_modules/http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "dependencies": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/serve-index/node_modules/inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "node_modules/serve-index/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "node_modules/serve-index/node_modules/setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "node_modules/set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/set-value/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "node_modules/shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "dependencies": { + "kind-of": "^6.0.2" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, + "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==", + "dev": true, + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "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/simple-update-notifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", + "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", + "dev": true, + "dependencies": { + "semver": "~7.0.0" + }, + "engines": { + "node": ">=8.10.0" + } + }, + "node_modules/simple-update-notifier/node_modules/semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, + "node_modules/sirv": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.19.tgz", + "integrity": "sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==", + "dev": true, + "dependencies": { + "@polka/url": "^1.0.0-next.20", + "mrmime": "^1.0.0", + "totalist": "^1.0.0" + }, + "engines": { + "node": ">= 10" + } + }, + "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, + "engines": { + "node": ">=8" + } + }, + "node_modules/slice-ansi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">= 6.0.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "dependencies": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "dependencies": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-node/node_modules/define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "dependencies": { + "is-descriptor": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "dependencies": { + "kind-of": "^3.2.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon-util/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "dependencies": { + "ms": "2.0.0" + } + }, + "node_modules/snapdragon/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "node_modules/snapdragon/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/snapdragon/node_modules/source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "dev": true, + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "node_modules/sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "dependencies": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "node_modules/socks": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz", + "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==", + "dev": true, + "dependencies": { + "ip": "^1.1.5", + "smart-buffer": "^4.2.0" + }, + "engines": { + "node": ">= 10.13.0", + "npm": ">= 3.0.0" + } + }, + "node_modules/sort-keys": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-5.0.0.tgz", + "integrity": "sha512-Pdz01AvCAottHTPQGzndktFNdbRA75BgOfeT1hH+AMnJFv8lynkPi42rfeEhpx1saTEI3YNMWxfqu0sFD1G8pw==", + "dev": true, + "dependencies": { + "is-plain-obj": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/sort-keys/node_modules/is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true, + "engines": { + "node": ">= 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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-resolve": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", + "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", + "deprecated": "See https://github.com/lydell/source-map-resolve#deprecated", + "dev": true, + "dependencies": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "node_modules/source-map-support/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "deprecated": "See https://github.com/lydell/source-map-url#deprecated", + "dev": true + }, + "node_modules/spawn-command": { + "version": "0.0.2-1", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", + "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=", + "dev": true + }, + "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, + "dependencies": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "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==", + "dev": true, + "dependencies": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "node_modules/spdx-license-ids": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", + "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", + "dev": true + }, + "node_modules/spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "dependencies": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + } + }, + "node_modules/spdy-transport/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/specificity": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.4.1.tgz", + "integrity": "sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==", + "dev": true, + "bin": { + "specificity": "bin/specificity" + } + }, + "node_modules/split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "dependencies": { + "extend-shallow": "^3.0.0" + }, + "engines": { + "node": ">=0.10.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==", + "dev": true + }, + "node_modules/ssr-window": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/ssr-window/-/ssr-window-4.0.2.tgz", + "integrity": "sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ==" + }, + "node_modules/stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "deprecated": "Modern JS already guarantees Array#sort() is a stable sort, so this library is deprecated. See the compatibility table on MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#browser_compatibility", + "dev": 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==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "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, + "engines": { + "node": ">=8" + } + }, + "node_modules/stackframe": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", + "dev": true + }, + "node_modules/stat-mode": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz", + "integrity": "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/state-toggle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", + "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "dependencies": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "dependencies": { + "is-descriptor": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-accessor-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-data-descriptor/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "dependencies": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/static-extend/node_modules/kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, + "node_modules/streamx": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.13.2.tgz", + "integrity": "sha512-+TWqixPhGDXEG9L/XczSbhfkmwAtGs3BJX5QNU6cvno+pOLKeszByWcnaTu6dg8efsTYqR8ZZuXWHhZfgrxMvA==", + "dev": true, + "dependencies": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + } + }, + "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==", + "dev": true, + "dependencies": { + "safe-buffer": "~5.1.0" + } + }, + "node_modules/string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true, + "engines": { + "node": ">=0.6.19" + } + }, + "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, + "dependencies": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "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, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width/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 + }, + "node_modules/string.prototype.matchall": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", + "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.4.3", + "side-channel": "^1.0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/stringify-entities": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.2.tgz", + "integrity": "sha512-nrBAQClJAPN2p+uGCVJRPIPakKeKWZ9GtBCmormE7pWOSlHat7+x5A8gx85M7HM5Dt0BP3pP5RhVW77WdbJJ3A==", + "dev": true, + "dependencies": { + "character-entities-html4": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-hexadecimal": "^1.0.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==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "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==", + "dev": true, + "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==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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, + "dependencies": { + "min-indent": "^1.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/style-loader": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz", + "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==", + "dev": true, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.0.0" + } + }, + "node_modules/style-search": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", + "integrity": "sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=", + "dev": true + }, + "node_modules/styled-components": { + "version": "5.3.11", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.11.tgz", + "integrity": "sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==", + "dependencies": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/traverse": "^7.4.5", + "@emotion/is-prop-valid": "^1.1.0", + "@emotion/stylis": "^0.8.4", + "@emotion/unitless": "^0.7.4", + "babel-plugin-styled-components": ">= 1.12.0", + "css-to-react-native": "^3.0.0", + "hoist-non-react-statics": "^3.0.0", + "shallowequal": "^1.1.0", + "supports-color": "^5.5.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/styled-components" + }, + "peerDependencies": { + "react": ">= 16.8.0", + "react-dom": ">= 16.8.0", + "react-is": ">= 16.8.0" + } + }, + "node_modules/styled-components/node_modules/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==", + "engines": { + "node": ">=4" + } + }, + "node_modules/styled-components/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylehacks": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.0.tgz", + "integrity": "sha512-SzLmvHQTrIWfSgljkQCw2++C9+Ne91d/6Sp92I8c5uHTcy/PgeHamwITIbBW9wnFTY/3ZfSXR9HIL6Ikqmcu6Q==", + "dev": true, + "dependencies": { + "browserslist": "^4.16.6", + "postcss-selector-parser": "^6.0.4" + }, + "engines": { + "node": "^10 || ^12 || >=14.0" + }, + "peerDependencies": { + "postcss": "^8.2.15" + } + }, + "node_modules/stylelint": { + "version": "14.9.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.9.1.tgz", + "integrity": "sha512-RdAkJdPiLqHawCSnu21nE27MjNXaVd4WcOHA4vK5GtIGjScfhNnaOuWR2wWdfKFAvcWQPOYe311iveiVKSmwsA==", + "dev": true, + "dependencies": { + "@csstools/selector-specificity": "^2.0.1", + "balanced-match": "^2.0.0", + "colord": "^2.9.2", + "cosmiconfig": "^7.0.1", + "css-functions-list": "^3.1.0", + "debug": "^4.3.4", + "execall": "^2.0.0", + "fast-glob": "^3.2.11", + "fastest-levenshtein": "^1.0.12", + "file-entry-cache": "^6.0.1", + "get-stdin": "^8.0.0", + "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.14", + "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.2.0", + "svg-tags": "^1.0.0", + "table": "^6.8.0", + "v8-compile-cache": "^2.3.0", + "write-file-atomic": "^4.0.1" + }, + "bin": { + "stylelint": "bin/stylelint.js" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/stylelint" + } + }, + "node_modules/stylelint-config-rational-order": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/stylelint-config-rational-order/-/stylelint-config-rational-order-0.1.2.tgz", + "integrity": "sha512-Qo7ZQaihCwTqijfZg4sbdQQHtugOX/B1/fYh018EiDZHW+lkqH9uHOnsDwDPGZrYJuB6CoyI7MZh2ecw2dOkew==", + "dev": true, + "dependencies": { + "stylelint": "^9.10.1", + "stylelint-order": "^2.2.1" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "dev": true, + "engines": { + "node": ">= 6" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/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, + "dependencies": { + "color-convert": "^1.9.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "dependencies": { + "sprintf-js": "~1.0.2" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "dev": true, + "dependencies": { + "array-uniq": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "dependencies": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/braces/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/camelcase-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", + "integrity": "sha512-Ej37YKYbFUI8QiYlvj9YHb6/Z60dZyPJW0Cs8sFilMbd2lP0bw3ylAq9yJkK4lcTA2dID5fG8LjmJYbO7kWb7Q==", + "dev": true, + "dependencies": { + "camelcase": "^4.1.0", + "map-obj": "^2.0.0", + "quick-lru": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/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, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/clone-regexp": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-1.0.1.tgz", + "integrity": "sha512-Fcij9IwRW27XedRIJnSOEupS7RVcXtObJXbcUOX93UCLqqOdRpkvzKywOOSizmEK/Is3S/RHX9dLdfo6R1Q1mw==", + "dev": true, + "dependencies": { + "is-regexp": "^1.0.0", + "is-supported-regexp-flag": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/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, + "dependencies": { + "color-name": "1.1.3" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/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 + }, + "node_modules/stylelint-config-rational-order/node_modules/cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "dependencies": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "dev": true, + "dependencies": { + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "node_modules/stylelint-config-rational-order/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, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/execall": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execall/-/execall-1.0.0.tgz", + "integrity": "sha512-/J0Q8CvOvlAdpvhfkD/WnTQ4H1eU0exze2nFGPj/RSC7jpQ0NkKe2r28T5eMkhEEs+fzepMZNy1kVRKNlC04nQ==", + "dev": true, + "dependencies": { + "clone-regexp": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/fast-glob": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "dev": true, + "dependencies": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/file-entry-cache": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-4.0.0.tgz", + "integrity": "sha512-AVSwsnbV8vH/UVbvgEhf3saVQXORNv0ZzSkvkhQIaia5Tia+JhGTaa/ePUSVoPHQyGayQNmYfkzFi3WZV5zcpA==", + "dev": true, + "dependencies": { + "flat-cache": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dev": true, + "dependencies": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/fill-range/node_modules/extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "dependencies": { + "is-extendable": "^0.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "dependencies": { + "locate-path": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "dependencies": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "node_modules/stylelint-config-rational-order/node_modules/get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "dev": true, + "dependencies": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/glob-parent/node_modules/is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "dev": true, + "dependencies": { + "is-extglob": "^2.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/globby": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", + "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", + "dev": true, + "dependencies": { + "@types/glob": "^7.1.1", + "array-union": "^1.0.2", + "dir-glob": "^2.2.2", + "fast-glob": "^2.2.6", + "glob": "^7.1.3", + "ignore": "^4.0.3", + "pify": "^4.0.1", + "slash": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/globby/node_modules/ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true, + "engines": { + "node": ">= 4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/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, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/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/stylelint-config-rational-order/node_modules/html-tags": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz", + "integrity": "sha512-+Il6N8cCo2wB/Vd3gqy/8TZhTD3QvcVeQLCnZiGkGCH3JP28IgGAY41giccp2W4R3jfyJPAP318FQTa1yU7K7g==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", + "dev": true, + "dependencies": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/import-fresh/node_modules/resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/import-lazy": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-3.1.0.tgz", + "integrity": "sha512-8/gvXvX2JMn0F+CDlSC4l6kOmVaLOO3XLkksI7CI3Ud95KDYJuYur2b9P/PUt/i/pDAMd/DulQsNbbbmRRsDIQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha512-BYqTHXTGUIvg7t1r4sJNKcbDZkL92nkXA8YtRpbjFHRHGDL/NtUeiBJMeE60kIFN/Mg8ESaWQvftaYMGJzQZCQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/is-number/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylelint-config-rational-order/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==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/is-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "dependencies": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/known-css-properties": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.11.0.tgz", + "integrity": "sha512-bEZlJzXo5V/ApNNa5z375mJC6Nrz4vG43UgcSCrg2OHC+yuB6j0iDSrY7RQ/+PRofFB03wNIIt9iXIVLr4wc7w==", + "dev": true + }, + "node_modules/stylelint-config-rational-order/node_modules/leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "dependencies": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "dependencies": { + "chalk": "^2.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/map-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", + "integrity": "sha512-TzQSV2DiMYgoF5RycneKVUzIa9bQsj/B3tTgsE3dOGqlzHnGIDaC7XBE7grnA+8kZPnfqSGFe95VHc2oc0VFUQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/meow": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz", + "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==", + "dev": true, + "dependencies": { + "camelcase-keys": "^4.0.0", + "decamelize-keys": "^1.0.0", + "loud-rejection": "^1.0.0", + "minimist-options": "^3.0.1", + "normalize-package-data": "^2.3.4", + "read-pkg-up": "^3.0.0", + "redent": "^2.0.0", + "trim-newlines": "^2.0.0", + "yargs-parser": "^10.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "dependencies": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/minimist-options": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", + "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", + "dev": true, + "dependencies": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0" + }, + "engines": { + "node": ">= 4" + } + }, + "node_modules/stylelint-config-rational-order/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, + "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/stylelint-config-rational-order/node_modules/p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "dependencies": { + "p-try": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "dependencies": { + "p-limit": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "dependencies": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "dependencies": { + "pify": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/path-type/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "node_modules/stylelint-config-rational-order/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/postcss-safe-parser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz", + "integrity": "sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g==", + "dev": true, + "dependencies": { + "postcss": "^7.0.26" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/postcss-scss": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.1.1.tgz", + "integrity": "sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA==", + "dev": true, + "dependencies": { + "postcss": "^7.0.6" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "dependencies": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/postcss-sorting": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-4.1.0.tgz", + "integrity": "sha512-r4T2oQd1giURJdHQ/RMb72dKZCuLOdWx2B/XhXN1Y1ZdnwXsKH896Qz6vD4tFy9xSjpKNYhlZoJmWyhH/7JUQw==", + "dev": true, + "dependencies": { + "lodash": "^4.17.4", + "postcss": "^7.0.0" + }, + "engines": { + "node": ">=6.14.3" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "node_modules/stylelint-config-rational-order/node_modules/quick-lru": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", + "integrity": "sha512-tRS7sTgyxMXtLum8L65daJnHUhfDUgboRdcWW2bR9vBfrj2+O5HSMbQOJfJJjIVSPFqbBCF37FpwWXGitDc5tA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "dependencies": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "dependencies": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/redent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", + "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "dev": true, + "dependencies": { + "indent-string": "^3.0.0", + "strip-indent": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "dependencies": { + "glob": "^7.1.3" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true, + "bin": { + "semver": "bin/semver" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stylelint-config-rational-order/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "node_modules/stylelint-config-rational-order/node_modules/string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "dependencies": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "dependencies": { + "ansi-regex": "^4.1.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/strip-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/stylelint": { + "version": "9.10.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-9.10.1.tgz", + "integrity": "sha512-9UiHxZhOAHEgeQ7oLGwrwoDR8vclBKlSX7r4fH0iuu0SfPwFaLkb1c7Q2j1cqg9P7IDXeAV2TvQML/fRQzGBBQ==", + "dev": true, + "dependencies": { + "autoprefixer": "^9.0.0", + "balanced-match": "^1.0.0", + "chalk": "^2.4.1", + "cosmiconfig": "^5.0.0", + "debug": "^4.0.0", + "execall": "^1.0.0", + "file-entry-cache": "^4.0.0", + "get-stdin": "^6.0.0", + "global-modules": "^2.0.0", + "globby": "^9.0.0", + "globjoin": "^0.1.4", + "html-tags": "^2.0.0", + "ignore": "^5.0.4", + "import-lazy": "^3.1.0", + "imurmurhash": "^0.1.4", + "known-css-properties": "^0.11.0", + "leven": "^2.1.0", + "lodash": "^4.17.4", + "log-symbols": "^2.0.0", + "mathml-tag-names": "^2.0.1", + "meow": "^5.0.0", + "micromatch": "^3.1.10", + "normalize-selector": "^0.2.0", + "pify": "^4.0.0", + "postcss": "^7.0.13", + "postcss-html": "^0.36.0", + "postcss-jsx": "^0.36.0", + "postcss-less": "^3.1.0", + "postcss-markdown": "^0.36.0", + "postcss-media-query-parser": "^0.2.3", + "postcss-reporter": "^6.0.0", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-safe-parser": "^4.0.0", + "postcss-sass": "^0.3.5", + "postcss-scss": "^2.0.0", + "postcss-selector-parser": "^3.1.0", + "postcss-syntax": "^0.36.2", + "postcss-value-parser": "^3.3.0", + "resolve-from": "^4.0.0", + "signal-exit": "^3.0.2", + "slash": "^2.0.0", + "specificity": "^0.4.1", + "string-width": "^3.0.0", + "style-search": "^0.1.0", + "sugarss": "^2.0.0", + "svg-tags": "^1.0.0", + "table": "^5.0.0" + }, + "bin": { + "stylelint": "bin/stylelint.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/stylelint-order": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-2.2.1.tgz", + "integrity": "sha512-019KBV9j8qp1MfBjJuotse6MgaZqGVtXMc91GU9MsS9Feb+jYUvUU3Z8XiClqPdqJZQ0ryXQJGg3U3PcEjXwfg==", + "dev": true, + "dependencies": { + "lodash": "^4.17.10", + "postcss": "^7.0.2", + "postcss-sorting": "^4.1.0" + }, + "engines": { + "node": ">=6" + }, + "peerDependencies": { + "stylelint": "^9.10.1 || ^10.0.0" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/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, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "dependencies": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "engines": { + "node": ">=6.0.0" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "dependencies": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/trim-newlines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", + "integrity": "sha512-MTBWv3jhVjTU7XR3IQHllbiJs8sc75a80OEhB6or/q7pLTWgQ0bMGQXXYQSrSuXe6WiKWDZ5txXY5P59a/coVA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/stylelint-config-rational-order/node_modules/yargs-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", + "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "dev": true, + "dependencies": { + "camelcase": "^4.1.0" + } + }, + "node_modules/stylelint-config-recommended": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-7.0.0.tgz", + "integrity": "sha512-yGn84Bf/q41J4luis1AZ95gj0EQwRX8lWmGmBwkwBNSkpGSpl66XcPTulxGa/Z91aPoNGuIGBmFkcM1MejMo9Q==", + "dev": true, + "peerDependencies": { + "stylelint": "^14.4.0" + } + }, + "node_modules/stylelint-config-recommended-scss": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-6.0.0.tgz", + "integrity": "sha512-6QOe2/OzXV2AP5FE12A7+qtKdZik7Saf42SMMl84ksVBBPpTdrV+9HaCbPYiRMiwELY9hXCVdH4wlJ+YJb5eig==", + "dev": true, + "dependencies": { + "postcss-scss": "^4.0.2", + "stylelint-config-recommended": "^7.0.0", + "stylelint-scss": "^4.0.0" + }, + "peerDependencies": { + "stylelint": "^14.4.0" + } + }, + "node_modules/stylelint-config-standard": { + "version": "25.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-25.0.0.tgz", + "integrity": "sha512-21HnP3VSpaT1wFjFvv9VjvOGDtAviv47uTp3uFmzcN+3Lt+RYRv6oAplLaV51Kf792JSxJ6svCJh/G18E9VnCA==", + "dev": true, + "dependencies": { + "stylelint-config-recommended": "^7.0.0" + }, + "peerDependencies": { + "stylelint": "^14.4.0" + } + }, + "node_modules/stylelint-config-standard-scss": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard-scss/-/stylelint-config-standard-scss-4.0.0.tgz", + "integrity": "sha512-xizu8PTEyB6zYXBiVg6VtvUYn9m57x+6ZtaOdaxsfpbe5eagLPGNlbYnKfm/CfN69ArUpnwR6LjgsTHzlGbtXQ==", + "dev": true, + "dependencies": { + "stylelint-config-recommended-scss": "^6.0.0", + "stylelint-config-standard": "^25.0.0" + }, + "peerDependencies": { + "stylelint": "^14.4.0" + } + }, + "node_modules/stylelint-config-styled-components": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/stylelint-config-styled-components/-/stylelint-config-styled-components-0.1.1.tgz", + "integrity": "sha512-z5Xz/9GmvxO6e/DLzBMwkB85zHxEEjN6K7Cj80Bi+o/9vR9eS3GX3E9VuMnX9WLFYulqbqLtTapGGY28JBiy9Q==", + "dev": true + }, + "node_modules/stylelint-order": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-5.0.0.tgz", + "integrity": "sha512-OWQ7pmicXufDw5BlRqzdz3fkGKJPgLyDwD1rFY3AIEfIH/LQY38Vu/85v8/up0I+VPiuGRwbc2Hg3zLAsJaiyw==", + "dev": true, + "dependencies": { + "postcss": "^8.3.11", + "postcss-sorting": "^7.0.1" + }, + "peerDependencies": { + "stylelint": "^14.0.0" + } + }, + "node_modules/stylelint-processor-styled-components": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/stylelint-processor-styled-components/-/stylelint-processor-styled-components-1.10.0.tgz", + "integrity": "sha512-g4HpN9rm0JD0LoHuIOcd/FIjTZCJ0ErQ+dC3VTxp+dSvnkV+MklKCCmCQEdz5K5WxF4vPuzfVgdbSDuPYGZhoA==", + "dev": true, + "dependencies": { + "@babel/parser": "^7.8.3", + "@babel/traverse": "^7.8.3", + "micromatch": "^4.0.2", + "postcss": "^7.0.26" + } + }, + "node_modules/stylelint-processor-styled-components/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "node_modules/stylelint-processor-styled-components/node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/stylelint-processor-styled-components/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, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/stylelint-scss": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-4.3.0.tgz", + "integrity": "sha512-GvSaKCA3tipzZHoz+nNO7S02ZqOsdBzMiCx9poSmLlb3tdJlGddEX/8QzCOD8O7GQan9bjsvLMsO5xiw6IhhIQ==", + "dev": true, + "dependencies": { + "lodash": "^4.17.21", + "postcss-media-query-parser": "^0.2.3", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-selector-parser": "^6.0.6", + "postcss-value-parser": "^4.1.0" + }, + "peerDependencies": { + "stylelint": "^14.5.1" + } + }, + "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/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/stylelint/node_modules/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, + "engines": { + "node": ">=0.10.0" + } + }, + "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, + "engines": { + "node": ">=8" + } + }, + "node_modules/stylelint/node_modules/write-file-atomic": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz", + "integrity": "sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + }, + "engines": { + "node": "^12.13.0 || ^14.15.0 || >=16" + } + }, + "node_modules/stylis": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz", + "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==" + }, + "node_modules/sugarss": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-2.0.0.tgz", + "integrity": "sha512-WfxjozUk0UVA4jm+U1d736AUpzSrNsQcIbyOkoE364GrtWmIrFdk5lksEupgWMD4VaT/0kVx1dobpiDumSgmJQ==", + "dev": true, + "dependencies": { + "postcss": "^7.0.2" + } + }, + "node_modules/sugarss/node_modules/picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "node_modules/sugarss/node_modules/postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "dependencies": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + }, + "engines": { + "node": ">=6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/postcss/" + } + }, + "node_modules/sugarss/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, + "engines": { + "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==", + "dev": true, + "dependencies": { + "debug": "^4.1.0" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/superjson": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/superjson/-/superjson-1.11.0.tgz", + "integrity": "sha512-6PfAg1FKhqkwWvPb2uXhH4MkMttdc17eJ91+Aoz4s1XUEDZFmLfFx/xVA3wgkPxAGy5dpozgGdK6V/n20Wj9yg==", + "dependencies": { + "copy-anything": "^3.0.2" + }, + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "dev": true, + "dependencies": { + "has-flag": "^4.0.0", + "supports-color": "^7.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==", + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", + "dev": true + }, + "node_modules/svgo": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", + "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", + "dev": true, + "dependencies": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^4.1.3", + "css-tree": "^1.1.3", + "csso": "^4.2.0", + "picocolors": "^1.0.0", + "stable": "^0.1.8" + }, + "bin": { + "svgo": "bin/svgo" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/svgo/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/swiper": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-9.3.1.tgz", + "integrity": "sha512-YBDf0DLBLO7O4rwYHfz+HltkY4sDwKSbRf1it56rngpkYHxiKg0NkPMXAFmw2nGvMNQJwV14Dse47hQIifJzzA==", + "funding": [ + { + "type": "patreon", + "url": "https://www.patreon.com/swiperjs" + }, + { + "type": "open_collective", + "url": "http://opencollective.com/swiper" + } + ], + "dependencies": { + "ssr-window": "^4.0.2" + }, + "engines": { + "node": ">= 4.7.0" + } + }, + "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/symlink-or-copy": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/symlink-or-copy/-/symlink-or-copy-1.3.1.tgz", + "integrity": "sha512-0K91MEXFpBUaywiwSSkmKjnGcasG/rVBXFLJz5DrgGabpYD6N+3yZrfD6uUIfpuTu65DZLHi7N8CizHc07BPZA==", + "dev": true + }, + "node_modules/tabbable": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.1.1.tgz", + "integrity": "sha512-4kl5w+nCB44EVRdO0g/UGoOp3vlwgycUVtkk/7DPyeLZUCuNFFKCFG6/t/DgHLrUPHjrZg6s5tNm+56Q2B0xyg==" + }, + "node_modules/table": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", + "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", + "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" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "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, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "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/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, + "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/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tar": { + "version": "6.1.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz", + "integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==", + "dev": true, + "dependencies": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^4.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/tar/node_modules/minipass": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.5.tgz", + "integrity": "sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/tar/node_modules/mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true, + "bin": { + "mkdirp": "bin/cmd.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/teex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", + "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", + "dev": true, + "dependencies": { + "streamx": "^2.12.5" + } + }, + "node_modules/temp-file": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz", + "integrity": "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==", + "dev": true, + "dependencies": { + "async-exit-hook": "^2.0.1", + "fs-extra": "^10.0.0" + } + }, + "node_modules/temp-file/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/temp-file/node_modules/jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "dependencies": { + "universalify": "^2.0.0" + }, + "optionalDependencies": { + "graceful-fs": "^4.1.6" + } + }, + "node_modules/temp-file/node_modules/universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true, + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "dependencies": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/terser": { + "version": "5.17.7", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.7.tgz", + "integrity": "sha512-/bi0Zm2C6VAexlGgLlVxA0P2lru/sdLyfCVaRMfKVo9nWxbmz7f/sD8VPybPeSUJaJcwmCJis9pBIhcVcG1QcQ==", + "dev": true, + "dependencies": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "bin": { + "terser": "bin/terser" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/terser-webpack-plugin": { + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", + "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", + "dev": true, + "dependencies": { + "@jridgewell/trace-mapping": "^0.3.17", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.16.8" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^5.1.0" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "esbuild": { + "optional": true + }, + "uglify-js": { + "optional": true + } + } + }, + "node_modules/terser/node_modules/commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "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==", + "dev": true, + "dependencies": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "node_modules/throat": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", + "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", + "dev": true + }, + "node_modules/through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "node_modules/through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "dependencies": { + "readable-stream": "3" + } + }, + "node_modules/through2-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", + "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", + "dev": true, + "dependencies": { + "through2": "~2.0.0", + "xtend": "~4.0.0" + } + }, + "node_modules/through2-filter/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/through2/node_modules/readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "node_modules/tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "dependencies": { + "rimraf": "^3.0.0" + }, + "engines": { + "node": ">=8.17.0" + } + }, + "node_modules/tmp-promise": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", + "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "dev": true, + "dependencies": { + "tmp": "^0.2.0" + } + }, + "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-absolute-glob": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", + "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", + "dev": true, + "dependencies": { + "is-absolute": "^1.0.0", + "is-negated-glob": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "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": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "engines": { + "node": ">=4" + } + }, + "node_modules/to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "dependencies": { + "kind-of": "^3.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-object-path/node_modules/kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "dependencies": { + "is-buffer": "^1.1.5" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "dependencies": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "dependencies": { + "is-number": "^7.0.0" + }, + "engines": { + "node": ">=8.0" + } + }, + "node_modules/to-through": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", + "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", + "dev": true, + "dependencies": { + "through2": "^2.0.3" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/to-through/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=0.6" + } + }, + "node_modules/totalist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", + "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "dev": true, + "dependencies": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "dev": true, + "dependencies": { + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true, + "bin": { + "tree-kill": "cli.js" + } + }, + "node_modules/trim": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", + "integrity": "sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ==", + "deprecated": "Use String.prototype.trim() instead", + "dev": true + }, + "node_modules/trim-newlines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz", + "integrity": "sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/trim-trailing-lines": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz", + "integrity": "sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/trough": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/truncate-utf8-bytes": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", + "dev": true, + "dependencies": { + "utf8-byte-length": "^1.0.1" + } + }, + "node_modules/ts-jest": { + "version": "27.1.4", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.4.tgz", + "integrity": "sha512-qjkZlVPWVctAezwsOD1OPzbZ+k7zA5z3oxII4dGdZo5ggX/PL7kvwTM0pXTr10fAtbiVpJaL3bWd502zAhpgSQ==", + "dev": true, + "dependencies": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^27.0.0", + "json5": "2.x", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "20.x" + }, + "bin": { + "ts-jest": "cli.js" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + }, + "peerDependencies": { + "@babel/core": ">=7.0.0-beta.0 <8", + "@types/jest": "^27.0.0", + "babel-jest": ">=27.0.0 <28", + "jest": "^27.0.0", + "typescript": ">=3.8 <5.0" + }, + "peerDependenciesMeta": { + "@babel/core": { + "optional": true + }, + "@types/jest": { + "optional": true + }, + "babel-jest": { + "optional": true + }, + "esbuild": { + "optional": true + } + } + }, + "node_modules/ts-loader": { + "version": "9.2.8", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.2.8.tgz", + "integrity": "sha512-gxSak7IHUuRtwKf3FIPSW1VpZcqF9+MBrHOvBp9cjHh+525SjtCIJKVGjRKIAfxBwDGDGCFF00rTfzB1quxdSw==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4" + }, + "engines": { + "node": ">=12.0.0" + }, + "peerDependencies": { + "typescript": "*", + "webpack": "^5.0.0" + } + }, + "node_modules/ts-loader/node_modules/enhanced-resolve": { + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.2.tgz", + "integrity": "sha512-GIm3fQfwLJ8YZx2smuHpBKkXC1yOk+OBEmKckVyL0i/ea8mqDEykK3ld5dgH1QYPNyT/lIllxV2LULnxCHaHkA==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/ts-node": { + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", + "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", + "dev": true, + "dependencies": { + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.0", + "yn": "3.1.1" + }, + "bin": { + "ts-node": "dist/bin.js", + "ts-node-cwd": "dist/bin-cwd.js", + "ts-node-esm": "dist/bin-esm.js", + "ts-node-script": "dist/bin-script.js", + "ts-node-transpile-only": "dist/bin-transpile.js", + "ts-script": "dist/bin-script-deprecated.js" + }, + "peerDependencies": { + "@swc/core": ">=1.2.50", + "@swc/wasm": ">=1.2.50", + "@types/node": "*", + "typescript": ">=2.7" + }, + "peerDependenciesMeta": { + "@swc/core": { + "optional": true + }, + "@swc/wasm": { + "optional": true + } + } + }, + "node_modules/ts-node/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/tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, + "node_modules/tsconfig-paths-webpack-plugin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.0.0.tgz", + "integrity": "sha512-fw/7265mIWukrSHd0i+wSwx64kYUSAKPfxRDksjKIYTxSAp9W9/xcZVBF4Kl0eqQd5eBpAQ/oQrc5RyM/0c1GQ==", + "dev": true, + "dependencies": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.7.0", + "tsconfig-paths": "^4.0.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/tsconfig-paths-webpack-plugin/node_modules/enhanced-resolve": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", + "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/tsconfig-paths-webpack-plugin/node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tsconfig-paths-webpack-plugin/node_modules/tsconfig-paths": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.1.0.tgz", + "integrity": "sha512-AHx4Euop/dXFC+Vx589alFba8QItjF+8hf8LtmuiCwHyI4rHXQtOOENaM8kvYf5fR0dRChy3wzWIZ9WbB7FWow==", + "dev": true, + "dependencies": { + "json5": "^2.2.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/tsconfig-paths/node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, + "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": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "node_modules/tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "dependencies": { + "tslib": "^1.8.1" + }, + "engines": { + "node": ">= 6" + }, + "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" + } + }, + "node_modules/tsutils/node_modules/tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "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==", + "dev": true, + "dependencies": { + "prelude-ls": "^1.2.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, + "engines": { + "node": ">=4" + } + }, + "node_modules/type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "dependencies": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "node_modules/typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "dependencies": { + "is-typedarray": "^1.0.0" + } + }, + "node_modules/typescript": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "dev": true, + "bin": { + "tsc": "bin/tsc", + "tsserver": "bin/tsserver" + }, + "engines": { + "node": ">=4.2.0" + } + }, + "node_modules/typescript-plugin-styled-components": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/typescript-plugin-styled-components/-/typescript-plugin-styled-components-2.0.0.tgz", + "integrity": "sha512-Wu7F96dwuphgiACHfu63vTbRRg6tkPwLnpFJwdxM70Y0PLfeKLRnvs2Yo5MAySMwE120ODMKk9W4TtJgY1ZumA==", + "dev": true, + "peerDependencies": { + "typescript": "^4.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==", + "dev": true, + "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/unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/underscore.string": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz", + "integrity": "sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ==", + "dev": true, + "dependencies": { + "sprintf-js": "^1.1.1", + "util-deprecate": "^1.0.2" + }, + "engines": { + "node": "*" + } + }, + "node_modules/unherit": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", + "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", + "dev": true, + "dependencies": { + "inherits": "^2.0.0", + "xtend": "^4.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/unified": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-7.1.0.tgz", + "integrity": "sha512-lbk82UOIGuCEsZhPj8rNAkXSDXd6p0QLzIuSsCdxrqnqU56St4eyOB+AlXsVgVeRmetPTYydIuvFfpDIed8mqw==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0", + "@types/vfile": "^3.0.0", + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^1.1.0", + "trough": "^1.0.0", + "vfile": "^3.0.0", + "x-is-string": "^0.1.0" + } + }, + "node_modules/unified/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==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "dependencies": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/union-value/node_modules/is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "node_modules/unique-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", + "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", + "dev": true, + "dependencies": { + "json-stable-stringify-without-jsonify": "^1.0.1", + "through2-filter": "^3.0.0" + } + }, + "node_modules/unist-util-find-all-after": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-1.0.5.tgz", + "integrity": "sha512-lWgIc3rrTMTlK1Y0hEuL+k+ApzFk78h+lsaa2gHf63Gp5Ww+mt11huDniuaoq1H+XMK2lIIjjPkncxXcDp3QDw==", + "dev": true, + "dependencies": { + "unist-util-is": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-is": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", + "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==", + "dev": true + }, + "node_modules/unist-util-remove-position": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz", + "integrity": "sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==", + "dev": true, + "dependencies": { + "unist-util-visit": "^1.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", + "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==", + "dev": true + }, + "node_modules/unist-util-visit": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", + "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "dev": true, + "dependencies": { + "unist-util-visit-parents": "^2.0.0" + } + }, + "node_modules/unist-util-visit-parents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", + "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "dev": true, + "dependencies": { + "unist-util-is": "^3.0.0" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/unixify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unixify/-/unixify-1.0.0.tgz", + "integrity": "sha1-OmQcjC/7zk2mg6XHDwOkYpQMIJA=", + "dev": true, + "dependencies": { + "normalize-path": "^2.1.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unixify/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "dependencies": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", + "dev": true, + "dependencies": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-value/node_modules/isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", + "dev": true, + "dependencies": { + "isarray": "1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unset-value/node_modules/has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/unzip-crx-3": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/unzip-crx-3/-/unzip-crx-3-0.2.0.tgz", + "integrity": "sha512-0+JiUq/z7faJ6oifVB5nSwt589v1KCduqIJupNVDoWSXZtWDmjDGO3RAEOvwJ07w90aoXoP4enKsR7ecMrJtWQ==", + "dev": true, + "dependencies": { + "jszip": "^3.1.0", + "mkdirp": "^0.5.1", + "yaku": "^0.16.6" + } + }, + "node_modules/update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/browserslist" + } + ], + "dependencies": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + }, + "bin": { + "browserslist-lint": "cli.js" + }, + "peerDependencies": { + "browserslist": ">= 4.21.0" + } + }, + "node_modules/uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dependencies": { + "punycode": "^2.1.0" + } + }, + "node_modules/urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "deprecated": "Please see https://github.com/lydell/urix#deprecated", + "dev": true + }, + "node_modules/url-loader": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", + "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", + "dev": true, + "dependencies": { + "loader-utils": "^2.0.0", + "mime-types": "^2.1.27", + "schema-utils": "^3.0.0" + }, + "engines": { + "node": ">= 10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "file-loader": "*", + "webpack": "^4.0.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "file-loader": { + "optional": true + } + } + }, + "node_modules/use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/use-callback-ref": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.0.tgz", + "integrity": "sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==", + "dependencies": { + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-composed-ref": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.3.0.tgz", + "integrity": "sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/use-isomorphic-layout-effect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", + "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-latest": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.2.1.tgz", + "integrity": "sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==", + "dependencies": { + "use-isomorphic-layout-effect": "^1.1.1" + }, + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sidecar": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", + "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", + "dependencies": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "peerDependencies": { + "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, + "node_modules/utf8-byte-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", + "integrity": "sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==", + "dev": true + }, + "node_modules/util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "node_modules/utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", + "dev": true + }, + "node_modules/utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true, + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "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-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "node_modules/v8-to-istanbul": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + }, + "engines": { + "node": ">=10.12.0" + } + }, + "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, + "dependencies": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "node_modules/value-or-function": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", + "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/verror": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", + "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", + "dev": true, + "optional": true, + "dependencies": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + }, + "engines": { + "node": ">=0.6.0" + } + }, + "node_modules/verror/node_modules/core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true, + "optional": true + }, + "node_modules/vfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-3.0.1.tgz", + "integrity": "sha512-y7Y3gH9BsUSdD4KzHsuMaCzRjglXN0W2EcMf0gpvu6+SbsGhMje7xDc8AEoeXy6mIwCKMI6BkjMsRjzQbhMEjQ==", + "dev": true, + "dependencies": { + "is-buffer": "^2.0.0", + "replace-ext": "1.0.0", + "unist-util-stringify-position": "^1.0.0", + "vfile-message": "^1.0.0" + } + }, + "node_modules/vfile-location": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.6.tgz", + "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==", + "dev": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.2.tgz", + "integrity": "sha512-QjSNP6Yxzyycd4SVOtmKKyTsSvClqBPJcd00Z0zuPj3hOIjg0rUPG6DbFGPvUKRgYyaIWLPKpuEclcuvb3H8qA==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-message/node_modules/unist-util-stringify-position": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.2.tgz", + "integrity": "sha512-7A6eiDCs9UtjcwZOcCpM4aPII3bAAGv13E96IkawkOAW0OhH+yRxtY0lzo8KiHpzEMfH7Q+FizUmwp8Iqy5EWg==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile/node_modules/is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "engines": { + "node": ">=4" + } + }, + "node_modules/vfile/node_modules/replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vfile/node_modules/vfile-message": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz", + "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==", + "dev": true, + "dependencies": { + "unist-util-stringify-position": "^1.1.1" + } + }, + "node_modules/vinyl": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", + "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", + "dev": true, + "dependencies": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vinyl-fs": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", + "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", + "dev": true, + "dependencies": { + "fs-mkdirp-stream": "^1.0.0", + "glob-stream": "^6.1.0", + "graceful-fs": "^4.0.0", + "is-valid-glob": "^1.0.0", + "lazystream": "^1.0.0", + "lead": "^1.0.0", + "object.assign": "^4.0.4", + "pumpify": "^1.3.5", + "readable-stream": "^2.3.3", + "remove-bom-buffer": "^3.0.0", + "remove-bom-stream": "^1.2.0", + "resolve-options": "^1.1.0", + "through2": "^2.0.0", + "to-through": "^2.0.0", + "value-or-function": "^3.0.0", + "vinyl": "^2.0.0", + "vinyl-sourcemap": "^1.1.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vinyl-fs/node_modules/through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "dependencies": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "node_modules/vinyl-sourcemap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", + "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", + "dev": true, + "dependencies": { + "append-buffer": "^1.0.2", + "convert-source-map": "^1.5.0", + "graceful-fs": "^4.1.6", + "normalize-path": "^2.1.1", + "now-and-later": "^2.0.0", + "remove-bom-buffer": "^3.0.0", + "vinyl": "^2.0.0" + }, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/vinyl-sourcemap/node_modules/normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "dependencies": { + "remove-trailing-separator": "^1.0.1" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vinyl/node_modules/clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true, + "engines": { + "node": ">=0.8" + } + }, + "node_modules/void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/vue-template-compiler": { + "version": "2.6.14", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.14.tgz", + "integrity": "sha512-ODQS1SyMbjKoO1JBJZojSw6FE4qnh9rIpUZn2EUT86FKizx9uH5z6uXiIrm4/Nb/gwxTi/o17ZDEGWAXHvtC7g==", + "dev": true, + "dependencies": { + "de-indent": "^1.0.2", + "he": "^1.1.0" + } + }, + "node_modules/w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "deprecated": "Use your platform's native performance.now() and performance.timeOrigin.", + "dev": true, + "dependencies": { + "browser-process-hrtime": "^1.0.0" + } + }, + "node_modules/w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dev": true, + "dependencies": { + "xml-name-validator": "^3.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/walk-sync": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/walk-sync/-/walk-sync-2.2.0.tgz", + "integrity": "sha512-IC8sL7aB4/ZgFcGI2T1LczZeFWZ06b3zoHH7jBPyHxOtIIz1jppWHjjEXkOFvFojBVAK9pV7g47xOZ4LW3QLfg==", + "dev": true, + "dependencies": { + "@types/minimatch": "^3.0.3", + "ensure-posix-path": "^1.1.0", + "matcher-collection": "^2.0.0", + "minimatch": "^3.0.4" + }, + "engines": { + "node": "8.* || >= 10.*" + } + }, + "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, + "dependencies": { + "makeerror": "1.0.12" + } + }, + "node_modules/watchboy": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/watchboy/-/watchboy-0.4.3.tgz", + "integrity": "sha512-GHs1HxwvxSMBsqd/WfTOZhj5gBdMqf5HQpfgtKxDfZRxrlYPDdVLRB61LCeRzJaWANmvSIMlfmRVDwVmJFgAKA==", + "dev": true, + "dependencies": { + "lodash.difference": "^4.5.0", + "micromatch": "^4.0.2", + "pify": "^4.0.1", + "unixify": "^1.0.0" + }, + "engines": { + "node": ">=8.0.0" + } + }, + "node_modules/watchboy/node_modules/pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "dev": true, + "dependencies": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "dependencies": { + "minimalistic-assert": "^1.0.0" + } + }, + "node_modules/wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "dependencies": { + "defaults": "^1.0.3" + } + }, + "node_modules/webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true, + "engines": { + "node": ">=10.4" + } + }, + "node_modules/webpack": { + "version": "5.85.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.85.0.tgz", + "integrity": "sha512-7gazTiYqwo5OSqwH1tigLDL2r3qDeP2dOKYgd+LlXpsUMqDTklg6tOghexqky0/+6QY38kb/R/uRPUleuL43zg==", + "dev": true, + "dependencies": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.14.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.2", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.7", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "bin": { + "webpack": "bin/webpack.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-bundle-analyzer": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.5.0.tgz", + "integrity": "sha512-GUMZlM3SKwS8Z+CKeIFx7CVoHn3dXFcUAjT/dcZQQmfSZGvitPfMob2ipjai7ovFFqPvTqkEZ/leL4O0YOdAYQ==", + "dev": true, + "dependencies": { + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "chalk": "^4.1.0", + "commander": "^7.2.0", + "gzip-size": "^6.0.0", + "lodash": "^4.17.20", + "opener": "^1.5.2", + "sirv": "^1.0.7", + "ws": "^7.3.1" + }, + "bin": { + "webpack-bundle-analyzer": "lib/bin/analyzer.js" + }, + "engines": { + "node": ">= 10.13.0" + } + }, + "node_modules/webpack-bundle-analyzer/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/webpack-bundle-analyzer/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/webpack-cli": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.9.2.tgz", + "integrity": "sha512-m3/AACnBBzK/kMTcxWHcZFPrw/eQuY4Df1TxvIWfWM2x7mRqBQCqKEd96oCUa9jkapLBaFfRce33eGDb4Pr7YQ==", + "dev": true, + "dependencies": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^1.1.1", + "@webpack-cli/info": "^1.4.1", + "@webpack-cli/serve": "^1.6.1", + "colorette": "^2.0.14", + "commander": "^7.0.0", + "execa": "^5.0.0", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^2.2.0", + "rechoir": "^0.7.0", + "webpack-merge": "^5.7.3" + }, + "bin": { + "webpack-cli": "bin/cli.js" + }, + "engines": { + "node": ">=10.13.0" + }, + "peerDependencies": { + "webpack": "4.x.x || 5.x.x" + }, + "peerDependenciesMeta": { + "@webpack-cli/generators": { + "optional": true + }, + "@webpack-cli/migrate": { + "optional": true + }, + "webpack-bundle-analyzer": { + "optional": true + }, + "webpack-dev-server": { + "optional": true + } + } + }, + "node_modules/webpack-cli/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/webpack-cli/node_modules/interpret": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/webpack-dev-middleware": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz", + "integrity": "sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg==", + "dev": true, + "dependencies": { + "colorette": "^2.0.10", + "memfs": "^3.4.1", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + }, + "peerDependencies": { + "webpack": "^4.0.0 || ^5.0.0" + } + }, + "node_modules/webpack-dev-middleware/node_modules/ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "dev": 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" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack-dev-middleware/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack-dev-middleware/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/webpack-dev-middleware/node_modules/schema-utils": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack-dev-server": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.8.1.tgz", + "integrity": "sha512-dwld70gkgNJa33czmcj/PlKY/nOy/BimbrgZRaR9vDATBQAYgLzggR0nxDtPLJiLrMgZwbE6RRfJ5vnBBasTyg==", + "dev": true, + "dependencies": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.1", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^1.6.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "portfinder": "^1.0.28", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.0.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.21", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.4.2" + }, + "bin": { + "webpack-dev-server": "bin/webpack-dev-server.js" + }, + "engines": { + "node": ">= 12.13.0" + }, + "peerDependencies": { + "webpack": "^4.37.0 || ^5.0.0" + }, + "peerDependenciesMeta": { + "webpack-cli": { + "optional": true + } + } + }, + "node_modules/webpack-dev-server/node_modules/ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "dev": 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" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/webpack-dev-server/node_modules/ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.3" + }, + "peerDependencies": { + "ajv": "^8.8.2" + } + }, + "node_modules/webpack-dev-server/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/webpack-dev-server/node_modules/schema-utils": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", + "dev": true, + "dependencies": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" + }, + "engines": { + "node": ">= 12.13.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/webpack" + } + }, + "node_modules/webpack-dev-server/node_modules/ws": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", + "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "dev": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/webpack-merge": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", + "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", + "dev": true, + "dependencies": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + }, + "engines": { + "node": ">=10.0.0" + } + }, + "node_modules/webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/webpack/node_modules/enhanced-resolve": { + "version": "5.14.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.14.1.tgz", + "integrity": "sha512-Vklwq2vDKtl0y/vtwjSesgJ5MYS7Etuk5txS8VdKL4AOS1aUlD96zqIfsOSLQsdv3xgMRbtkWM8eG9XDfKUPow==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "dependencies": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "dependencies": { + "iconv-lite": "0.4.24" + } + }, + "node_modules/whatwg-encoding/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==", + "dev": true, + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "node_modules/whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "dev": true, + "dependencies": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "node-which": "bin/node-which" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "dependencies": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "node_modules/wildcard": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", + "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", + "dev": true + }, + "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==", + "dev": true, + "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==", + "dev": true, + "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/wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "node_modules/write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "dependencies": { + "mkdirp": "^0.5.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "dependencies": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + }, + "node_modules/ws": { + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", + "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", + "dev": true, + "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/x-is-string": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", + "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=", + "dev": true + }, + "node_modules/xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "node_modules/xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "dev": true, + "engines": { + "node": ">=8.0" + } + }, + "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 + }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true, + "engines": { + "node": ">=0.4" + } + }, + "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, + "engines": { + "node": ">=10" + } + }, + "node_modules/yaku": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/yaku/-/yaku-0.16.7.tgz", + "integrity": "sha1-HRlceKqbW/hHnIlblQT9TwhHmE4=", + "dev": true + }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "node_modules/yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==", + "engines": { + "node": ">= 6" + } + }, + "node_modules/yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "dependencies": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "engines": { + "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==", + "dev": true, + "engines": { + "node": ">=10" + } + }, + "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==", + "dev": true, + "dependencies": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "node_modules/yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "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==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/zod": { + "version": "3.21.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz", + "integrity": "sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==", + "funding": { + "url": "https://github.com/sponsors/colinhacks" + } + }, + "node_modules/zustand": { + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.3.8.tgz", + "integrity": "sha512-4h28KCkHg5ii/wcFFJ5Fp+k1J3gJoasaIbppdgZFO4BPJnsNxL0mQXBSFgOgAdCdBj35aDTPvdAJReTMntFPGg==", + "dependencies": { + "use-sync-external-store": "1.2.0" + }, + "engines": { + "node": ">=12.7.0" + }, + "peerDependencies": { + "immer": ">=9.0", + "react": ">=16.8" + }, + "peerDependenciesMeta": { + "immer": { + "optional": true + }, + "react": { + "optional": true + } + } } - } }, - "expect": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", - "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1" - } - }, - "express": { - "version": "4.18.0", - "resolved": "https://registry.npmjs.org/express/-/express-4.18.0.tgz", - "integrity": "sha512-EJEXxiTQJS3lIPrU1AE2vRuT7X7E+0KBbpm5GSoK524yl0K8X+er8zS2P14E64eqsVNoWbMCT7MpmQ+ErAhgRg==", - "dev": true, - "requires": { - "accepts": "~1.3.8", - "array-flatten": "1.1.1", - "body-parser": "1.20.0", - "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.10.3", - "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": { - "array-flatten": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", - "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", - "dev": true + "dependencies": { + "@ag-grid-community/client-side-row-model": { + "version": "28.2.1", + "resolved": "https://registry.npmjs.org/@ag-grid-community/client-side-row-model/-/client-side-row-model-28.2.1.tgz", + "integrity": "sha512-JLLNVNAtSbVjg/h0+JqNxbRGzHR9xl3YHO4kVt8Bu0UO1XQLfGLT8wkzqQTcEOiq0pEfFTee7/BGT3oHOQfUQg==", + "requires": { + "@ag-grid-community/core": "~28.2.1" + } }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } + "@ag-grid-community/core": { + "version": "28.2.1", + "resolved": "https://registry.npmjs.org/@ag-grid-community/core/-/core-28.2.1.tgz", + "integrity": "sha512-qGhqZhY8KbPlr3cJBVkNjGKu+cOyFc8IGvPcvlm0pjNC9cdxO/ct9Sa1Dg+k3ACCEroMEt1apBvnoOgurpvewQ==" }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true + "@ag-grid-community/infinite-row-model": { + "version": "28.2.1", + "resolved": "https://registry.npmjs.org/@ag-grid-community/infinite-row-model/-/infinite-row-model-28.2.1.tgz", + "integrity": "sha512-jvEvVNQ/USlQjGW0LbryR4/I1ZSgOBPn4tg45KWm3+R0jmDSfetI20D5t3UaSQHY6ZQMDVYxR3xSkorPFI3Vng==", + "requires": { + "@ag-grid-community/core": "~28.2.1" + } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "@ag-grid-community/react": { + "version": "28.2.1", + "resolved": "https://registry.npmjs.org/@ag-grid-community/react/-/react-28.2.1.tgz", + "integrity": "sha512-VWtiBMhvDKp//lIa2Ovzv+/gcQj6wnZDhngyPW5e97Sl+sIs6/UngHSTbbmhIb+wWUCIKmSRL1+R05PNnKjFTA==", + "requires": { + "prop-types": "^15.8.1" + } }, - "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==", - "dev": true + "@ag-grid-community/styles": { + "version": "28.2.1", + "resolved": "https://registry.npmjs.org/@ag-grid-community/styles/-/styles-28.2.1.tgz", + "integrity": "sha512-dy3Z46zTnzrwJOnH+tFvIvY9g/8qIi+b7XmbQlmATBr9zcNMk0wqWH1/9sNHs1fFW6m3Csvu4ctyzdr9mSw1YA==" }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true - } - } - }, - "extend": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", - "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", - "dev": true - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } + "@ampproject/remapping": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.1.2.tgz", + "integrity": "sha512-hoyByceqwKirw7w3Z7gnIIZC3Wx3J484Y3L/cMpXFbr7d9ZQj2mODrirNzcJa+SM3UlpWXYvKV4RlRpFXlWgXg==", + "requires": { + "@jridgewell/trace-mapping": "^0.3.0" + } }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } + "@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==", + "requires": { + "@babel/highlight": "^7.18.6" + } }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true - } - } - }, - "extract-zip": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", - "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", - "dev": true, - "requires": { - "@types/yauzl": "^2.9.1", - "debug": "^4.1.1", - "get-stream": "^5.1.0", - "yauzl": "^2.10.0" - } - }, - "extsprintf": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", - "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==", - "dev": true, - "optional": true - }, - "fast-average-color": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/fast-average-color/-/fast-average-color-9.3.0.tgz", - "integrity": "sha512-FlPROSqDMOnoBgkFhWMHJODPvpS0Od0WDpedcKq4U/t0JVapGAkblNwxOr75qT+ZNd0dQM4qlgqrtnXbCJ8cNg==" - }, - "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-fifo": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.1.0.tgz", - "integrity": "sha512-Kl29QoNbNvn4nhDsLYjyIAaIqaJB6rBx5p3sL9VjaefJ+eMFBWVZiaoguaoZfzEKr5RhAti0UgM8703akGPJ6g==", - "dev": true - }, - "fast-glob": { - "version": "3.2.11", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", - "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", - "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==", - "dev": true - }, - "fast-levenshtein": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", - "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", - "dev": true - }, - "fastest-levenshtein": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", - "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", - "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==", - "dev": true, - "requires": { - "reusify": "^1.0.4" - } - }, - "faye-websocket": { - "version": "0.11.4", - "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", - "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", - "dev": true, - "requires": { - "websocket-driver": ">=0.5.1" - } - }, - "fb-watchman": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", - "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", - "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==", - "dev": true, - "requires": { - "pend": "~1.2.0" - } - }, - "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==", - "dev": true, - "requires": { - "flat-cache": "^3.0.4" - } - }, - "file-loader": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", - "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", - "dev": true, - "requires": { - "loader-utils": "^2.0.0", - "schema-utils": "^3.0.0" - } - }, - "filelist": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", - "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", - "dev": true, - "requires": { - "minimatch": "^5.0.1" - }, - "dependencies": { - "brace-expansion": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", - "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", - "dev": true, - "requires": { - "balanced-match": "^1.0.0" - } + "@babel/compat-data": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.20.5.tgz", + "integrity": "sha512-KZXo2t10+/jxmkhNXc7pZTqRvSOIvVv/+lJwHS+B2rErwOyjuVRh60yVpb7liQ1U5t7lLJ1bz+t8tSypUZdm0g==" }, - "minimatch": { - "version": "5.1.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", - "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", - "dev": true, - "requires": { - "brace-expansion": "^2.0.1" - } - } - } - }, - "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==", - "dev": true, - "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==", - "dev": true, - "requires": { - "ms": "2.0.0" - } + "@babel/core": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.20.5.tgz", + "integrity": "sha512-UdOWmk4pNWTm/4DlPUl/Pt4Gz4rcEMb7CY0Y3eJl5Yz1vI8ZJGmHWaVE55LoxRjdpx0z259GE9U5STA9atUinQ==", + "requires": { + "@ampproject/remapping": "^2.1.0", + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.5", + "@babel/helper-compilation-targets": "^7.20.0", + "@babel/helper-module-transforms": "^7.20.2", + "@babel/helpers": "^7.20.5", + "@babel/parser": "^7.20.5", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.2", + "json5": "^2.2.1", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true + "@babel/generator": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.20.5.tgz", + "integrity": "sha512-jl7JY2Ykn9S0yj4DQP82sYvPU+T3g0HFcWTqDLqiuA9tGRNIj9VfbtXGAYTTkyNEnQk1jkMGOdYka8aG/lulCA==", + "requires": { + "@babel/types": "^7.20.5", + "@jridgewell/gen-mapping": "^0.3.2", + "jsesc": "^2.5.1" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.18.6.tgz", + "integrity": "sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.20.0", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.0.tgz", + "integrity": "sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==", + "requires": { + "@babel/compat-data": "^7.20.0", + "@babel/helper-validator-option": "^7.18.6", + "browserslist": "^4.21.3", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==" + } + } + }, + "@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==" + }, + "@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==", + "requires": { + "@babel/template": "^7.18.10", + "@babel/types": "^7.19.0" + } + }, + "@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==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@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==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-module-transforms": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.20.2.tgz", + "integrity": "sha512-zvBKyJXRbmK07XhMuujYoJ48B5yvvmM6+wcpv6Ivj4Yg6qO7NOZOSnvZN9CRl1zz1Z4cKf8YejmCMh8clOoOeA==", + "requires": { + "@babel/helper-environment-visitor": "^7.18.9", + "@babel/helper-module-imports": "^7.18.6", + "@babel/helper-simple-access": "^7.20.2", + "@babel/helper-split-export-declaration": "^7.18.6", + "@babel/helper-validator-identifier": "^7.19.1", + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.1", + "@babel/types": "^7.20.2" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz", + "integrity": "sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==" + }, + "@babel/helper-simple-access": { + "version": "7.20.2", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz", + "integrity": "sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==", + "requires": { + "@babel/types": "^7.20.2" + } + }, + "@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==", + "requires": { + "@babel/types": "^7.18.6" + } + }, + "@babel/helper-string-parser": { + "version": "7.19.4", + "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz", + "integrity": "sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==" + }, + "@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==" + }, + "@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==" + }, + "@babel/helpers": { + "version": "7.20.6", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.20.6.tgz", + "integrity": "sha512-Pf/OjgfgFRW5bApskEz5pvidpim7tEDPlFtKcNRXWmfHGn9IEI2W2flqRQXTFb7gIPTyK++N6rVHuwKut4XK6w==", + "requires": { + "@babel/template": "^7.18.10", + "@babel/traverse": "^7.20.5", + "@babel/types": "^7.20.5" + } + }, + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + }, + "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==", + "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==", + "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==", + "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==" + }, + "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==" + }, + "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==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "@babel/parser": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.20.5.tgz", + "integrity": "sha512-r27t/cy/m9uKLXQNWWebeCUHgnAZq0CpG1OwKRxzJMP1vpSU4bSIK2hq+/cp0bQxetkXx38n09rNu8jVkcK/zA==" + }, + "@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==", + "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.16.7", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-typescript/-/plugin-syntax-typescript-7.16.7.tgz", + "integrity": "sha512-YhUIJHHGkqPgEcMYkPCKTyGUdoGKWtopIycQyjJH8OjvRgOYsXsaKehLVPScKJWAULPxMa4N1vCe6szREFlZ7A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.16.7" + } + }, + "@babel/runtime": { + "version": "7.18.9", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.18.9.tgz", + "integrity": "sha512-lkqXDcvlFT5rvEjiu6+QYO+1GXrEHRo2LOtS7E4GtX5ESIZOgepqsZBVIj6Pv+a6zqsya9VCgiK1KAK4BvJDAw==", + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/runtime-corejs3": { + "version": "7.17.9", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.17.9.tgz", + "integrity": "sha512-WxYHHUWF2uZ7Hp1K+D1xQgbgkGUfA+5UPOegEXGt2Y5SMog/rYCVaifLZDbw8UkNXozEqqrZTy6bglL7xTaCOw==", + "dev": true, + "requires": { + "core-js-pure": "^3.20.2", + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.18.10", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.18.10.tgz", + "integrity": "sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==", + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/parser": "^7.18.10", + "@babel/types": "^7.18.10" + } + }, + "@babel/traverse": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.20.5.tgz", + "integrity": "sha512-WM5ZNN3JITQIq9tFZaw1ojLU3WgWdtkxnhM1AegMS+PvHjkM5IXjmYEGY7yukz5XS4sJyEf2VzWjI8uAavhxBQ==", + "requires": { + "@babel/code-frame": "^7.18.6", + "@babel/generator": "^7.20.5", + "@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.20.5", + "@babel/types": "^7.20.5", + "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==" + } + } + }, + "@babel/types": { + "version": "7.20.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.20.5.tgz", + "integrity": "sha512-c9fst/h2/dcF7H+MJKZ2T0KjEQ8hY/BNnDk/H3XY8C4Aw/eWQXWn/lWntHF9ooUBnGmEvbfGrTgLWc+um0YDUg==", + "requires": { + "@babel/helper-string-parser": "^7.19.4", + "@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 + }, + "@cspotcode/source-map-consumer": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", + "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", + "dev": true + }, + "@cspotcode/source-map-support": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", + "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", + "dev": true, + "requires": { + "@cspotcode/source-map-consumer": "0.8.0" + } + }, + "@csstools/selector-specificity": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@csstools/selector-specificity/-/selector-specificity-2.0.1.tgz", + "integrity": "sha512-aG20vknL4/YjQF9BSV7ts4EWm/yrjagAN7OWBNmlbEOUiu0llj4OGrFoOKK3g2vey4/p2omKCoHrWtPxSwV3HA==", + "dev": true, + "requires": {} + }, + "@develar/schema-utils": { + "version": "2.6.5", + "resolved": "https://registry.npmjs.org/@develar/schema-utils/-/schema-utils-2.6.5.tgz", + "integrity": "sha512-0cp4PsWQ/9avqTVMCtZ+GirikIA36ikvjtHweU4/j8yLtgObI0+JUPhYFScgwlteveGB1rt3Cm8UhN04XayDig==", + "dev": true, + "requires": { + "ajv": "^6.12.0", + "ajv-keywords": "^3.4.1" + } + }, + "@discoveryjs/json-ext": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@discoveryjs/json-ext/-/json-ext-0.5.7.tgz", + "integrity": "sha512-dBVuXR082gk3jsFp7Rd/JI4kytwGHecnCoTtXFb7DB6CNHp4rg5k1bhg0nWdLGLnOV71lmDzGQaLMy8iPLY0pw==", + "dev": true + }, + "@electron/asar": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/@electron/asar/-/asar-3.2.3.tgz", + "integrity": "sha512-wmOfE6szYyqZhRIiLH+eyZEp+bGcJI0OD/SCvSUrfBE0jvauyGYO2ZhpWxmNCcDojKu5DYrsVqT5BOCZZ01XIg==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "chromium-pickle-js": "^0.2.0", + "commander": "^5.0.0", + "glob": "^7.1.6", + "minimatch": "^3.0.4" + } + }, + "@electron/get": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/@electron/get/-/get-2.0.2.tgz", + "integrity": "sha512-eFZVFoRXb3GFGd7Ak7W4+6jBl9wBtiZ4AaYOse97ej6mKj5tkyO0dUnUChs1IhJZtx1BENo4/p4WUTXpi6vT+g==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "env-paths": "^2.2.0", + "fs-extra": "^8.1.0", + "global-agent": "^3.0.0", + "got": "^11.8.5", + "progress": "^2.0.3", + "semver": "^6.2.0", + "sumchecker": "^3.0.1" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "@electron/notarize": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@electron/notarize/-/notarize-1.2.3.tgz", + "integrity": "sha512-9oRzT56rKh5bspk3KpAVF8lPKHYQrBnRwcgiOeR0hdilVEQmszDaAu0IPCPrwwzJN0ugNs0rRboTreHMt/6mBQ==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "fs-extra": "^9.0.1" + }, + "dependencies": { + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, + "@electron/osx-sign": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@electron/osx-sign/-/osx-sign-1.0.4.tgz", + "integrity": "sha512-xfhdEcIOfAZg7scZ9RQPya1G1lWo8/zMCwUXAulq0SfY7ONIW+b9qGyKdMyuMctNYwllrIS+vmxfijSfjeh97g==", + "dev": true, + "requires": { + "compare-version": "^0.1.2", + "debug": "^4.3.4", + "fs-extra": "^10.0.0", + "isbinaryfile": "^4.0.8", + "minimist": "^1.2.6", + "plist": "^3.0.5" + }, + "dependencies": { + "fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "isbinaryfile": { + "version": "4.0.10", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-4.0.10.tgz", + "integrity": "sha512-iHrqe5shvBUcFbmZq9zOQHBoeOhZJu6RQGrDpBgenUm/Am+F3JM2MgQj+rK3Z601fzrL5gLZWtAPH2OBaSVcyw==", + "dev": true + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, + "@electron/rebuild": { + "version": "3.2.10", + "resolved": "https://registry.npmjs.org/@electron/rebuild/-/rebuild-3.2.10.tgz", + "integrity": "sha512-SUBM6Mwi3yZaDFQjZzfGKpYTtOp9m60glounwX6tfGeVc/ZOl4jbquktUcyy7gYSLDWFLtKkftkY2xgMJZLQgg==", + "dev": true, + "requires": { + "@malept/cross-spawn-promise": "^2.0.0", + "chalk": "^4.0.0", + "debug": "^4.1.1", + "detect-libc": "^2.0.1", + "fs-extra": "^10.0.0", + "got": "^11.7.0", + "lzma-native": "^8.0.5", + "node-abi": "^3.0.0", + "node-api-version": "^0.1.4", + "node-gyp": "^9.0.0", + "ora": "^5.1.0", + "semver": "^7.3.5", + "tar": "^6.0.5", + "yargs": "^17.0.1" + }, + "dependencies": { + "@malept/cross-spawn-promise": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-2.0.0.tgz", + "integrity": "sha512-1DpKU0Z5ThltBwjNySMC14g0CkbyhCaz9FkhxqNsZI6uAPJXFS8cMXlBKo26FJ8ZuW6S9GCMcR9IO5k2X5/9Fg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.1" + } + }, + "@npmcli/fs": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/@npmcli/fs/-/fs-2.1.2.tgz", + "integrity": "sha512-yOJKRvohFOaLqipNtwYB9WugyZKhC/DZC4VYPmpaCzDBrA8YpK3qHZ8/HGscMnE4GqbkLNuVcCnxkeQEdGt6LQ==", + "dev": true, + "requires": { + "@gar/promisify": "^1.1.3", + "semver": "^7.3.5" + } + }, + "@npmcli/move-file": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/@npmcli/move-file/-/move-file-2.0.1.tgz", + "integrity": "sha512-mJd2Z5TjYWq/ttPLLGqArdtnC74J6bOzg4rMDnN+p1xTacZ2yPRCk2y0oSWQtygLR9YVQXgOcONrwtnk3JupxQ==", + "dev": true, + "requires": { + "mkdirp": "^1.0.4", + "rimraf": "^3.0.2" + } + }, + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "cacache": { + "version": "16.1.3", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-16.1.3.tgz", + "integrity": "sha512-/+Emcj9DAXxX4cwlLmRI9c166RuL3w30zp4R7Joiv2cQTtTtA+jeuCAjH3ZlGnYS3tKENSrKhAzVVP9GVyzeYQ==", + "dev": true, + "requires": { + "@npmcli/fs": "^2.1.0", + "@npmcli/move-file": "^2.0.0", + "chownr": "^2.0.0", + "fs-minipass": "^2.1.0", + "glob": "^8.0.1", + "infer-owner": "^1.0.4", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "mkdirp": "^1.0.4", + "p-map": "^4.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^3.0.2", + "ssri": "^9.0.0", + "tar": "^6.1.11", + "unique-filename": "^2.0.0" + }, + "dependencies": { + "glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + } + } + } + }, + "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" + } + }, + "detect-libc": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz", + "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==", + "dev": true + }, + "fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "lru-cache": { + "version": "7.18.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.1.tgz", + "integrity": "sha512-8/HcIENyQnfUTCDizRu9rrDyG6XG/21M4X7/YEGZeD76ZJilFPAUVb/2zysFf7VVO1LEjCDFyHp8pMMvozIrvg==", + "dev": true + }, + "make-fetch-happen": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/make-fetch-happen/-/make-fetch-happen-10.2.1.tgz", + "integrity": "sha512-NgOPbRiaQM10DYXvN3/hhGVI2M5MtITFryzBGxHM5p4wnFxsVCbxkrBrDsk+EZ5OB4jEOT7AjDxtdF+KVEFT7w==", + "dev": true, + "requires": { + "agentkeepalive": "^4.2.1", + "cacache": "^16.1.0", + "http-cache-semantics": "^4.1.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.0", + "is-lambda": "^1.0.1", + "lru-cache": "^7.7.1", + "minipass": "^3.1.6", + "minipass-collect": "^1.0.2", + "minipass-fetch": "^2.0.3", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.4", + "negotiator": "^0.6.3", + "promise-retry": "^2.0.1", + "socks-proxy-agent": "^7.0.0", + "ssri": "^9.0.0" + } + }, + "minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "minipass-fetch": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minipass-fetch/-/minipass-fetch-2.1.2.tgz", + "integrity": "sha512-LT49Zi2/WMROHYoqGgdlQIZh8mLPZmOrN2NdJjMXxYe4nkN6FUyuPuOAOedNJDrx0IRGg9+4guZewtp8hE6TxA==", + "dev": true, + "requires": { + "encoding": "^0.1.13", + "minipass": "^3.1.6", + "minipass-sized": "^1.0.3", + "minizlib": "^2.1.2" + } + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + }, + "node-gyp": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/node-gyp/-/node-gyp-9.3.1.tgz", + "integrity": "sha512-4Q16ZCqq3g8awk6UplT7AuxQ35XN4R/yf/+wSAwcBUAjg7l58RTactWaP8fIDTi0FzI7YcVLujwExakZlfWkXg==", + "dev": true, + "requires": { + "env-paths": "^2.2.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.6", + "make-fetch-happen": "^10.0.3", + "nopt": "^6.0.0", + "npmlog": "^6.0.0", + "rimraf": "^3.0.2", + "semver": "^7.3.5", + "tar": "^6.1.2", + "which": "^2.0.2" + } + }, + "nopt": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-6.0.0.tgz", + "integrity": "sha512-ZwLpbTgdhuZUnZzjd7nb1ZV+4DoiC6/sfiVKok72ym/4Tlf+DFdlHYmT2JPmcNNWV6Pi3SDf1kT+A4r9RTuT9g==", + "dev": true, + "requires": { + "abbrev": "^1.0.0" + } + }, + "socks-proxy-agent": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-7.0.0.tgz", + "integrity": "sha512-Fgl0YPZ902wEsAyiQ+idGd1A7rSFx/ayC1CQVMw5P+EQx2V0SgpGtf6OKFhVjPflPUl9YMmEOnmfjCdMUsygww==", + "dev": true, + "requires": { + "agent-base": "^6.0.2", + "debug": "^4.3.3", + "socks": "^2.6.2" + } + }, + "ssri": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-9.0.1.tgz", + "integrity": "sha512-o57Wcn66jMQvfHG1FlYbWeZWW/dHZhJXjpIcTfXldXEk5nz5lStPo3mK0OJQfGR3RbZUlbISexbljkJzuEj/8Q==", + "dev": true, + "requires": { + "minipass": "^3.1.1" + } + }, + "unique-filename": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-2.0.1.tgz", + "integrity": "sha512-ODWHtkkdx3IAR+veKxFV+VBkUMcN+FaqzUUd7IZzt+0zhDZFPFxhlqwPF3YQvMHx1TD0tdgYl+kuPnJ8E6ql7A==", + "dev": true, + "requires": { + "unique-slug": "^3.0.0" + } + }, + "unique-slug": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-3.0.0.tgz", + "integrity": "sha512-8EyMynh679x/0gqE9fT9oilG+qEt+ibFyqjuVTsZn1+CMxH+XLlpvr2UZx4nVcCwTpx81nICr2JQFkM+HPLq4w==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + }, + "yargs": { + "version": "17.7.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.1.tgz", + "integrity": "sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==", + "dev": true, + "requires": { + "cliui": "^8.0.1", + "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.1.1" + } + }, + "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 + } + } + }, + "@electron/universal": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/@electron/universal/-/universal-1.3.4.tgz", + "integrity": "sha512-BdhBgm2ZBnYyYRLRgOjM5VHkyFItsbggJ0MHycOjKWdFGYwK97ZFXH54dTvUWEfha81vfvwr5On6XBjt99uDcg==", + "dev": true, + "requires": { + "@electron/asar": "^3.2.1", + "@malept/cross-spawn-promise": "^1.1.0", + "debug": "^4.3.1", + "dir-compare": "^3.0.0", + "fs-extra": "^9.0.1", + "minimatch": "^3.0.4", + "plist": "^3.0.4" + }, + "dependencies": { + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, + "@emotion/babel-plugin": { + "version": "11.10.2", + "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.10.2.tgz", + "integrity": "sha512-xNQ57njWTFVfPAc3cjfuaPdsgLp5QOSuRsj9MA6ndEhH/AzuZM86qIQzt6rq+aGBwj3n5/TkLmU5lhAfdRmogA==", + "requires": { + "@babel/helper-module-imports": "^7.16.7", + "@babel/plugin-syntax-jsx": "^7.17.12", + "@babel/runtime": "^7.18.3", + "@emotion/hash": "^0.9.0", + "@emotion/memoize": "^0.8.0", + "@emotion/serialize": "^1.1.0", + "babel-plugin-macros": "^3.1.0", + "convert-source-map": "^1.5.0", + "escape-string-regexp": "^4.0.0", + "find-root": "^1.1.0", + "source-map": "^0.5.7", + "stylis": "4.0.13" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==" + } + } + }, + "@emotion/cache": { + "version": "11.10.3", + "resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.10.3.tgz", + "integrity": "sha512-Psmp/7ovAa8appWh3g51goxu/z3iVms7JXOreq136D8Bbn6dYraPnmL6mdM8GThEx9vwSn92Fz+mGSjBzN8UPQ==", + "requires": { + "@emotion/memoize": "^0.8.0", + "@emotion/sheet": "^1.2.0", + "@emotion/utils": "^1.2.0", + "@emotion/weak-memoize": "^0.3.0", + "stylis": "4.0.13" + } + }, + "@emotion/hash": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.0.tgz", + "integrity": "sha512-14FtKiHhy2QoPIzdTcvh//8OyBlknNs2nXRwIhG904opCby3l+9Xaf/wuPvICBF0rc1ZCNBd3nKe9cd2mecVkQ==" }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true - } - } - }, - "find-root": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", - "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" - }, - "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==", - "dev": true, - "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==", - "dev": true, - "requires": { - "flatted": "^3.1.0", - "rimraf": "^3.0.2" - } - }, - "flatted": { - "version": "3.2.5", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", - "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", - "dev": true - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, - "follow-redirects": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", - "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", - "dev": true - }, - "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" - } - }, - "format-duration": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/format-duration/-/format-duration-2.0.0.tgz", - "integrity": "sha512-ARqJ9qXm71pw3SGAY7bibf8lRLvltOXLjWjzzR3UrUjHu1zdeYpA/Z+u+ltdhrfRa440OjEsHNzdmuZViqqQWQ==" - }, - "forwarded": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", - "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "framer-motion": { - "version": "9.1.7", - "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-9.1.7.tgz", - "integrity": "sha512-nKxBkIO4IPkMEqcBbbATxsVjwPYShKl051yhBv9628iAH6JLeHD0siBHxkL62oQzMC1+GNX73XtPjgP753ufuw==", - "requires": { - "@emotion/is-prop-valid": "^0.8.2", - "tslib": "^2.4.0" - }, - "dependencies": { "@emotion/is-prop-valid": { - "version": "0.8.8", - "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", - "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", - "optional": true, - "requires": { - "@emotion/memoize": "0.7.4" - } + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz", + "integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==", + "requires": { + "@emotion/memoize": "^0.8.0" + } }, "@emotion/memoize": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", - "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", - "optional": true - } - } - }, - "fresh": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", - "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", - "dev": true - }, - "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==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^4.0.0", - "universalify": "^0.1.0" - } - }, - "fs-merger": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/fs-merger/-/fs-merger-3.2.1.tgz", - "integrity": "sha512-AN6sX12liy0JE7C2evclwoo0aCG3PFulLjrTLsJpWh/2mM+DinhpSGqYLbHBBbIW1PLRNcFhJG8Axtz8mQW3ug==", - "dev": true, - "requires": { - "broccoli-node-api": "^1.7.0", - "broccoli-node-info": "^2.1.0", - "fs-extra": "^8.0.1", - "fs-tree-diff": "^2.0.1", - "walk-sync": "^2.2.0" - } - }, - "fs-minipass": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", - "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "fs-mkdirp-stream": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", - "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "through2": "^2.0.3" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "fs-monkey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", - "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", - "dev": true - }, - "fs-tree-diff": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fs-tree-diff/-/fs-tree-diff-2.0.1.tgz", - "integrity": "sha512-x+CfAZ/lJHQqwlD64pYM5QxWjzWhSjroaVsr8PW831zOApL55qPibed0c+xebaLWVr2BnHFoHdrwOv8pzt8R5A==", - "dev": true, - "requires": { - "@types/symlink-or-copy": "^1.2.0", - "heimdalljs-logger": "^0.1.7", - "object-assign": "^4.1.0", - "path-posix": "^1.0.0", - "symlink-or-copy": "^1.1.8" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" - }, - "function.prototype.name": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", - "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "es-abstract": "^1.19.0", - "functions-have-names": "^1.2.2" - } - }, - "functional-red-black-tree": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", - "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", - "dev": true - }, - "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==", - "dev": true - }, - "fuse.js": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-6.6.2.tgz", - "integrity": "sha512-cJaJkxCCxC8qIIcPBF9yGxY0W/tVZS3uEISDxhYIdtk8OL93pe+6Zj7LjCqVV4dzbqcriOZ+kQ/NE4RXZHsIGA==" - }, - "gauge": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", - "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", - "dev": true, - "requires": { - "aproba": "^1.0.3 || ^2.0.0", - "color-support": "^1.1.3", - "console-control-strings": "^1.1.0", - "has-unicode": "^2.0.1", - "signal-exit": "^3.0.7", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1", - "wide-align": "^1.1.5" - } - }, - "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==" - }, - "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==", - "dev": true, - "requires": { - "function-bind": "^1.1.1", - "has": "^1.0.3", - "has-symbols": "^1.0.3" - } - }, - "get-nonce": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", - "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==" - }, - "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-stdin": { - "version": "8.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", - "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", - "dev": true - }, - "get-stream": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", - "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "get-symbol-description": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", - "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.1" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", - "dev": true - }, - "glob": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", - "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "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==", - "dev": true, - "requires": { - "is-glob": "^4.0.3" - } - }, - "glob-stream": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", - "integrity": "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==", - "dev": true, - "requires": { - "extend": "^3.0.0", - "glob": "^7.1.1", - "glob-parent": "^3.1.0", - "is-negated-glob": "^1.0.0", - "ordered-read-streams": "^1.0.0", - "pumpify": "^1.3.5", - "readable-stream": "^2.1.5", - "remove-trailing-separator": "^1.0.1", - "to-absolute-glob": "^2.0.0", - "unique-stream": "^2.0.2" - }, - "dependencies": { - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - } + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.8.0.tgz", + "integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==" }, - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "glob-to-regexp": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", - "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", - "dev": true - }, - "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==", - "dev": true, - "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" - } - }, - "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" - } - } - } - }, - "globals": { - "version": "13.19.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", - "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", - "dev": true, - "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==", - "dev": true, - "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 - }, - "gonzales-pe": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", - "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==", - "dev": true, - "requires": { - "minimist": "^1.2.5" - } - }, - "gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.3" - } - }, - "got": { - "version": "11.8.6", - "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", - "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", - "dev": true, - "requires": { - "@sindresorhus/is": "^4.0.0", - "@szmarczak/http-timer": "^4.0.5", - "@types/cacheable-request": "^6.0.1", - "@types/responselike": "^1.0.0", - "cacheable-lookup": "^5.0.3", - "cacheable-request": "^7.0.2", - "decompress-response": "^6.0.0", - "http2-wrapper": "^1.0.0-beta.5.2", - "lowercase-keys": "^2.0.0", - "p-cancelable": "^2.0.0", - "responselike": "^2.0.0" - } - }, - "graceful-fs": { - "version": "4.2.10", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", - "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" - }, - "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==", - "dev": true - }, - "gulp-sort": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/gulp-sort/-/gulp-sort-2.0.0.tgz", - "integrity": "sha1-xnYqLx8N4KP8WVohWZ0/rI26Gso=", - "dev": true, - "requires": { - "through2": "^2.0.1" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "gzip-size": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", - "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", - "dev": true, - "requires": { - "duplexer": "^0.1.2" - } - }, - "handle-thing": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", - "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", - "dev": true - }, - "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 - }, - "harmony-reflect": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", - "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==", - "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-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==", - "dev": true - }, - "has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true - }, - "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==", - "dev": 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==", - "dev": true - }, - "has-tostringtag": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", - "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "has-unicode": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", - "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } + "@emotion/react": { + "version": "11.10.4", + "resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.10.4.tgz", + "integrity": "sha512-j0AkMpr6BL8gldJZ6XQsQ8DnS9TxEQu1R+OGmDZiWjBAJtCcbt0tS3I/YffoqHXxH6MjgI7KdMbYKw3MEiU9eA==", + "requires": { + "@babel/runtime": "^7.18.3", + "@emotion/babel-plugin": "^11.10.0", + "@emotion/cache": "^11.10.0", + "@emotion/serialize": "^1.1.0", + "@emotion/use-insertion-effect-with-fallbacks": "^1.0.0", + "@emotion/utils": "^1.2.0", + "@emotion/weak-memoize": "^0.3.0", + "hoist-non-react-statics": "^3.3.1" } - } }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "heimdalljs": { - "version": "0.2.6", - "resolved": "https://registry.npmjs.org/heimdalljs/-/heimdalljs-0.2.6.tgz", - "integrity": "sha512-o9bd30+5vLBvBtzCPwwGqpry2+n0Hi6H1+qwt6y+0kwRHGGF8TFIhJPmnuM0xO97zaKrDZMwO/V56fAnn8m/tA==", - "dev": true, - "requires": { - "rsvp": "~3.2.1" - }, - "dependencies": { - "rsvp": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.2.1.tgz", - "integrity": "sha1-B8tKXfJa3Z6Cbrxn3Mn9idsn2Eo=", - "dev": true - } - } - }, - "heimdalljs-logger": { - "version": "0.1.10", - "resolved": "https://registry.npmjs.org/heimdalljs-logger/-/heimdalljs-logger-0.1.10.tgz", - "integrity": "sha512-pO++cJbhIufVI/fmB/u2Yty3KJD0TqNPecehFae0/eps0hkZ3b4Zc/PezUMOpYuHFQbA7FxHZxa305EhmjLj4g==", - "dev": true, - "requires": { - "debug": "^2.2.0", - "heimdalljs": "^0.2.6" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } + "@emotion/serialize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.1.0.tgz", + "integrity": "sha512-F1ZZZW51T/fx+wKbVlwsfchr5q97iW8brAnXmsskz4d0hVB4O3M/SiA3SaeH06x02lSNzkkQv+n3AX3kCXKSFA==", + "requires": { + "@emotion/hash": "^0.9.0", + "@emotion/memoize": "^0.8.0", + "@emotion/unitless": "^0.8.0", + "@emotion/utils": "^1.2.0", + "csstype": "^3.0.2" + }, + "dependencies": { + "@emotion/unitless": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.8.0.tgz", + "integrity": "sha512-VINS5vEYAscRl2ZUDiT3uMPlrFQupiKgHz5AA4bCH1miKBg4qtwkim1qPmJj/4WG6TreYMY111rEFsjupcOKHw==" + } + } }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "history": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz", - "integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==", - "requires": { - "@babel/runtime": "^7.7.6" - } - }, - "hoist-non-react-statics": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", - "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", - "requires": { - "react-is": "^16.7.0" - }, - "dependencies": { - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - } - } - }, - "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" - } - }, - "hpack.js": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", - "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "obuf": "^1.0.0", - "readable-stream": "^2.0.1", - "wbuf": "^1.1.0" - } - }, - "html-encoding-sniffer": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", - "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", - "dev": true, - "requires": { - "whatwg-encoding": "^1.0.5" - } - }, - "html-entities": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", - "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==", - "dev": true - }, - "html-escaper": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", - "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" - }, - "html-minifier-terser": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", - "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", - "dev": true, - "requires": { - "camel-case": "^4.1.2", - "clean-css": "^5.2.2", - "commander": "^8.3.0", - "he": "^1.2.0", - "param-case": "^3.0.4", - "relateurl": "^0.2.7", - "terser": "^5.10.0" - }, - "dependencies": { - "commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true - } - } - }, - "html-parse-stringify": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", - "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", - "requires": { - "void-elements": "3.1.0" - } - }, - "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 - }, - "html-webpack-plugin": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz", - "integrity": "sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==", - "dev": true, - "requires": { - "@types/html-minifier-terser": "^6.0.0", - "html-minifier-terser": "^6.0.2", - "lodash": "^4.17.21", - "pretty-error": "^4.0.0", - "tapable": "^2.0.0" - } - }, - "htmlparser2": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", - "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", - "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "domhandler": "^4.0.0", - "domutils": "^2.5.2", - "entities": "^2.0.0" - } - }, - "http-cache-semantics": { - "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==", - "dev": true - }, - "http-deceiver": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", - "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", - "dev": 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==", - "dev": true, - "requires": { - "depd": "2.0.0", - "inherits": "2.0.4", - "setprototypeof": "1.2.0", - "statuses": "2.0.1", - "toidentifier": "1.0.1" - }, - "dependencies": { - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true + "@emotion/sheet": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.2.0.tgz", + "integrity": "sha512-OiTkRgpxescko+M51tZsMq7Puu/KP55wMT8BgpcXVG2hqXc0Vo0mfymJ/Uj24Hp0i083ji/o0aLddh08UEjq8w==" }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true - } - } - }, - "http-parser-js": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.6.tgz", - "integrity": "sha512-vDlkRPDJn93swjcjqMSaGSPABbIarsr1TLAui/gLDXzV5VsJNdXNzMYDyNBLQkjWQCJ1uizu8T2oDMhmGt0PRA==", - "dev": true - }, - "http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dev": true, - "requires": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - } - }, - "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" - } - }, - "http-proxy-middleware": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.4.tgz", - "integrity": "sha512-m/4FxX17SUvz4lJ5WPXOHDUuCwIqXLfLHs1s0uZ3oYjhoXlx9csYxaOa0ElDEJ+h8Q4iJ1s+lTMbiCa4EXIJqg==", - "dev": true, - "requires": { - "@types/http-proxy": "^1.17.8", - "http-proxy": "^1.18.1", - "is-glob": "^4.0.1", - "is-plain-obj": "^3.0.0", - "micromatch": "^4.0.2" - } - }, - "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==", - "dev": true, - "requires": { - "quick-lru": "^5.1.1", - "resolve-alpn": "^1.0.0" - } - }, - "https-proxy-agent": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", - "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 - }, - "humanize-ms": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", - "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", - "dev": true, - "requires": { - "ms": "^2.0.0" - } - }, - "husky": { - "version": "7.0.4", - "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.4.tgz", - "integrity": "sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==", - "dev": true - }, - "i18next": { - "version": "21.6.16", - "resolved": "https://registry.npmjs.org/i18next/-/i18next-21.6.16.tgz", - "integrity": "sha512-xJlzrVxG9CyAGsbMP1aKuiNr1Ed2m36KiTB7hjGMG2Zo4idfw3p9THUEu+GjBwIgEZ7F11ZbCzJcfv4uyfKNuw==", - "requires": { - "@babel/runtime": "^7.17.2" - } - }, - "i18next-parser": { - "version": "6.6.0", - "resolved": "https://registry.npmjs.org/i18next-parser/-/i18next-parser-6.6.0.tgz", - "integrity": "sha512-yA3W6PL+7epCyUFTpUDdztKArfpeGMWRUOnB/4FZRodfXkjCIBcBg728h6b/lrBTbva4OlFjVgv1kCXbvZVRWQ==", - "dev": true, - "requires": { - "@babel/runtime": "^7.15.4", - "broccoli-plugin": "^4.0.7", - "cheerio": "^1.0.0-rc.2", - "colors": "1.4.0", - "commander": "~9.4.1", - "concat-stream": "~2.0.0", - "eol": "^0.9.1", - "fs-extra": "^10.0.0", - "gulp-sort": "^2.0.0", - "i18next": "^21.2.0", - "js-yaml": "4.1.0", - "rsvp": "^4.8.2", - "sort-keys": "^5.0.0", - "through2": "~4.0.2", - "typescript": "^4.2.4", - "vinyl": "~3.0.0", - "vinyl-fs": "^3.0.2", - "vue-template-compiler": "^2.6.11" - }, - "dependencies": { - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", - "dev": true + "@emotion/stylis": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/@emotion/stylis/-/stylis-0.8.5.tgz", + "integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==" }, - "colors": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", - "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", - "dev": true + "@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" }, - "commander": { - "version": "9.4.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", - "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", - "dev": true + "@emotion/use-insertion-effect-with-fallbacks": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.0.0.tgz", + "integrity": "sha512-1eEgUGmkaljiBnRMTdksDV1W4kUnmwgp7X9G8B++9GYwl1lUdqSndSriIrTJ0N7LQaoauY9JJ2yhiOYK5+NI4A==", + "requires": {} }, - "concat-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", - "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.0.2", - "typedarray": "^0.0.6" - } + "@emotion/utils": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.2.0.tgz", + "integrity": "sha512-sn3WH53Kzpw8oQ5mgMmIzzyAaH2ZqFEbozVVBSYp538E06OSE6ytOp7pRAjNQR+Q/orwqdQYJSe2m3hCOeznkw==" }, - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } + "@emotion/weak-memoize": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.3.0.tgz", + "integrity": "sha512-AHPmaAx+RYfZz0eYu6Gviiagpmiyw98ySSlQvCUhVGDRtDFe4DBS0x1bSjdF3gqUDYOczB+yYvBTtEylYSdRhg==" }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } + "@eslint/eslintrc": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-1.4.0.tgz", + "integrity": "sha512-7yfvXy6MWLgWSFsLhz5yH3iQ52St8cdUY6FoGieKkRDVxuxmrNuUetIuu6cmjNWwniUHiWXjxCr5tTXDrbYS5A==", + "dev": true, + "requires": { + "ajv": "^6.12.4", + "debug": "^4.3.2", + "espree": "^9.4.0", + "globals": "^13.19.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" + } }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } + "@floating-ui/core": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.2.1.tgz", + "integrity": "sha512-LSqwPZkK3rYfD7GKoIeExXOyYx6Q1O4iqZWwIehDNuv3Dv425FIAE8PRwtAx1imEolFTHgBEcoFHm9MDnYgPCg==" }, - "replace-ext": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", - "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", - "dev": true + "@floating-ui/dom": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.2.1.tgz", + "integrity": "sha512-Rt45SmRiV8eU+xXSB9t0uMYiQ/ZWGE/jumse2o3i5RGlyvcbqOF4q+1qBnzLE2kZ5JGhq0iMkcGXUKbFe7MpTA==", + "requires": { + "@floating-ui/core": "^1.2.1" + } }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true + "@floating-ui/react": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.19.2.tgz", + "integrity": "sha512-JyNk4A0Ezirq8FlXECvRtQOX/iBe5Ize0W/pLkrZjfHW9GUV7Xnq6zm6fyZuQzaHHqEnVizmvlA96e1/CkZv+w==", + "requires": { + "@floating-ui/react-dom": "^1.3.0", + "aria-hidden": "^1.1.3", + "tabbable": "^6.0.1" + } + }, + "@floating-ui/react-dom": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-1.3.0.tgz", + "integrity": "sha512-htwHm67Ji5E/pROEAr7f8IKFShuiCKHwUC/UY4vC3I5jiSvGFAYnSYiZO5MlGmads+QqvUkR9ANHEguGrDv72g==", + "requires": { + "@floating-ui/dom": "^1.2.1" + } + }, + "@gar/promisify": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz", + "integrity": "sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==", + "dev": true + }, + "@humanwhocodes/config-array": { + "version": "0.11.8", + "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.8.tgz", + "integrity": "sha512-UybHIJzJnR5Qc/MsD9Kr+RpO2h+/P1GhOwdiLPXK5TWk5sgTdu88bTD9UP+CKbPPh5Rni1u0GjAdYQLemG8g+g==", + "dev": true, + "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==", + "dev": true + }, + "@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==", + "dev": true + }, + "@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": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "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": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/console/-/console-27.5.1.tgz", + "integrity": "sha512-kZ/tNpS3NXn0mlXXXPNuDZnb4c0oZ20r4K5eemM2k30ZC3G0T02nXUvyhf5YdbXWHPEJLc9qGLxEZ216MdL+Zg==", + "dev": true, + "requires": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0" + } + }, + "@jest/core": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/core/-/core-27.5.1.tgz", + "integrity": "sha512-AK6/UTrvQD0Cd24NSqmIA6rKsu0tKIxfiCducZvqxYdmMisOYAsdItspT+fQDQYARPf8XgjAFZi0ogW2agH5nQ==", + "dev": true, + "requires": { + "@jest/console": "^27.5.1", + "@jest/reporters": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "jest-changed-files": "^27.5.1", + "jest-config": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-resolve-dependencies": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "jest-watcher": "^27.5.1", + "micromatch": "^4.0.4", + "rimraf": "^3.0.0", + "slash": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "@jest/environment": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-27.5.1.tgz", + "integrity": "sha512-/WQjhPJe3/ghaol/4Bq480JKXV/Rfw8nQdN7f41fM8VDHLcxKXou6QyXAh3EFr9/bVG3x74z1NWDkP87EiY8gA==", + "dev": true, + "requires": { + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1" + } + }, + "@jest/fake-timers": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/fake-timers/-/fake-timers-27.5.1.tgz", + "integrity": "sha512-/aPowoolwa07k7/oM3aASneNeBGCmGQsc3ugN4u6s4C/+s5M64MFo/+djTdiwcbQlRfFElGuDXWzaWj6QgKObQ==", + "dev": true, + "requires": { + "@jest/types": "^27.5.1", + "@sinonjs/fake-timers": "^8.0.1", + "@types/node": "*", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" + } + }, + "@jest/globals": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/globals/-/globals-27.5.1.tgz", + "integrity": "sha512-ZEJNB41OBQQgGzgyInAv0UUfDDj3upmHydjieSxFvTRuZElrx7tXg/uVQ5hYVEwiXs3+aMsAeEc9X7xiSKCm4Q==", + "dev": true, + "requires": { + "@jest/environment": "^27.5.1", + "@jest/types": "^27.5.1", + "expect": "^27.5.1" + } + }, + "@jest/reporters": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/reporters/-/reporters-27.5.1.tgz", + "integrity": "sha512-cPXh9hWIlVJMQkVk84aIvXuBB4uQQmFqZiacloFuGiP3ah1sbCxCosidXFDfqG8+6fO1oR2dTJTlsOy4VFmUfw==", + "dev": true, + "requires": { + "@bcoe/v8-coverage": "^0.2.3", + "@jest/console": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "collect-v8-coverage": "^1.0.0", + "exit": "^0.1.2", + "glob": "^7.1.2", + "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-haste-map": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "slash": "^3.0.0", + "source-map": "^0.6.0", + "string-length": "^4.0.1", + "terminal-link": "^2.0.0", + "v8-to-istanbul": "^8.1.0" + }, + "dependencies": { + "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 + } + } + }, + "@jest/source-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/source-map/-/source-map-27.5.1.tgz", + "integrity": "sha512-y9NIHUYF3PJRlHk98NdC/N1gl88BL08aQQgu4k4ZopQkCw9t9cV8mtl3TV8b/YCB8XaVTFrmUTAJvjsntDireg==", + "dev": true, + "requires": { + "callsites": "^3.0.0", + "graceful-fs": "^4.2.9", + "source-map": "^0.6.0" + }, + "dependencies": { + "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 + } + } + }, + "@jest/test-result": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-result/-/test-result-27.5.1.tgz", + "integrity": "sha512-EW35l2RYFUcUQxFJz5Cv5MTOxlJIQs4I7gxzi2zVU7PJhOwfYq1MdC5nhSmYjX1gmMmLPvB3sIaC+BkcHRBfag==", + "dev": true, + "requires": { + "@jest/console": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/istanbul-lib-coverage": "^2.0.0", + "collect-v8-coverage": "^1.0.0" + } + }, + "@jest/test-sequencer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/test-sequencer/-/test-sequencer-27.5.1.tgz", + "integrity": "sha512-LCheJF7WB2+9JuCS7VB/EmGIdQuhtqjRNI9A43idHv3E4KltCTsPsLxvdaubFHSYwY/fNjMWjl6vNRhDiN7vpQ==", + "dev": true, + "requires": { + "@jest/test-result": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-runtime": "^27.5.1" + } + }, + "@jest/transform": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/transform/-/transform-27.5.1.tgz", + "integrity": "sha512-ipON6WtYgl/1329g5AIJVbUuEh0wZVbdpGwC99Jw4LwuoBNS95MVphU6zOeD9pDkon+LLbFL7lOQRapbB8SCHw==", + "dev": true, + "requires": { + "@babel/core": "^7.1.0", + "@jest/types": "^27.5.1", + "babel-plugin-istanbul": "^6.1.1", + "chalk": "^4.0.0", + "convert-source-map": "^1.4.0", + "fast-json-stable-stringify": "^2.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-util": "^27.5.1", + "micromatch": "^4.0.4", + "pirates": "^4.0.4", + "slash": "^3.0.0", + "source-map": "^0.6.1", + "write-file-atomic": "^3.0.0" + }, + "dependencies": { + "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 + } + } + }, + "@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "dependencies": { + "@types/yargs": { + "version": "16.0.4", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.4.tgz", + "integrity": "sha512-T8Yc9wt/5LbJyCaLiHPReJa0kApcIgJ7Bn735GjItUfh08Z1pJvu8QZqb9s+mMvKV6WUQRV7K2R46YbjMXTTJw==", + "dev": true, + "requires": { + "@types/yargs-parser": "*" + } + } + } + }, + "@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==", + "requires": { + "@jridgewell/set-array": "^1.0.1", + "@jridgewell/sourcemap-codec": "^1.4.10", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@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==" + }, + "@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==" + }, + "@jridgewell/source-map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.3.tgz", + "integrity": "sha512-b+fsZXeLYi9fEULmfBrhxn4IrPlINf8fiNarzTof004v3lFdntdwa9PF7vFJqm3mg7s+ScJMxXaE3Acp1irZcg==", + "dev": true, + "requires": { + "@jridgewell/gen-mapping": "^0.3.0", + "@jridgewell/trace-mapping": "^0.3.9" + } + }, + "@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==" + }, + "@jridgewell/trace-mapping": { + "version": "0.3.18", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.18.tgz", + "integrity": "sha512-w+niJYzMHdd7USdiH2U6869nqhD2nbfZXND5Yp93qIbEmnDNk7PD48o+YchRVpzMU7M6jVCbenTR7PA1FLQ9pA==", + "requires": { + "@jridgewell/resolve-uri": "3.1.0", + "@jridgewell/sourcemap-codec": "1.4.14" + } + }, + "@leichtgewicht/ip-codec": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.3.tgz", + "integrity": "sha512-nkalE/f1RvRGChwBnEIoBfSEYOXnCRdleKuv6+lePbMDrMZXeDQnqak5XDOeBgrPPyPfAdcCu/B5z+v3VhplGg==", + "dev": true + }, + "@malept/cross-spawn-promise": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@malept/cross-spawn-promise/-/cross-spawn-promise-1.1.1.tgz", + "integrity": "sha512-RTBGWL5FWQcg9orDOCcp4LvItNzUPcyEU9bwaeJX0rJ1IQxzucC48Y0/sQLp/g6t99IQgAlGIaesJS+gTn7tVQ==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.1" + } + }, + "@malept/flatpak-bundler": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@malept/flatpak-bundler/-/flatpak-bundler-0.4.0.tgz", + "integrity": "sha512-9QOtNffcOF/c1seMCDnjckb3R9WHcG34tky+FHpNKKCW0wc/scYLwMtO+ptyGUfMW0/b/n4qRiALlaFHc9Oj7Q==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "fs-extra": "^9.0.0", + "lodash": "^4.17.15", + "tmp-promise": "^3.0.2" + }, + "dependencies": { + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, + "@mantine/core": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@mantine/core/-/core-6.0.13.tgz", + "integrity": "sha512-FjVUGgat2qISV9WD1maVJa81y7H0JjKJ3m0cJj65PzgrXT20hzdEda7S3i4j+a8vUnx+836x5q/yS+RDHvoSlA==", + "requires": { + "@floating-ui/react": "^0.19.1", + "@mantine/styles": "6.0.13", + "@mantine/utils": "6.0.13", + "@radix-ui/react-scroll-area": "1.0.2", + "react-remove-scroll": "^2.5.5", + "react-textarea-autosize": "8.3.4" + } + }, + "@mantine/dates": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@mantine/dates/-/dates-6.0.13.tgz", + "integrity": "sha512-sWStU+sgblTZAfuuFlwG3w3WCFYHVf1L+sG2WdlXOljd9WpQVem214HTh6staJ894+vIQESIvseWvq6FDyQAaQ==", + "requires": { + "@mantine/utils": "6.0.13" + } + }, + "@mantine/form": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@mantine/form/-/form-6.0.13.tgz", + "integrity": "sha512-oR/bnnJEd6T42N5pUhXYZ5RaKC4EZozEFW2jHCWDKIAJDjIgGUQrLL/tCjclQ2NwtghaoCTz+9zu32CuXer7TA==", + "requires": { + "fast-deep-equal": "^3.1.3", + "klona": "^2.0.5" + } + }, + "@mantine/hooks": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@mantine/hooks/-/hooks-6.0.13.tgz", + "integrity": "sha512-fHuE3zXo5OP/Q1dMOTnegU6U+tI9GuhO2tgOz6szVuOxrrk0Hzuq1Na9NUSv27HShSRbAfQk+hvyIh+iVV7KXA==", + "requires": {} + }, + "@mantine/modals": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@mantine/modals/-/modals-6.0.13.tgz", + "integrity": "sha512-R/FfH+vzk1iKxl/HDgUC0CXZI7zvQ79J+VUSw9eQcNWgSTx9IwrDbFeEtWC2SvVNaCYmMSxgadCbgjKsaeqzWA==", + "requires": { + "@mantine/utils": "6.0.13" + } + }, + "@mantine/notifications": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@mantine/notifications/-/notifications-6.0.13.tgz", + "integrity": "sha512-d3BxNN7LEblvAsui0yGiI1q1Ji2OlhFLfe/cLdj7s5VMOtiKYRV14dICJxe4Jn/o+8Gg+UKw+aO/ZiQoT+BGIw==", + "requires": { + "@mantine/utils": "6.0.13", + "react-transition-group": "4.4.2" + } + }, + "@mantine/styles": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@mantine/styles/-/styles-6.0.13.tgz", + "integrity": "sha512-+27oX8ObiBv8jHHDxXKjqe+7cfTJyaAV/Ie00T49EE4LuHuS6nL4vlXHmqamFtDCj2ypEWBV0sdXDev/DNAXSg==", + "requires": { + "clsx": "1.1.1", + "csstype": "3.0.9" + }, + "dependencies": { + "csstype": { + "version": "3.0.9", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.9.tgz", + "integrity": "sha512-rpw6JPxK6Rfg1zLOYCSwle2GFOOsnjmDYDaBwEcwoOg4qlsIVCN789VkBZDJAGi4T07gI4YSutR43t9Zz4Lzuw==" + } + } + }, + "@mantine/utils": { + "version": "6.0.13", + "resolved": "https://registry.npmjs.org/@mantine/utils/-/utils-6.0.13.tgz", + "integrity": "sha512-iqIU9wurqAeccVbWjM0yr1JGne5VP+ob55M03QAXOEN4+ck93VDTjCkZJR2RFhDcs5q0twQFoOmU/gULR8aKIA==", + "requires": {} + }, + "@mdn/browser-compat-data": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-4.1.15.tgz", + "integrity": "sha512-OZx2PxHtJDc9NOHGR3T0ZtX1WYl5qH/xmiH3sKSmcd3o+vPMG1kVUYbZrMxH3fVKpkkkrQpwETCIDRXcMXAWTw==", + "dev": true + }, + "@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "dev": true, + "requires": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + }, + "dependencies": { + "glob-to-regexp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", + "integrity": "sha512-Iozmtbqv0noj0uDDqoL0zNq0VBEfK2YFoMAZoxJe4cwphvLR+JskfF30QhXHOR4m3KrE6NLRYw+U9MRXvifyig==", + "dev": true + } + } + }, + "@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==", + "dev": true, + "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==", + "dev": true + }, + "@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==", + "dev": true, + "requires": { + "@nodelib/fs.scandir": "2.1.5", + "fastq": "^1.6.0" + } + }, + "@pmmmwh/react-refresh-webpack-plugin": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.5.tgz", + "integrity": "sha512-RbG7h6TuP6nFFYKJwbcToA1rjC1FyPg25NR2noAZ0vKI+la01KTSRPkuVPE+U88jXv7javx2JHglUcL1MHcshQ==", + "dev": true, + "requires": { + "ansi-html-community": "^0.0.8", + "common-path-prefix": "^3.0.0", + "core-js-pure": "^3.8.1", + "error-stack-parser": "^2.0.6", + "find-up": "^5.0.0", + "html-entities": "^2.1.0", + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0", + "source-map": "^0.7.3" + } + }, + "@polka/url": { + "version": "1.0.0-next.21", + "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.21.tgz", + "integrity": "sha512-a5Sab1C4/icpTZVzZc5Ghpz88yQtGOyNqYXcZgOssB2uuAr+wF/MvN6bgtW32q7HHrvBki+BsZ0OuNv6EV3K9g==", + "dev": true + }, + "@radix-ui/number": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.0.tgz", + "integrity": "sha512-Ofwh/1HX69ZfJRiRBMTy7rgjAzHmwe4kW9C9Y99HTRUcYLUuVT0KESFj15rPjRgKJs20GPq8Bm5aEDJ8DuA3vA==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/primitive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.0.0.tgz", + "integrity": "sha512-3e7rn8FDMin4CgeL7Z/49smCA3rFYY3Ha2rUQ7HRWFadS5iCRw08ZgVT1LaNTCNqgvrUiyczLflrVrF0SRQtNA==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-compose-refs": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.0.0.tgz", + "integrity": "sha512-0KaSv6sx787/hK3eF53iOkiSLwAGlFMx5lotrqD2pTjB18KbybKoEIgkNZTKC60YECDQTKGTRcDBILwZVqVKvA==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-context": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.0.0.tgz", + "integrity": "sha512-1pVM9RfOQ+n/N5PJK33kRSKsr1glNxomxONs5c49MliinBY6Yw2Q995qfBUUo0/Mbg05B/sGA0gkgPI7kmSHBg==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-dialog": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dialog/-/react-dialog-1.0.0.tgz", + "integrity": "sha512-Yn9YU+QlHYLWwV1XfKiqnGVpWYWk6MeBVM6x/bcoyPvxgjQGoeT35482viLPctTMWoMw0PoHgqfSox7Ig+957Q==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-dismissable-layer": "1.0.0", + "@radix-ui/react-focus-guards": "1.0.0", + "@radix-ui/react-focus-scope": "1.0.0", + "@radix-ui/react-id": "1.0.0", + "@radix-ui/react-portal": "1.0.0", + "@radix-ui/react-presence": "1.0.0", + "@radix-ui/react-primitive": "1.0.0", + "@radix-ui/react-slot": "1.0.0", + "@radix-ui/react-use-controllable-state": "1.0.0", + "aria-hidden": "^1.1.1", + "react-remove-scroll": "2.5.4" + }, + "dependencies": { + "@radix-ui/react-primitive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.0.tgz", + "integrity": "sha512-EyXe6mnRlHZ8b6f4ilTDrXmkLShICIuOTTj0GX4w1rp+wSxf3+TD05u1UOITC8VsJ2a9nwHvdXtOXEOl0Cw/zQ==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.0" + } + }, + "@radix-ui/react-slot": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.0.tgz", + "integrity": "sha512-3mrKauI/tWXo1Ll+gN5dHcxDPdm/Df1ufcDLCecn+pnCIVcdWE7CujXo8QaXOWRJyZyQWWbpB8eFwHzWXlv5mQ==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0" + } + }, + "react-remove-scroll": { + "version": "2.5.4", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.4.tgz", + "integrity": "sha512-xGVKJJr0SJGQVirVFAUZ2k1QLyO6m+2fy0l8Qawbp5Jgrv3DeLalrfMNBFSlmz5kriGGzsVBtGVnf4pTKIhhWA==", + "requires": { + "react-remove-scroll-bar": "^2.3.3", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + } + } + } + }, + "@radix-ui/react-direction": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.0.0.tgz", + "integrity": "sha512-2HV05lGUgYcA6xgLQ4BKPDmtL+QbIZYH5fCOTAOOcJ5O0QbWS3i9lKaurLzliYUDhORI2Qr3pyjhJh44lKA3rQ==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-dismissable-layer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.0.tgz", + "integrity": "sha512-n7kDRfx+LB1zLueRDvZ1Pd0bxdJWDUZNQ/GWoxDn2prnuJKRdxsjulejX/ePkOsLi2tTm6P24mDqlMSgQpsT6g==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-primitive": "1.0.0", + "@radix-ui/react-use-callback-ref": "1.0.0", + "@radix-ui/react-use-escape-keydown": "1.0.0" + }, + "dependencies": { + "@radix-ui/react-primitive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.0.tgz", + "integrity": "sha512-EyXe6mnRlHZ8b6f4ilTDrXmkLShICIuOTTj0GX4w1rp+wSxf3+TD05u1UOITC8VsJ2a9nwHvdXtOXEOl0Cw/zQ==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.0" + } + }, + "@radix-ui/react-slot": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.0.tgz", + "integrity": "sha512-3mrKauI/tWXo1Ll+gN5dHcxDPdm/Df1ufcDLCecn+pnCIVcdWE7CujXo8QaXOWRJyZyQWWbpB8eFwHzWXlv5mQ==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0" + } + } + } + }, + "@radix-ui/react-focus-guards": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-guards/-/react-focus-guards-1.0.0.tgz", + "integrity": "sha512-UagjDk4ijOAnGu4WMUPj9ahi7/zJJqNZ9ZAiGPp7waUWJO0O1aWXi/udPphI0IUjvrhBsZJGSN66dR2dsueLWQ==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-focus-scope": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-focus-scope/-/react-focus-scope-1.0.0.tgz", + "integrity": "sha512-C4SWtsULLGf/2L4oGeIHlvWQx7Rf+7cX/vKOAD2dXW0A1b5QXwi3wWeaEgW+wn+SEVrraMUk05vLU9fZZz5HbQ==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-primitive": "1.0.0", + "@radix-ui/react-use-callback-ref": "1.0.0" + }, + "dependencies": { + "@radix-ui/react-primitive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.0.tgz", + "integrity": "sha512-EyXe6mnRlHZ8b6f4ilTDrXmkLShICIuOTTj0GX4w1rp+wSxf3+TD05u1UOITC8VsJ2a9nwHvdXtOXEOl0Cw/zQ==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.0" + } + }, + "@radix-ui/react-slot": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.0.tgz", + "integrity": "sha512-3mrKauI/tWXo1Ll+gN5dHcxDPdm/Df1ufcDLCecn+pnCIVcdWE7CujXo8QaXOWRJyZyQWWbpB8eFwHzWXlv5mQ==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0" + } + } + } + }, + "@radix-ui/react-id": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.0.0.tgz", + "integrity": "sha512-Q6iAB/U7Tq3NTolBBQbHTgclPmGWE3OlktGGqrClPozSw4vkQ1DfQAOtzgRPecKsMdJINE05iaoDUG8tRzCBjw==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.0" + } + }, + "@radix-ui/react-portal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.0.0.tgz", + "integrity": "sha512-a8qyFO/Xb99d8wQdu4o7qnigNjTPG123uADNecz0eX4usnQEj7o+cG4ZX4zkqq98NYekT7UoEQIjxBNWIFuqTA==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.0" + }, + "dependencies": { + "@radix-ui/react-primitive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.0.tgz", + "integrity": "sha512-EyXe6mnRlHZ8b6f4ilTDrXmkLShICIuOTTj0GX4w1rp+wSxf3+TD05u1UOITC8VsJ2a9nwHvdXtOXEOl0Cw/zQ==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.0" + } + }, + "@radix-ui/react-slot": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.0.tgz", + "integrity": "sha512-3mrKauI/tWXo1Ll+gN5dHcxDPdm/Df1ufcDLCecn+pnCIVcdWE7CujXo8QaXOWRJyZyQWWbpB8eFwHzWXlv5mQ==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0" + } + } + } + }, + "@radix-ui/react-presence": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.0.0.tgz", + "integrity": "sha512-A+6XEvN01NfVWiKu38ybawfHsBjWum42MRPnEuqPsBZ4eV7e/7K321B5VgYMPv3Xx5An6o1/l9ZuDBgmcmWK3w==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-use-layout-effect": "1.0.0" + } + }, + "@radix-ui/react-primitive": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-1.0.1.tgz", + "integrity": "sha512-fHbmislWVkZaIdeF6GZxF0A/NH/3BjrGIYj+Ae6eTmTCr7EB0RQAAVEiqsXK6p3/JcRqVSBQoceZroj30Jj3XA==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-slot": "1.0.1" + } + }, + "@radix-ui/react-scroll-area": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-scroll-area/-/react-scroll-area-1.0.2.tgz", + "integrity": "sha512-k8VseTxI26kcKJaX0HPwkvlNBPTs56JRdYzcZ/vzrNUkDlvXBy8sMc7WvCpYzZkHgb+hd72VW9MqkqecGtuNgg==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/number": "1.0.0", + "@radix-ui/primitive": "1.0.0", + "@radix-ui/react-compose-refs": "1.0.0", + "@radix-ui/react-context": "1.0.0", + "@radix-ui/react-direction": "1.0.0", + "@radix-ui/react-presence": "1.0.0", + "@radix-ui/react-primitive": "1.0.1", + "@radix-ui/react-use-callback-ref": "1.0.0", + "@radix-ui/react-use-layout-effect": "1.0.0" + } + }, + "@radix-ui/react-slot": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.1.tgz", + "integrity": "sha512-avutXAFL1ehGvAXtPquu0YK5oz6ctS474iM3vNGQIkswrVhdrS52e3uoMQBzZhNRAIE0jBnUyXWNmSjGHhCFcw==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.0" + } + }, + "@radix-ui/react-use-callback-ref": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.0.tgz", + "integrity": "sha512-GZtyzoHz95Rhs6S63D2t/eqvdFCm7I+yHMLVQheKM7nBD8mbZIt+ct1jz4536MDnaOGKIxynJ8eHTkVGVVkoTg==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@radix-ui/react-use-controllable-state": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.0.tgz", + "integrity": "sha512-FohDoZvk3mEXh9AWAVyRTYR4Sq7/gavuofglmiXB2g1aKyboUD4YtgWxKj8O5n+Uak52gXQ4wKz5IFST4vtJHg==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.0" + } + }, + "@radix-ui/react-use-escape-keydown": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.0.tgz", + "integrity": "sha512-JwfBCUIfhXRxKExgIqGa4CQsiMemo1Xt0W/B4ei3fpzpvPENKpMKQ8mZSB6Acj3ebrAEgi2xiQvcI1PAAodvyg==", + "requires": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.0" + } + }, + "@radix-ui/react-use-layout-effect": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.0.tgz", + "integrity": "sha512-6Tpkq+R6LOlmQb1R5NNETLG0B4YP0wc+klfXafpUCj6JGyaUc8il7/kUZ7m59rGbXGczE9Bs+iz2qloqsZBduQ==", + "requires": { + "@babel/runtime": "^7.13.10" + } + }, + "@remix-run/router": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.1.0.tgz", + "integrity": "sha512-rGl+jH/7x1KBCQScz9p54p0dtPLNeKGb3e0wD2H5/oZj41bwQUnXdzbj2TbUAFhvD7cp9EyEQA4dEgpUFa1O7Q==" + }, + "@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": 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": "8.1.0", + "resolved": "https://registry.npmjs.org/@sinonjs/fake-timers/-/fake-timers-8.1.0.tgz", + "integrity": "sha512-OAPJUAtgeINhh/TAlUID4QTs53Njm7xzddaVlEs/SXwgtiD1tW22zAB/W1wdqfrpmikgaWQ9Fw6Ws+hsiRm5Vg==", + "dev": true, + "requires": { + "@sinonjs/commons": "^1.7.0" + } + }, + "@stylelint/postcss-css-in-js": { + "version": "0.38.0", + "resolved": "https://registry.npmjs.org/@stylelint/postcss-css-in-js/-/postcss-css-in-js-0.38.0.tgz", + "integrity": "sha512-XOz5CAe49kS95p5yRd+DAIWDojTjfmyAQ4bbDlXMdbZTQ5t0ThjSLvWI6JI2uiS7MFurVBkZ6zUqcimzcLTBoQ==", + "dev": true, + "requires": { + "@babel/core": "^7.17.9" + } + }, + "@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==", + "dev": true, + "requires": { + "defer-to-connect": "^2.0.0" + } + }, + "@tanstack/match-sorter-utils": { + "version": "8.7.2", + "resolved": "https://registry.npmjs.org/@tanstack/match-sorter-utils/-/match-sorter-utils-8.7.2.tgz", + "integrity": "sha512-bptNeoexeDB947fWoCPwUchPSx5FA9gwzU0bkXz0du5pT8Ud2+1ob+xOgHj6EF3VN0kdXtLhwjPyhY7/dJglkg==", + "requires": { + "remove-accents": "0.4.2" + } + }, + "@tanstack/query-core": { + "version": "4.29.5", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-4.29.5.tgz", + "integrity": "sha512-xXIiyQ/4r9KfaJ3k6kejqcaqFXXBTzN2aOJ5H1J6aTJE9hl/nbgAdfF6oiIu0CD5xowejJEJ6bBg8TO7BN4NuQ==" + }, + "@tanstack/react-query": { + "version": "4.29.5", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-4.29.5.tgz", + "integrity": "sha512-F87cibC3s3eG0Q90g2O+hqntpCrudKFnR8P24qkH9uccEhXErnJxBC/AAI4cJRV2bfMO8IeGZQYf3WyYgmSg0w==", + "requires": { + "@tanstack/query-core": "4.29.5", + "use-sync-external-store": "^1.2.0" + } + }, + "@tanstack/react-query-devtools": { + "version": "4.29.6", + "resolved": "https://registry.npmjs.org/@tanstack/react-query-devtools/-/react-query-devtools-4.29.6.tgz", + "integrity": "sha512-qpYI41a69MWmrllcGiSE1KlpmnwJY/w0yKMnmp6VXn7nVy0i5TMMAT4u8D48F1Ipv/BKIDI1lqxPAvB4MqryBg==", + "requires": { + "@tanstack/match-sorter-utils": "^8.7.0", + "superjson": "^1.10.0", + "use-sync-external-store": "^1.2.0" + } + }, + "@teamsupercell/typings-for-css-modules-loader": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/@teamsupercell/typings-for-css-modules-loader/-/typings-for-css-modules-loader-2.5.2.tgz", + "integrity": "sha512-3sqH2B4itcm5XgV1IHENt4NOaW7bOC1CwJr63vrdKWWyKVxNxtBM+ABVhJZYFCCVAwNy7ulA64z6HyQqw96m4A==", + "dev": true, + "requires": { + "camelcase": "^5.3.1", + "loader-utils": "^1.4.2", + "prettier": "*", + "schema-utils": "^2.0.1" + }, + "dependencies": { + "json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", + "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + } + }, + "schema-utils": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.1.tgz", + "integrity": "sha512-SHiNtMOUGWBQJwzISiVYKu82GiV4QYGePp3odlY1tuKO7gPtphAT5R/py0fA6xtbgLL/RvtJZnU9b8s0F1q0Xg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.5", + "ajv": "^6.12.4", + "ajv-keywords": "^3.5.2" + } + } + } + }, + "@testing-library/dom": { + "version": "8.13.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.13.0.tgz", + "integrity": "sha512-9VHgfIatKNXQNaZTtLnalIy0jNZzY35a4S3oi08YAt9Hv1VsfZ/DfA45lM8D/UhtHBGJ4/lGwp0PZkVndRkoOQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.4", + "@babel/runtime": "^7.12.5", + "@types/aria-query": "^4.2.0", + "aria-query": "^5.0.0", + "chalk": "^4.1.0", + "dom-accessibility-api": "^0.5.9", + "lz-string": "^1.4.4", + "pretty-format": "^27.0.2" + } + }, + "@testing-library/jest-dom": { + "version": "5.16.4", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.4.tgz", + "integrity": "sha512-Gy+IoFutbMQcky0k+bqqumXZ1cTGswLsFqmNLzNdSKkU9KGV2u9oXhukCbbJ9/LRPKiqwxEE8VpV/+YZlfkPUA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.9.2", + "@types/testing-library__jest-dom": "^5.9.1", + "aria-query": "^5.0.0", + "chalk": "^3.0.0", + "css": "^3.0.0", + "css.escape": "^1.5.1", + "dom-accessibility-api": "^0.5.6", + "lodash": "^4.17.15", + "redent": "^3.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" + } + } + } + }, + "@testing-library/react": { + "version": "13.0.0", + "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-13.0.0.tgz", + "integrity": "sha512-p0lYA1M7uoEmk2LnCbZLGmHJHyH59sAaZVXChTXlyhV/PRW9LoIh4mdf7tiXsO8BoNG+vN8UnFJff1hbZeXv+w==", + "dev": true, + "requires": { + "@babel/runtime": "^7.12.5", + "@testing-library/dom": "^8.5.0", + "@types/react-dom": "*" + } }, - "vinyl": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", - "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", - "dev": true, - "requires": { - "clone": "^2.1.2", - "clone-stats": "^1.0.0", - "remove-trailing-separator": "^1.1.0", - "replace-ext": "^2.0.0", - "teex": "^1.0.1" - } - } - } - }, - "iconv-corefoundation": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz", - "integrity": "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==", - "dev": true, - "optional": true, - "requires": { - "cli-truncate": "^2.1.0", - "node-addon-api": "^1.6.3" - } - }, - "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==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - } - }, - "icss-utils": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", - "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", - "dev": true, - "requires": {} - }, - "identity-obj-proxy": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", - "integrity": "sha1-lNK9qWCERT7zb7xarsN+D3nx/BQ=", - "dev": true, - "requires": { - "harmony-reflect": "^1.4.6" - } - }, - "ieee754": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", - "dev": true - }, - "ignore": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", - "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", - "dev": true - }, - "immediate": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", - "dev": true - }, - "immer": { - "version": "9.0.21", - "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", - "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==" - }, - "immutable": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz", - "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==", - "dev": true - }, - "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-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/import-from/-/import-from-3.0.0.tgz", - "integrity": "sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ==", - "dev": true, - "requires": { - "resolve-from": "^5.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 - } - } - }, - "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": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "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 - }, - "indexes-of": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", - "integrity": "sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "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==", - "dev": true - }, - "ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "dev": true - }, - "internal-slot": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", - "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", - "dev": true, - "requires": { - "get-intrinsic": "^1.1.0", - "has": "^1.0.3", - "side-channel": "^1.0.4" - } - }, - "interpret": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", - "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", - "dev": true - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "requires": { - "loose-envify": "^1.0.0" - } - }, - "ip": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", - "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", - "dev": true - }, - "ipaddr.js": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz", - "integrity": "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==", - "dev": true - }, - "is-absolute": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", - "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", - "dev": true, - "requires": { - "is-relative": "^1.0.0", - "is-windows": "^1.0.1" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-alphabetical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", - "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", - "dev": true - }, - "is-alphanumeric": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz", - "integrity": "sha512-ZmRL7++ZkcMOfDuWZuMJyIVLr2keE1o/DeNWh1EmgqGhUcV+9BIVsx0BcSBOHTZqzjs4+dISzr2KAeBEWGgXeA==", - "dev": true - }, - "is-alphanumerical": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", - "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", - "dev": true, - "requires": { - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0" - } - }, - "is-arrayish": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", - "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" - }, - "is-bigint": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", - "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", - "dev": true, - "requires": { - "has-bigints": "^1.0.1" - } - }, - "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==", - "dev": true, - "requires": { - "binary-extensions": "^2.0.0" - } - }, - "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==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" - }, - "is-callable": { - "version": "1.2.7", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", - "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", - "dev": true - }, - "is-ci": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", - "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", - "dev": true, - "requires": { - "ci-info": "^3.2.0" - } - }, - "is-core-module": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", - "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", - "requires": { - "has": "^1.0.3" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "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==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-decimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", - "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", - "dev": true - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - }, - "is-directory": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", - "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", - "dev": true - }, - "is-docker": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", - "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", - "dev": true - }, - "is-electron": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/is-electron/-/is-electron-2.2.2.tgz", - "integrity": "sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg==" - }, - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "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==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-hexadecimal": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", - "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", - "dev": true - }, - "is-interactive": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", - "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", - "dev": true - }, - "is-lambda": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", - "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=", - "dev": true - }, - "is-negated-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", - "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", - "dev": true - }, - "is-negative-zero": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", - "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", - "dev": true - }, - "is-number": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", - "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", - "dev": true - }, - "is-number-object": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", - "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", - "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" - }, - "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==", - "dev": true - }, - "is-plain-obj": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", - "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", - "dev": true - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "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-regex": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", - "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-tostringtag": "^1.0.0" - } - }, - "is-regexp": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz", - "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==", - "dev": true - }, - "is-relative": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", - "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", - "dev": true, - "requires": { - "is-unc-path": "^1.0.0" - } - }, - "is-shared-array-buffer": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", - "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-stream": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", - "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", - "dev": true - }, - "is-string": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", - "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", - "dev": true, - "requires": { - "has-tostringtag": "^1.0.0" - } - }, - "is-supported-regexp-flag": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-supported-regexp-flag/-/is-supported-regexp-flag-1.0.1.tgz", - "integrity": "sha512-3vcJecUUrpgCqc/ca0aWeNu64UGgxcvO60K/Fkr1N6RSvfGCTU60UKN68JDmKokgba0rFFJs12EnzOQa14ubKQ==", - "dev": true - }, - "is-symbol": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", - "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", - "dev": true, - "requires": { - "has-symbols": "^1.0.2" - } - }, - "is-typedarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", - "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", - "dev": true - }, - "is-unc-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", - "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", - "dev": true, - "requires": { - "unc-path-regex": "^0.1.2" - } - }, - "is-unicode-supported": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", - "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", - "dev": true - }, - "is-utf8": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", - "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", - "dev": true - }, - "is-valid-glob": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", - "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", - "dev": true - }, - "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==", - "dev": true, - "requires": { - "call-bind": "^1.0.2" - } - }, - "is-what": { - "version": "4.1.7", - "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.7.tgz", - "integrity": "sha512-DBVOQNiPKnGMxRMLIYSwERAS5MVY1B7xYiGnpgctsOFvVDz9f9PFXXxMcTOHuoqYp4NK9qFYQaIC1NRRxLMpBQ==" - }, - "is-whitespace-character": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", - "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", - "dev": true - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-word-character": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", - "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", - "dev": true - }, - "is-wsl": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", - "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", - "dev": true, - "requires": { - "is-docker": "^2.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isbinaryfile": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.0.tgz", - "integrity": "sha512-UDdnyGvMajJUWCkib7Cei/dvyJrrvo4FIrsvSFWdPpXSUorzXrDJ0S+X5Q4ZlasfPjca4yqCNNsjbCeiy8FFeg==", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "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.1.0", - "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", - "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", - "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" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "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" - }, - "dependencies": { - "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 - } - } - }, - "istanbul-reports": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", - "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", - "dev": true, - "requires": { - "html-escaper": "^2.0.0", - "istanbul-lib-report": "^3.0.0" - } - }, - "jake": { - "version": "10.8.5", - "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", - "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", - "dev": true, - "requires": { - "async": "^3.2.3", - "chalk": "^4.0.2", - "filelist": "^1.0.1", - "minimatch": "^3.0.4" - } - }, - "jest": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", - "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", - "dev": true, - "requires": { - "@jest/core": "^27.5.1", - "import-local": "^3.0.2", - "jest-cli": "^27.5.1" - } - }, - "jest-changed-files": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", - "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "execa": "^5.0.0", - "throat": "^6.0.1" - } - }, - "jest-circus": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", - "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "dedent": "^0.7.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3", - "throat": "^6.0.1" - } - }, - "jest-cli": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", - "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", - "dev": true, - "requires": { - "@jest/core": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "exit": "^0.1.2", - "graceful-fs": "^4.2.9", - "import-local": "^3.0.2", - "jest-config": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "prompts": "^2.0.1", - "yargs": "^16.2.0" - } - }, - "jest-config": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", - "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", - "dev": true, - "requires": { - "@babel/core": "^7.8.0", - "@jest/test-sequencer": "^27.5.1", - "@jest/types": "^27.5.1", - "babel-jest": "^27.5.1", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "deepmerge": "^4.2.2", - "glob": "^7.1.1", - "graceful-fs": "^4.2.9", - "jest-circus": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-jasmine2": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runner": "^27.5.1", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "micromatch": "^4.0.4", - "parse-json": "^5.2.0", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "strip-json-comments": "^3.1.1" - } - }, - "jest-diff": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", - "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "diff-sequences": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - } - }, - "jest-docblock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", - "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", - "dev": true, - "requires": { - "detect-newline": "^3.0.0" - } - }, - "jest-each": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", - "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1" - } - }, - "jest-environment-jsdom": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", - "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1", - "jsdom": "^16.6.0" - } - }, - "jest-environment-node": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", - "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "jest-mock": "^27.5.1", - "jest-util": "^27.5.1" - } - }, - "jest-get-type": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", - "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", - "dev": true - }, - "jest-haste-map": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", - "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@types/graceful-fs": "^4.1.2", - "@types/node": "*", - "anymatch": "^3.0.3", - "fb-watchman": "^2.0.0", - "fsevents": "^2.3.2", - "graceful-fs": "^4.2.9", - "jest-regex-util": "^27.5.1", - "jest-serializer": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "micromatch": "^4.0.4", - "walker": "^1.0.7" - } - }, - "jest-jasmine2": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", - "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "co": "^4.6.0", - "expect": "^27.5.1", - "is-generator-fn": "^2.0.0", - "jest-each": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "pretty-format": "^27.5.1", - "throat": "^6.0.1" - } - }, - "jest-leak-detector": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", - "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", - "dev": true, - "requires": { - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - } - }, - "jest-matcher-utils": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", - "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", - "dev": true, - "requires": { - "chalk": "^4.0.0", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "pretty-format": "^27.5.1" - } - }, - "jest-message-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", - "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", - "dev": true, - "requires": { - "@babel/code-frame": "^7.12.13", - "@jest/types": "^27.5.1", - "@types/stack-utils": "^2.0.0", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "micromatch": "^4.0.4", - "pretty-format": "^27.5.1", - "slash": "^3.0.0", - "stack-utils": "^2.0.3" - } - }, - "jest-mock": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", - "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@types/node": "*" - } - }, - "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": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", - "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", - "dev": true - }, - "jest-resolve": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", - "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-pnp-resolver": "^1.2.2", - "jest-util": "^27.5.1", - "jest-validate": "^27.5.1", - "resolve": "^1.20.0", - "resolve.exports": "^1.1.0", - "slash": "^3.0.0" - } - }, - "jest-resolve-dependencies": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", - "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-snapshot": "^27.5.1" - } - }, - "jest-runner": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", - "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", - "dev": true, - "requires": { - "@jest/console": "^27.5.1", - "@jest/environment": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "emittery": "^0.8.1", - "graceful-fs": "^4.2.9", - "jest-docblock": "^27.5.1", - "jest-environment-jsdom": "^27.5.1", - "jest-environment-node": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-leak-detector": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-runtime": "^27.5.1", - "jest-util": "^27.5.1", - "jest-worker": "^27.5.1", - "source-map-support": "^0.5.6", - "throat": "^6.0.1" - } - }, - "jest-runtime": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", - "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", - "dev": true, - "requires": { - "@jest/environment": "^27.5.1", - "@jest/fake-timers": "^27.5.1", - "@jest/globals": "^27.5.1", - "@jest/source-map": "^27.5.1", - "@jest/test-result": "^27.5.1", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "chalk": "^4.0.0", - "cjs-module-lexer": "^1.0.0", - "collect-v8-coverage": "^1.0.0", - "execa": "^5.0.0", - "glob": "^7.1.3", - "graceful-fs": "^4.2.9", - "jest-haste-map": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-mock": "^27.5.1", - "jest-regex-util": "^27.5.1", - "jest-resolve": "^27.5.1", - "jest-snapshot": "^27.5.1", - "jest-util": "^27.5.1", - "slash": "^3.0.0", - "strip-bom": "^4.0.0" - } - }, - "jest-serializer": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", - "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", - "dev": true, - "requires": { - "@types/node": "*", - "graceful-fs": "^4.2.9" - } - }, - "jest-snapshot": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", - "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", - "dev": true, - "requires": { - "@babel/core": "^7.7.2", - "@babel/generator": "^7.7.2", - "@babel/plugin-syntax-typescript": "^7.7.2", - "@babel/traverse": "^7.7.2", - "@babel/types": "^7.0.0", - "@jest/transform": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/babel__traverse": "^7.0.4", - "@types/prettier": "^2.1.5", - "babel-preset-current-node-syntax": "^1.0.0", - "chalk": "^4.0.0", - "expect": "^27.5.1", - "graceful-fs": "^4.2.9", - "jest-diff": "^27.5.1", - "jest-get-type": "^27.5.1", - "jest-haste-map": "^27.5.1", - "jest-matcher-utils": "^27.5.1", - "jest-message-util": "^27.5.1", - "jest-util": "^27.5.1", - "natural-compare": "^1.4.0", - "pretty-format": "^27.5.1", - "semver": "^7.3.2" - } - }, - "jest-util": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", - "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "@types/node": "*", - "chalk": "^4.0.0", - "ci-info": "^3.2.0", - "graceful-fs": "^4.2.9", - "picomatch": "^2.2.3" - } - }, - "jest-validate": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", - "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", - "dev": true, - "requires": { - "@jest/types": "^27.5.1", - "camelcase": "^6.2.0", - "chalk": "^4.0.0", - "jest-get-type": "^27.5.1", - "leven": "^3.1.0", - "pretty-format": "^27.5.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": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", - "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", - "dev": true, - "requires": { - "@jest/test-result": "^27.5.1", - "@jest/types": "^27.5.1", - "@types/node": "*", - "ansi-escapes": "^4.2.1", - "chalk": "^4.0.0", - "jest-util": "^27.5.1", - "string-length": "^4.0.1" - } - }, - "jest-worker": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", - "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", - "dev": true, - "requires": { - "@types/node": "*", - "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.2.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", - "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", - "dev": true - }, - "js-tokens": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", - "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" - }, - "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" - } - }, - "jsdom": { - "version": "16.7.0", - "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", - "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", - "dev": true, - "requires": { - "abab": "^2.0.5", - "acorn": "^8.2.4", - "acorn-globals": "^6.0.0", - "cssom": "^0.4.4", - "cssstyle": "^2.3.0", - "data-urls": "^2.0.0", - "decimal.js": "^10.2.1", - "domexception": "^2.0.1", - "escodegen": "^2.0.0", - "form-data": "^3.0.0", - "html-encoding-sniffer": "^2.0.1", - "http-proxy-agent": "^4.0.1", - "https-proxy-agent": "^5.0.0", - "is-potential-custom-element-name": "^1.0.1", - "nwsapi": "^2.2.0", - "parse5": "6.0.1", - "saxes": "^5.0.1", - "symbol-tree": "^3.2.4", - "tough-cookie": "^4.0.0", - "w3c-hr-time": "^1.0.2", - "w3c-xmlserializer": "^2.0.0", - "webidl-conversions": "^6.1.0", - "whatwg-encoding": "^1.0.5", - "whatwg-mimetype": "^2.3.0", - "whatwg-url": "^8.5.0", - "ws": "^7.4.6", - "xml-name-validator": "^3.0.0" - }, - "dependencies": { "@tootallnate/once": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", - "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", - "dev": true + "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 }, - "form-data": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", - "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", - "dev": true, - "requires": { - "asynckit": "^0.4.0", - "combined-stream": "^1.0.8", - "mime-types": "^2.1.12" - } + "@trysound/sax": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz", + "integrity": "sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==", + "dev": true }, - "http-proxy-agent": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", - "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", - "dev": true, - "requires": { - "@tootallnate/once": "1", - "agent-base": "6", - "debug": "4" - } - } - } - }, - "jsesc": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", - "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" - }, - "json-buffer": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", - "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", - "dev": true - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-parse-even-better-errors": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", - "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" - }, - "json-schema": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", - "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", - "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==", - "dev": true - }, - "json-schema-typed": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-7.0.3.tgz", - "integrity": "sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==" - }, - "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": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", - "dev": true - }, - "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==", - "dev": true, - "optional": true - }, - "json5": { - "version": "2.2.3", - "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", - "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" - }, - "jsonfile": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", - "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6" - } - }, - "jsx-ast-utils": { - "version": "3.3.3", - "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", - "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==", - "dev": true, - "requires": { - "array-includes": "^3.1.5", - "object.assign": "^4.1.3" - } - }, - "jszip": { - "version": "3.9.1", - "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.9.1.tgz", - "integrity": "sha512-H9A60xPqJ1CuC4Ka6qxzXZeU8aNmgOeP5IFqwJbQQwtu2EUYxota3LdsiZWplF7Wgd9tkAd0mdu36nceSaPuYw==", - "dev": true, - "requires": { - "lie": "~3.3.0", - "pako": "~1.0.2", - "readable-stream": "~2.3.6", - "set-immediate-shim": "~1.0.1" - } - }, - "keyboardevent-from-electron-accelerator": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/keyboardevent-from-electron-accelerator/-/keyboardevent-from-electron-accelerator-2.0.0.tgz", - "integrity": "sha512-iQcmNA0M4ETMNi0kG/q0h/43wZk7rMeKYrXP7sqKIJbHkTU8Koowgzv+ieR/vWJbOwxx5nDC3UnudZ0aLSu4VA==" - }, - "keyboardevents-areequal": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/keyboardevents-areequal/-/keyboardevents-areequal-0.2.2.tgz", - "integrity": "sha512-Nv+Kr33T0mEjxR500q+I6IWisOQ0lK1GGOncV0kWE6n4KFmpcu7RUX5/2B0EUtX51Cb0HjZ9VJsSY3u4cBa0kw==" - }, - "keyv": { - "version": "4.5.2", - "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", - "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", - "dev": true, - "requires": { - "json-buffer": "3.0.1" - } - }, - "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 - }, - "klona": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz", - "integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==" - }, - "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 - }, - "language-subtag-registry": { - "version": "0.3.21", - "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz", - "integrity": "sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg==", - "dev": true - }, - "language-tags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", - "integrity": "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=", - "dev": true, - "requires": { - "language-subtag-registry": "~0.3.2" - } - }, - "lazy-val": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz", - "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==" - }, - "lazystream": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", - "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", - "dev": true, - "requires": { - "readable-stream": "^2.0.5" - } - }, - "lead": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", - "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", - "dev": true, - "requires": { - "flush-write-stream": "^1.0.2" - } - }, - "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==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1", - "type-check": "~0.4.0" - } - }, - "lie": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", - "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", - "dev": true, - "requires": { - "immediate": "~3.0.5" - } - }, - "lilconfig": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.5.tgz", - "integrity": "sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==", - "dev": true - }, - "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==" - }, - "lint-staged": { - "version": "12.3.7", - "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-12.3.7.tgz", - "integrity": "sha512-/S4D726e2GIsDVWIk1XGvheCaDm1SJRQp8efamZFWJxQMVEbOwSysp7xb49Oo73KYCdy97mIWinhlxcoNqIfIQ==", - "dev": true, - "requires": { - "cli-truncate": "^3.1.0", - "colorette": "^2.0.16", - "commander": "^8.3.0", - "debug": "^4.3.3", - "execa": "^5.1.1", - "lilconfig": "2.0.4", - "listr2": "^4.0.1", - "micromatch": "^4.0.4", - "normalize-path": "^3.0.0", - "object-inspect": "^1.12.0", - "pidtree": "^0.5.0", - "string-argv": "^0.3.1", - "supports-color": "^9.2.1", - "yaml": "^1.10.2" - }, - "dependencies": { - "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 + "@ts-rest/core": { + "version": "3.23.0", + "resolved": "https://registry.npmjs.org/@ts-rest/core/-/core-3.23.0.tgz", + "integrity": "sha512-2vJwa682m9yS/xQPvPxZBluJfIZwNkt2HY9ER3UtGnu8Dijw+8iymSyIyjRLpFFWUyRnVp9IqrEi/d84bkNFIw==", + "requires": {} }, - "ansi-styles": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.1.0.tgz", - "integrity": "sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ==", - "dev": true + "@tsconfig/node10": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", + "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", + "dev": true }, - "cli-truncate": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", - "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", - "dev": true, - "requires": { - "slice-ansi": "^5.0.0", - "string-width": "^5.0.0" - } + "@tsconfig/node12": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", + "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", + "dev": true }, - "commander": { - "version": "8.3.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", - "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", - "dev": true + "@tsconfig/node14": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", + "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", + "dev": true }, - "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 + "@tsconfig/node16": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", + "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", + "dev": true }, - "lilconfig": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.4.tgz", - "integrity": "sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA==", - "dev": true + "@types/aria-query": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==", + "dev": true }, - "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, - "requires": { - "ansi-styles": "^6.0.0", - "is-fullwidth-code-point": "^4.0.0" - } + "@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": "*" + } }, - "string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "requires": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - } + "@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" + } }, - "strip-ansi": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", - "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } + "@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" + } }, - "supports-color": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.2.2.tgz", - "integrity": "sha512-XC6g/Kgux+rJXmwokjm9ECpD6k/smUoS5LKlUCcsYr4IY3rW0XyAympon2RmxGrlnZURMpg5T18gWDP9CsHXFA==", - "dev": true - } - } - }, - "listr2": { - "version": "4.0.5", - "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.5.tgz", - "integrity": "sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA==", - "dev": true, - "requires": { - "cli-truncate": "^2.1.0", - "colorette": "^2.0.16", - "log-update": "^4.0.0", - "p-map": "^4.0.0", - "rfdc": "^1.3.0", - "rxjs": "^7.5.5", - "through": "^2.3.8", - "wrap-ansi": "^7.0.0" - }, - "dependencies": { - "rxjs": { - "version": "7.5.5", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", - "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", - "dev": true, - "requires": { - "tslib": "^2.1.0" - } - } - } - }, - "load-json-file": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", - "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "parse-json": "^4.0.0", - "pify": "^3.0.0", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } + "@types/babel__traverse": { + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", + "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0" + } }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - } - } - }, - "load-script": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz", - "integrity": "sha1-BJGTngvuVkPuSUp+PaPSuscMbKQ=" - }, - "loader-runner": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", - "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", - "dev": true - }, - "loader-utils": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", - "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^2.1.2" - } - }, - "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==", - "dev": true, - "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.difference": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", - "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", - "dev": true - }, - "lodash.escaperegexp": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", - "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=" - }, - "lodash.isequal": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", - "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" - }, - "lodash.memoize": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", - "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", - "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==", - "dev": true - }, - "lodash.truncate": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", - "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", - "dev": true - }, - "lodash.uniq": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", - "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", - "dev": true - }, - "log-symbols": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", - "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "is-unicode-supported": "^0.1.0" - } - }, - "log-update": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", - "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", - "dev": true, - "requires": { - "ansi-escapes": "^4.3.0", - "cli-cursor": "^3.1.0", - "slice-ansi": "^4.0.0", - "wrap-ansi": "^6.2.0" - }, - "dependencies": { - "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, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } + "@types/body-parser": { + "version": "1.19.2", + "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.2.tgz", + "integrity": "sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g==", + "dev": true, + "requires": { + "@types/connect": "*", + "@types/node": "*" + } }, - "wrap-ansi": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", - "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - } - } - }, - "longest-streak": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", - "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", - "dev": true - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "loud-rejection": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", - "integrity": "sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ==", - "dev": true, - "requires": { - "currently-unhandled": "^0.4.1", - "signal-exit": "^3.0.0" - } - }, - "lower-case": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", - "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", - "dev": true, - "requires": { - "tslib": "^2.0.3" - } - }, - "lowercase-keys": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", - "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", - "dev": true - }, - "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", - "requires": { - "yallist": "^4.0.0" - } - }, - "lz-string": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", - "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=", - "dev": true - }, - "lzma-native": { - "version": "8.0.6", - "resolved": "https://registry.npmjs.org/lzma-native/-/lzma-native-8.0.6.tgz", - "integrity": "sha512-09xfg67mkL2Lz20PrrDeNYZxzeW7ADtpYFbwSQh9U8+76RIzx5QsJBMy8qikv3hbUPfpy6hqwxt6FcGK81g9AA==", - "dev": true, - "requires": { - "node-addon-api": "^3.1.0", - "node-gyp-build": "^4.2.1", - "readable-stream": "^3.6.0" - }, - "dependencies": { - "node-addon-api": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", - "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", - "dev": true + "@types/bonjour": { + "version": "3.5.10", + "resolved": "https://registry.npmjs.org/@types/bonjour/-/bonjour-3.5.10.tgz", + "integrity": "sha512-p7ienRMiS41Nu2/igbJxxLDWrSZ0WxM8UQgCeO9KhoVF7cOVFkrKsiDr1EsJIla8vV3oEEjGcz11jc5yimhzZw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/cacheable-request": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.2.tgz", + "integrity": "sha512-B3xVo+dlKM6nnKTcmm5ZtY/OL8bOAOd2Olee9M1zft65ox50OzjEHW91sDiU9j6cvW8Ejg1/Qkf4xd2kugApUA==", + "dev": true, + "requires": { + "@types/http-cache-semantics": "*", + "@types/keyv": "*", + "@types/node": "*", + "@types/responselike": "*" + } + }, + "@types/connect": { + "version": "3.4.35", + "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", + "integrity": "sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/connect-history-api-fallback": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.3.5.tgz", + "integrity": "sha512-h8QJa8xSb1WD4fpKBDcATDNGXghFj6/3GRWG6dhmRcu0RX1Ubasur2Uvx5aeEwlf0MwblEC2bMzzMQntxnw/Cw==", + "dev": true, + "requires": { + "@types/express-serve-static-core": "*", + "@types/node": "*" + } + }, + "@types/debug": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.7.tgz", + "integrity": "sha512-9AonUzyTjXXhEOa0DnqpzZi6VHlqKMswga9EXjpXnnqxwLtdvPPtlO8evrI5D9S6asFRCQ6v+wpiUKbw+vKqyg==", + "dev": true, + "requires": { + "@types/ms": "*" + } + }, + "@types/electron-localshortcut": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/@types/electron-localshortcut/-/electron-localshortcut-3.1.0.tgz", + "integrity": "sha512-upKSXMxBPRdz5kmcXfdfn+hWH9PCAvwhyVozDXTIwwHQ1lUJcdSgGUfxOC1QBlnAPKPqcW/r4icWfMosKz8ibg==", + "dev": true, + "requires": { + "electron": "*" + } + }, + "@types/eslint": { + "version": "8.4.2", + "resolved": "https://registry.npmjs.org/@types/eslint/-/eslint-8.4.2.tgz", + "integrity": "sha512-Z1nseZON+GEnFjJc04sv4NSALGjhFwy6K0HXt7qsn5ArfAKtb63dXNJHf+1YW6IpOIYRBGUbu3GwJdj8DGnCjA==", + "dev": true, + "requires": { + "@types/estree": "*", + "@types/json-schema": "*" + } + }, + "@types/eslint-scope": { + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/@types/eslint-scope/-/eslint-scope-3.7.3.tgz", + "integrity": "sha512-PB3ldyrcnAicT35TWPs5IcwKD8S333HMaa2VVv4+wdvebJkjWuW/xESoB8IwRcog8HYVYamb1g/R31Qv5Bx03g==", + "dev": true, + "requires": { + "@types/eslint": "*", + "@types/estree": "*" + } + }, + "@types/estree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.1.tgz", + "integrity": "sha512-LG4opVs2ANWZ1TJoKc937iMmNstM/d0ae1vNbnBvBhqCSezgVUOzcLCqbI5elV8Vy6WKwKjaqR+zO9VKirBBCA==", + "dev": true + }, + "@types/express": { + "version": "4.17.13", + "resolved": "https://registry.npmjs.org/@types/express/-/express-4.17.13.tgz", + "integrity": "sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA==", + "dev": true, + "requires": { + "@types/body-parser": "*", + "@types/express-serve-static-core": "^4.17.18", + "@types/qs": "*", + "@types/serve-static": "*" + } + }, + "@types/express-serve-static-core": { + "version": "4.17.28", + "resolved": "https://registry.npmjs.org/@types/express-serve-static-core/-/express-serve-static-core-4.17.28.tgz", + "integrity": "sha512-P1BJAEAW3E2DJUlkgq4tOL3RyMunoWXqbSCygWo5ZIWTjUgN1YnaXWW4VWl/oc8vs/XoYibEGBKP0uZyF4AHig==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/qs": "*", + "@types/range-parser": "*" + } + }, + "@types/fs-extra": { + "version": "9.0.13", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-9.0.13.tgz", + "integrity": "sha512-nEnwB++1u5lVDM2UI4c1+5R+FYaKfaAzS4OococimjVm3nQw3TuzH5UNsocrcTBbhnerblyHj4A49qXbIiZdpA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@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, + "requires": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@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/hoist-non-react-statics": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz", + "integrity": "sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==", + "dev": true, + "requires": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, + "@types/html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/@types/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-oh/6byDPnL1zeNXFrDXFLyZjkr1MsBG667IM792caf1L2UPOOMf65NFzjUH/ltyfwjAGfs1rsX1eftK0jC/KIg==", + "dev": true + }, + "@types/http-cache-semantics": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.1.tgz", + "integrity": "sha512-SZs7ekbP8CN0txVG2xVRH6EgKmEm31BOxA07vkFaETzZz1xh+cbt8BcI0slpymvwhx5dlFnQG2rTlPVQn+iRPQ==", + "dev": true + }, + "@types/http-proxy": { + "version": "1.17.8", + "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.8.tgz", + "integrity": "sha512-5kPLG5BKpWYkw/LVOGWpiq3nEVqxiN32rTgI53Sk12/xHFQ2rG3ehI9IO+O3W2QoKeyB92dJkoka8SUm6BX1pA==", + "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/jest": { + "version": "27.4.1", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-27.4.1.tgz", + "integrity": "sha512-23iPJADSmicDVrWk+HT58LMJtzLAnB2AgIzplQuq/bSrGaxCrlvRFjGbXmamnnk/mAmCdLStiGqggu28ocUyiw==", + "dev": true, + "requires": { + "jest-matcher-utils": "^27.0.0", + "pretty-format": "^27.0.0" + } + }, + "@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/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha1-7ihweulOEdK4J7y+UnC86n8+ce4=", + "dev": true + }, + "@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/lodash": { + "version": "4.14.188", + "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.188.tgz", + "integrity": "sha512-zmEmF5OIM3rb7SbLCFYoQhO4dGt2FRM9AMkxvA3LaADOF1n8in/zGJlWji9fmafLoNyz+FoL6FE0SLtGIArD7w==", + "dev": true + }, + "@types/md5": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/@types/md5/-/md5-2.3.2.tgz", + "integrity": "sha512-v+JFDu96+UYJ3/UWzB0mEglIS//MZXgRaJ4ubUPwOM0gvLc/kcQ3TWNYwENEK7/EcXGQVrW8h/XqednSjBd/Og==", + "dev": true + }, + "@types/mime": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/@types/mime/-/mime-1.3.2.tgz", + "integrity": "sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw==", + "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/ms": { + "version": "0.7.31", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", + "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==", + "dev": true + }, + "@types/node": { + "version": "17.0.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", + "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==", + "dev": true + }, + "@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==" + }, + "@types/plist": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/plist/-/plist-3.0.2.tgz", + "integrity": "sha512-ULqvZNGMv0zRFvqn8/4LSPtnmN4MfhlPNtJCTpKuIIxGVGZ2rYWzFXrvEBoh9CVyqSE7D6YFRJ1hydLHI6kbWw==", + "dev": true, + "optional": true, + "requires": { + "@types/node": "*", + "xmlbuilder": ">=11.0.1" + } + }, + "@types/prettier": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/@types/prettier/-/prettier-2.6.3.tgz", + "integrity": "sha512-ymZk3LEC/fsut+/Q5qejp6R9O1rMxz3XaRHDV6kX8MrGAhOSPqVARbDi+EZvInBpw+BnCX3TD240byVkOfQsHg==", + "dev": true + }, + "@types/prop-types": { + "version": "15.7.4", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.4.tgz", + "integrity": "sha512-rZ5drC/jWjrArrS8BR6SIr4cWpW09RNTYt9AMZo3Jwwif+iacXAqgVjm0B0Bv/S1jhDXKHqRVNCbACkJ89RAnQ==", + "devOptional": true + }, + "@types/qs": { + "version": "6.9.7", + "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", + "integrity": "sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw==", + "dev": true + }, + "@types/range-parser": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/@types/range-parser/-/range-parser-1.2.4.tgz", + "integrity": "sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw==", + "dev": true + }, + "@types/react": { + "version": "18.0.26", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.0.26.tgz", + "integrity": "sha512-hCR3PJQsAIXyxhTNSiDFY//LhnMZWpNNr5etoCqx/iUfGc5gXWtQR2Phl908jVR6uPXacojQWTg4qRpkxTuGug==", + "devOptional": true, + "requires": { + "@types/prop-types": "*", + "@types/scheduler": "*", + "csstype": "^3.0.2" + } + }, + "@types/react-dom": { + "version": "18.0.9", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-18.0.9.tgz", + "integrity": "sha512-qnVvHxASt/H7i+XG1U1xMiY5t+IHcPGUK7TDMDzom08xa7e86eCeKOiLZezwCKVxJn6NEiiy2ekgX8aQssjIKg==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, + "@types/react-test-renderer": { + "version": "17.0.1", + "resolved": "https://registry.npmjs.org/@types/react-test-renderer/-/react-test-renderer-17.0.1.tgz", + "integrity": "sha512-3Fi2O6Zzq/f3QR9dRnlnHso9bMl7weKCviFmfF6B4LS1Uat6Hkm15k0ZAQuDz+UBq6B3+g+NM6IT2nr5QgPzCw==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, + "@types/react-virtualized-auto-sizer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@types/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.1.tgz", + "integrity": "sha512-GH8sAnBEM5GV9LTeiz56r4ZhMOUSrP43tAQNSRVxNexDjcNKLCEtnxusAItg1owFUFE6k0NslV26gqVClVvong==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, + "@types/react-window": { + "version": "1.8.5", + "resolved": "https://registry.npmjs.org/@types/react-window/-/react-window-1.8.5.tgz", + "integrity": "sha512-V9q3CvhC9Jk9bWBOysPGaWy/Z0lxYcTXLtLipkt2cnRj1JOSFNF7wqGpkScSXMgBwC+fnVRg/7shwgddBG5ICw==", + "dev": true, + "requires": { + "@types/react": "*" + } + }, + "@types/react-window-infinite-loader": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/@types/react-window-infinite-loader/-/react-window-infinite-loader-1.0.6.tgz", + "integrity": "sha512-V8g8sBDLVeJJAfEENJS7VXZK+DRJ+jzPNtk8jpj2G+obhf+iqGNUDGwNWCbBhLiD+KpHhf3kWQlKBRi0tAeU4Q==", + "dev": true, + "requires": { + "@types/react": "*", + "@types/react-window": "*" + } + }, + "@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/retry": { + "version": "0.12.1", + "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.1.tgz", + "integrity": "sha512-xoDlM2S4ortawSWORYqsdU+2rxdh4LRW9ytc3zmT37RIKQh6IHyKwwtKhKis9ah8ol07DCkZxPt8BBvPjC6v4g==", + "dev": true + }, + "@types/scheduler": { + "version": "0.16.2", + "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", + "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==", + "devOptional": true + }, + "@types/semver": { + "version": "7.3.13", + "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.3.13.tgz", + "integrity": "sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==" + }, + "@types/serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/@types/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha512-d/Hs3nWDxNL2xAczmOVZNj92YZCS6RGxfBPjKzuu/XirCgXdpKEb88dYNbrYGint6IVWLNP+yonwVAuRC0T2Dg==", + "dev": true, + "requires": { + "@types/express": "*" + } + }, + "@types/serve-static": { + "version": "1.13.10", + "resolved": "https://registry.npmjs.org/@types/serve-static/-/serve-static-1.13.10.tgz", + "integrity": "sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ==", + "dev": true, + "requires": { + "@types/mime": "^1", + "@types/node": "*" + } + }, + "@types/sockjs": { + "version": "0.3.33", + "resolved": "https://registry.npmjs.org/@types/sockjs/-/sockjs-0.3.33.tgz", + "integrity": "sha512-f0KEEe05NvUnat+boPTZ0dgaLZ4SfSouXUgv5noUiefG2ajgKjmETo9ZJyuqsl7dfl2aHlLJUiki6B4ZYldiiw==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@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/styled-components": { + "version": "5.1.26", + "resolved": "https://registry.npmjs.org/@types/styled-components/-/styled-components-5.1.26.tgz", + "integrity": "sha512-KuKJ9Z6xb93uJiIyxo/+ksS7yLjS1KzG6iv5i78dhVg/X3u5t1H7juRWqVmodIdz6wGVaIApo1u01kmFRdJHVw==", + "dev": true, + "requires": { + "@types/hoist-non-react-statics": "*", + "@types/react": "*", + "csstype": "^3.0.2" + } + }, + "@types/symlink-or-copy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/symlink-or-copy/-/symlink-or-copy-1.2.0.tgz", + "integrity": "sha512-Lja2xYuuf2B3knEsga8ShbOdsfNOtzT73GyJmZyY7eGl2+ajOqrs8yM5ze0fsSoYwvA6bw7/Qr7OZ7PEEmYwWg==", + "dev": true + }, + "@types/terser-webpack-plugin": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/@types/terser-webpack-plugin/-/terser-webpack-plugin-5.2.0.tgz", + "integrity": "sha512-iHDR2pRfFjGyDqCALX2tgUgFtGoQf2AJhKpC2XD1IMBQVJF2bny6WChGRDKj9eaZJl4F2RmvBhxJNtVPj7aTRw==", + "dev": true, + "requires": { + "terser-webpack-plugin": "*" + } + }, + "@types/testing-library__jest-dom": { + "version": "5.14.3", + "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.14.3.tgz", + "integrity": "sha512-oKZe+Mf4ioWlMuzVBaXQ9WDnEm1+umLx0InILg+yvZVBBDmzV5KfZyLrCvadtWcx8+916jLmHafcmqqffl+iIw==", + "dev": true, + "requires": { + "@types/jest": "*" + } + }, + "@types/unist": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.6.tgz", + "integrity": "sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==", + "dev": true + }, + "@types/verror": { + "version": "1.10.6", + "resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.6.tgz", + "integrity": "sha512-NNm+gdePAX1VGvPcGZCDKQZKYSiAWigKhKaz5KF94hG6f2s8de9Ow5+7AbXoeKxL8gavZfk4UquSAygOF2duEQ==", + "dev": true, + "optional": true + }, + "@types/vfile": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/@types/vfile/-/vfile-3.0.2.tgz", + "integrity": "sha512-b3nLFGaGkJ9rzOcuXRfHkZMdjsawuDD0ENL9fzTophtBg8FJHSGbH7daXkEpcwy3v7Xol3pAvsmlYyFhR4pqJw==", + "dev": true, + "requires": { + "@types/node": "*", + "@types/unist": "*", + "@types/vfile-message": "*" + } + }, + "@types/vfile-message": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/vfile-message/-/vfile-message-2.0.0.tgz", + "integrity": "sha512-GpTIuDpb9u4zIO165fUy9+fXcULdD8HFRNli04GehoMVbeNq7D6OBnqSmg3lxZnC+UvgUhEWKxdKiwYUkGltIw==", + "dev": true, + "requires": { + "vfile-message": "*" + } + }, + "@types/webpack-bundle-analyzer": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/@types/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.4.1.tgz", + "integrity": "sha512-yQAj3l7bIYL+QRRlNJt6gyP+zrXZOlgaR4wsX0WY4yzZIbv41ZibREfZvuYjxY0iVtvQQlbhx0AeokkCuqUAQg==", + "dev": true, + "requires": { + "@types/node": "*", + "tapable": "^2.2.0", + "webpack": "^5" + } + }, + "@types/webpack-env": { + "version": "1.16.3", + "resolved": "https://registry.npmjs.org/@types/webpack-env/-/webpack-env-1.16.3.tgz", + "integrity": "sha512-9gtOPPkfyNoEqCQgx4qJKkuNm/x0R2hKR7fdl7zvTJyHnIisuE/LfvXOsYWL0o3qq6uiBnKZNNNzi3l0y/X+xw==", + "dev": true + }, + "@types/ws": { + "version": "8.5.3", + "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.3.tgz", + "integrity": "sha512-6YOoWjruKj1uLf3INHH7D3qTXwFfEsg1kf3c0uDdSBJwfa/llkwIjrAGV7j7mVgGNbzTQ3HiHKKDXl6bJPD97w==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, + "@types/yargs": { + "version": "17.0.24", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz", + "integrity": "sha512-6i0aC7jV6QzQB8ne1joVZ0eSFIstHsCrobmOtghM11yGlH0j43FKL2UhWdELkyps0zuf7qVTUVCCR+tgSlyLLw==", + "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 + }, + "@types/yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-Cn6WYCm0tXv8p6k+A8PvbDG763EDpBoTzHdA+Q/MF6H3sapGjCm9NzoaJncJS9tUKSuCoDs9XHxYYsQDgxR6kw==", + "dev": true, + "optional": true, + "requires": { + "@types/node": "*" + } + }, + "@typescript-eslint/eslint-plugin": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.47.1.tgz", + "integrity": "sha512-r4RZ2Jl9kcQN7K/dcOT+J7NAimbiis4sSM9spvWimsBvDegMhKLA5vri2jG19PmIPbDjPeWzfUPQ2hjEzA4Nmg==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.47.1", + "@typescript-eslint/type-utils": "5.47.1", + "@typescript-eslint/utils": "5.47.1", + "debug": "^4.3.4", + "ignore": "^5.2.0", + "natural-compare-lite": "^1.4.0", + "regexpp": "^3.2.0", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/experimental-utils": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", + "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.7", + "@typescript-eslint/scope-manager": "4.33.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/typescript-estree": "4.33.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + }, + "dependencies": { + "@typescript-eslint/scope-manager": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", + "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0" + } + }, + "@typescript-eslint/types": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", + "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", + "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", + "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.33.0", + "eslint-visitor-keys": "^2.0.0" + } + }, + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + } + } + }, + "@typescript-eslint/parser": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.47.1.tgz", + "integrity": "sha512-9Vb+KIv29r6GPu4EboWOnQM7T+UjpjXvjCPhNORlgm40a9Ia9bvaPJswvtae1gip2QEeVeGh6YquqAzEgoRAlw==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "5.47.1", + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/typescript-estree": "5.47.1", + "debug": "^4.3.4" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.47.1.tgz", + "integrity": "sha512-9hsFDsgUwrdOoW1D97Ewog7DYSHaq4WKuNs0LHF9RiCmqB0Z+XRR4Pf7u7u9z/8CciHuJ6yxNws1XznI3ddjEw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/visitor-keys": "5.47.1" + } + }, + "@typescript-eslint/type-utils": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.47.1.tgz", + "integrity": "sha512-/UKOeo8ee80A7/GJA427oIrBi/Gd4osk/3auBUg4Rn9EahFpevVV1mUK8hjyQD5lHPqX397x6CwOk5WGh1E/1w==", + "dev": true, + "requires": { + "@typescript-eslint/typescript-estree": "5.47.1", + "@typescript-eslint/utils": "5.47.1", + "debug": "^4.3.4", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/types": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.47.1.tgz", + "integrity": "sha512-CmALY9YWXEpwuu6377ybJBZdtSAnzXLSQcxLSqSQSbC7VfpMu/HLVdrnVJj7ycI138EHqocW02LPJErE35cE9A==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.47.1.tgz", + "integrity": "sha512-4+ZhFSuISAvRi2xUszEj0xXbNTHceV9GbH9S8oAD2a/F9SW57aJNQVOCxG8GPfSWH/X4eOPdMEU2jYVuWKEpWA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/visitor-keys": "5.47.1", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/utils": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.47.1.tgz", + "integrity": "sha512-l90SdwqfmkuIVaREZ2ykEfCezepCLxzWMo5gVfcJsJCaT4jHT+QjgSkYhs5BMQmWqE9k3AtIfk4g211z/sTMVw==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@types/semver": "^7.3.12", + "@typescript-eslint/scope-manager": "5.47.1", + "@typescript-eslint/types": "5.47.1", + "@typescript-eslint/typescript-estree": "5.47.1", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0", + "semver": "^7.3.7" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.47.1", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.47.1.tgz", + "integrity": "sha512-rF3pmut2JCCjh6BLRhNKdYjULMb1brvoaiWDlHfLNVgmnZ0sBVJrs3SyaKE1XoDDnJuAx/hDQryHYmPUuNq0ig==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.47.1", + "eslint-visitor-keys": "^3.3.0" + } + }, + "@webassemblyjs/ast": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", + "integrity": "sha512-IN1xI7PwOvLPgjcf180gC1bqn3q/QaOCwYUahIOhbYUu8KA/3tw2RT/T0Gidi1l7Hhj5D/INhJxiICObqpMu4Q==", + "dev": true, + "requires": { + "@webassemblyjs/helper-numbers": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.11.6.tgz", + "integrity": "sha512-ejAj9hfRJ2XMsNHk/v6Fu2dGS+i4UaXBXGemOfQ/JfQ6mdQg/WXtwleQRLLS4OvfDhv8rYnVwH27YJLMyYsxhw==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.11.6.tgz", + "integrity": "sha512-o0YkoP4pVu4rN8aTJgAyj9hC2Sv5UlkzCHhxqWj8butaLvnpdc2jOwh4ewE6CX0txSfLn/UYaV/pheS2Txg//Q==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.11.6.tgz", + "integrity": "sha512-z3nFzdcp1mb8nEOFFk8DrYLpHvhKC3grJD2ardfKOzmbmJvEf/tPIqCY+sNcwZIY8ZD7IkB2l7/pqhUhqm7hLA==", + "dev": true + }, + "@webassemblyjs/helper-numbers": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.11.6.tgz", + "integrity": "sha512-vUIhZ8LZoIWHBohiEObxVm6hwP034jwmc9kuq5GdHZH0wiLVLIPcMCdpJzG4C11cHoQ25TFIQj9kaVADVX7N3g==", + "dev": true, + "requires": { + "@webassemblyjs/floating-point-hex-parser": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.11.6.tgz", + "integrity": "sha512-sFFHKwcmBprO9e7Icf0+gddyWYDViL8bpPjJJl0WHxCdETktXdmtWLGVzoHbqUcY4Be1LkNfwTmXOJUFZYSJdA==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.11.6.tgz", + "integrity": "sha512-LPpZbSOwTpEC2cgn4hTydySy1Ke+XEu+ETXuoyvuyezHO3Kjdu90KK95Sh9xTbmjrCsUwvWwCOQQNta37VrS9g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.11.6.tgz", + "integrity": "sha512-LM4p2csPNvbij6U1f19v6WR56QZ8JcHg3QIJTlSwzFcmx6WSORicYj6I63f9yU1kEUtrpG+kjkiIAkevHpDXrg==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.11.6.tgz", + "integrity": "sha512-m7a0FhE67DQXgouf1tbN5XQcdWoNgaAuoULHIfGFIEVKA6tu/edls6XnIlkmS6FrXAquJRPni3ZZKjw6FSPjPQ==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.11.6.tgz", + "integrity": "sha512-vtXf2wTQ3+up9Zsg8sa2yWiQpzSsMyXj0qViVP6xKGCUT8p8YJ6HqI7l5eCnWx1T/FYdsv07HQs2wTFbbof/RA==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.11.6.tgz", + "integrity": "sha512-Ybn2I6fnfIGuCR+Faaz7YcvtBKxvoLV3Lebn1tM4o/IAJzmi9AWYIPWpyBfU8cC+JxAO57bk4+zdsTjJR+VTOw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/helper-wasm-section": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-opt": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6", + "@webassemblyjs/wast-printer": "1.11.6" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.11.6.tgz", + "integrity": "sha512-3XOqkZP/y6B4F0PBAXvI1/bky7GryoogUtfwExeP/v7Nzwo1QLcq5oQmpKlftZLbT+ERUOAZVQjuNVak6UXjPA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.11.6.tgz", + "integrity": "sha512-cOrKuLRE7PCe6AsOVl7WasYf3wbSo4CeOk6PkrjS7g57MFfVUF9u6ysQBBODX0LdgSvQqRiGz3CXvIDKcPNy4g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-buffer": "1.11.6", + "@webassemblyjs/wasm-gen": "1.11.6", + "@webassemblyjs/wasm-parser": "1.11.6" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.11.6.tgz", + "integrity": "sha512-6ZwPeGzMJM3Dqp3hCsLgESxBGtT/OeCvCZ4TA1JUPYgmhAx38tTPR9JaKy0S5H3evQpO/h2uWs2j6Yc/fjkpTQ==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@webassemblyjs/helper-api-error": "1.11.6", + "@webassemblyjs/helper-wasm-bytecode": "1.11.6", + "@webassemblyjs/ieee754": "1.11.6", + "@webassemblyjs/leb128": "1.11.6", + "@webassemblyjs/utf8": "1.11.6" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.11.6.tgz", + "integrity": "sha512-JM7AhRcE+yW2GWYaKeHL5vt4xqee5N2WcezptmgyhNS+ScggqcT1OtXykhAb13Sn5Yas0j2uv9tHgrjwvzAP4A==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.11.6", + "@xtuc/long": "4.2.2" + } + }, + "@webpack-cli/configtest": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.1.tgz", + "integrity": "sha512-1FBc1f9G4P/AxMqIgfZgeOTuRnwZMten8E7zap5zgpPInnCrP8D4Q81+4CWIch8i/Nf7nXjP0v6CjjbHOrXhKg==", + "dev": true, + "requires": {} + }, + "@webpack-cli/info": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.4.1.tgz", + "integrity": "sha512-PKVGmazEq3oAo46Q63tpMr4HipI3OPfP7LiNOEJg963RMgT0rqheag28NCML0o3GIzA3DmxP1ZIAv9oTX1CUIA==", + "dev": true, + "requires": { + "envinfo": "^7.7.3" + } + }, + "@webpack-cli/serve": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.1.tgz", + "integrity": "sha512-gNGTiTrjEVQ0OcVnzsRSqTxaBSr+dmTfm+qJsCDluky8uhdLWep7Gcr62QsAKHTMxjCS/8nEITsmFAhfIx+QSw==", + "dev": true, + "requires": {} + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "7zip-bin": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/7zip-bin/-/7zip-bin-5.1.1.tgz", + "integrity": "sha512-sAP4LldeWNz0lNzmTird3uWfFDWWTeg6V/MsmyyLR9X1idwKBWIgt/ZvinqQldJm3LecKEs1emkbquO6PCiLVQ==", + "dev": true + }, + "abab": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/abab/-/abab-2.0.5.tgz", + "integrity": "sha512-9IK9EadsbHo6jLWIpxpR6pL0sazTXV6+SQv25ZB+F7Bj9mJNaOc4nCRabwd5M/JwmUa8idz6Eci6eKfJryPs6Q==", + "dev": true + }, + "abbrev": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz", + "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", + "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==", + "dev": true, + "requires": { + "mime-types": "~2.1.34", + "negotiator": "0.6.3" + } + }, + "acorn": { + "version": "8.8.2", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.8.2.tgz", + "integrity": "sha512-xjIYgE8HBrkpd/sJqOGNspf8uHG+NOHGOw6a/Urj8taM2EXfdNAH2oFcPeIFfsv3+kz/mJrS5VuMqbNLjCa2vw==", + "dev": true + }, + "acorn-globals": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/acorn-globals/-/acorn-globals-6.0.0.tgz", + "integrity": "sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + } + } + }, + "acorn-import-assertions": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/acorn-import-assertions/-/acorn-import-assertions-1.9.0.tgz", + "integrity": "sha512-cmMwop9x+8KFhxvKrKfPYmN6/pKTYYHBqLa0DfvVZcKMJWNyWLnaqND7dx/qn66R7ewM1UX5XMaDVP5wlVTaVA==", + "dev": true, + "requires": {} + }, + "acorn-jsx": { + "version": "5.3.2", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", + "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", + "dev": true, + "requires": {} + }, + "acorn-walk": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.2.0.tgz", + "integrity": "sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==", + "dev": true + }, + "address": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/address/-/address-1.1.2.tgz", + "integrity": "sha512-aT6camzM4xEA54YVJYSqxz1kv4IHnQZRtThJJHhUMRExaU5spC7jX5ugSwTaTgJliIgs4VhZOk7htClvQ/LmRA==", + "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" + } + }, + "agentkeepalive": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.2.1.tgz", + "integrity": "sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "depd": "^1.1.2", + "humanize-ms": "^1.2.1" + } + }, + "aggregate-error": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz", + "integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "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" - }, - "dependencies": { - "semver": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", - "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", - "dev": true - } - } - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "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-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", - "dev": true - }, - "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 - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "markdown-escapes": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", - "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", - "dev": true - }, - "markdown-table": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", - "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", - "dev": true - }, - "matcher": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", - "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", - "dev": true, - "optional": true, - "requires": { - "escape-string-regexp": "^4.0.0" - } - }, - "matcher-collection": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/matcher-collection/-/matcher-collection-2.0.1.tgz", - "integrity": "sha512-daE62nS2ZQsDg9raM0IlZzLmI2u+7ZapXBwdoeBUKAYERPDDIc0qNqA8E0Rp2D+gspKR7BgIFP52GeujaGXWeQ==", - "dev": true, - "requires": { - "@types/minimatch": "^3.0.3", - "minimatch": "^3.0.2" - } - }, - "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" - } - }, - "mdast-util-compact": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.4.tgz", - "integrity": "sha512-3YDMQHI5vRiS2uygEFYaqckibpJtKq5Sj2c8JioeOQBU6INpKbdWzfyLqFFnDwEcEnRFIdMsguzs5pC1Jp4Isg==", - "dev": true, - "requires": { - "unist-util-visit": "^1.1.0" - } - }, - "mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", - "dev": true - }, - "media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", - "dev": true - }, - "memfs": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.1.tgz", - "integrity": "sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==", - "dev": true, - "requires": { - "fs-monkey": "1.0.3" - } - }, - "memoize-one": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", - "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" - }, - "memory-fs": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz", - "integrity": "sha1-8rslNovBIeORwlIN6Slpyu4KApA=", - "dev": true - }, - "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": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", - "dev": true - }, - "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": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", - "dev": true - }, - "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": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "dev": true - }, - "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==" - }, - "mimic-response": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", - "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", - "dev": 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 - }, - "mini-css-extract-plugin": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.0.tgz", - "integrity": "sha512-ndG8nxCEnAemsg4FSgS+yNyHKgkTB4nPKqCOgh65j3/30qqC5RaSQQXMm++Y6sb6E1zRSxPkztj9fqxhS1Eo6w==", - "dev": true, - "requires": { - "schema-utils": "^4.0.0" - }, - "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" - } + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "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" + } + }, + "ajv-formats": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz", + "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==", + "requires": { + "ajv": "^8.0.0" + }, + "dependencies": { + "ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "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==" + } + } }, "ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.3" - } + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", + "integrity": "sha512-5p6WTN0DdTGVQk6VjcEju19IgaHudalcfabD7yhDGeA6bcQnmL+CpveLJq/3hvfwd1aof6L386Ougkx6RfyMIQ==", + "dev": true, + "requires": {} }, - "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 - }, - "schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - } - } - } - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimatch": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", - "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", - "dev": true, - "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==", - "dev": 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": { - "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 - } - } - }, - "minipass": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", - "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", - "dev": true, - "requires": { - "yallist": "^4.0.0" - } - }, - "minipass-collect": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", - "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-flush": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", - "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-pipeline": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", - "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minipass-sized": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", - "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", - "dev": true, - "requires": { - "minipass": "^3.0.0" - } - }, - "minizlib": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", - "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", - "dev": true, - "requires": { - "minipass": "^3.0.0", - "yallist": "^4.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - } - }, - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "requires": { - "minimist": "^1.2.6" - } - }, - "mktemp": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/mktemp/-/mktemp-0.4.0.tgz", - "integrity": "sha1-bQUVYRyKjITkhKogABKbmOmB/ws=", - "dev": true - }, - "mrmime": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.0.tgz", - "integrity": "sha512-a70zx7zFfVO7XpnQ2IX1Myh9yY4UYvfld/dikWRnsXxbyvMcfz+u6UfgNAtH+k2QqtJuzVpv6eLTx1G2+WKZbQ==", - "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==" - }, - "multicast-dns": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.4.tgz", - "integrity": "sha512-XkCYOU+rr2Ft3LI6w4ye51M3VK31qJXFIxu0XLw169PtKG0Zx47OrXeVW/GCYOfpC9s1yyyf1S+L8/4LY0J9Zw==", - "dev": true, - "requires": { - "dns-packet": "^5.2.2", - "thunky": "^1.0.2" - } - }, - "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "natural-compare": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", - "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", - "dev": true - }, - "natural-compare-lite": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", - "integrity": "sha1-F7CVgZiJef3a/gIB6TG6kzyWy7Q=", - "dev": true - }, - "negotiator": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", - "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", - "dev": true - }, - "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==", - "dev": true - }, - "net": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/net/-/net-1.0.2.tgz", - "integrity": "sha512-kbhcj2SVVR4caaVnGLJKmlk2+f+oLkjqdKeQlmUtz6nGzOpbcobwVIeSURNgraV/v3tlmGIX82OcPCl0K6RbHQ==" - }, - "no-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", - "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", - "dev": true, - "requires": { - "lower-case": "^2.0.2", - "tslib": "^2.0.3" - } - }, - "node-abi": { - "version": "3.33.0", - "resolved": "https://registry.yarnpkg.com/node-abi/-/node-abi-3.33.0.tgz#8b23a0cec84e1c5f5411836de6a9b84bccf26e7f", - "integrity": "sha512-7GGVawqyHF4pfd0YFybhv/eM9JwTtPqx0mAanQ146O3FlSh3pA24zf9IRQTOsfTSqXTNzPSP5iagAJ94jjuVog==", - "dev": true, - "requires": { - "semver": "^7.3.5" - } - }, - "node-addon-api": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", - "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", - "dev": true, - "optional": true - }, - "node-api-version": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.1.4.tgz", - "integrity": "sha512-KGXihXdUChwJAOHO53bv9/vXcLmdUsZ6jIptbvYvkpKfth+r7jw44JkVxQFA3kX5nQjzjmGu1uAu/xNNLNlI5g==", - "dev": true, - "requires": { - "semver": "^7.3.5" - } - }, - "node-forge": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", - "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", - "dev": true - }, - "node-gyp-build": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz", - "integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==", - "dev": true - }, - "node-int64": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", - "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", - "dev": true - }, - "node-mpv": { - "version": "git+ssh://git@github.com/jeffvli/Node-MPV.git#c7f84d7966b82e5916c3b4bb47cac667bb895c22", - "from": "node-mpv@github:jeffvli/Node-MPV" - }, - "node-releases": { - "version": "2.0.8", - "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", - "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==" - }, - "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" - } - }, - "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-range": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", - "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", - "dev": true - }, - "normalize-selector": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz", - "integrity": "sha512-dxvWdI8gw6eAvk9BlPffgEoGfM7AdijoCwOEJge3e3ulT2XLgmU7KvvxprOaCu05Q1uGRHmOhHe1r6emZoKyFw==", - "dev": true - }, - "normalize-url": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", - "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", - "dev": true - }, - "now-and-later": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", - "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", - "dev": true, - "requires": { - "once": "^1.3.2" - } - }, - "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" - } - }, - "npmlog": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.1.tgz", - "integrity": "sha512-BTHDvY6nrRHuRfyjt1MAufLxYdVXZfd099H4+i1f0lPywNQyI4foeNXJRObB/uy+TYqUW0vAD9gbdSOXPst7Eg==", - "dev": true, - "requires": { - "are-we-there-yet": "^3.0.0", - "console-control-strings": "^1.1.0", - "gauge": "^4.0.0", - "set-blocking": "^2.0.0" - } - }, - "nth-check": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", - "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", - "dev": true, - "requires": { - "boolbase": "^1.0.0" - } - }, - "num2fraction": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", - "integrity": "sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==", - "dev": true - }, - "nwsapi": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", - "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", - "dev": true - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-inspect": { - "version": "1.12.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", - "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", - "dev": true - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.assign": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", - "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "has-symbols": "^1.0.3", - "object-keys": "^1.1.1" - } - }, - "object.entries": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", - "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "object.fromentries": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", - "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "object.hasown": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", - "integrity": "sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==", - "dev": true, - "requires": { - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "object.values": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", - "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "obuf": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", - "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", - "dev": 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==", - "dev": true, - "requires": { - "ee-first": "1.1.1" - } - }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", - "requires": { - "mimic-fn": "^2.1.0" - } - }, - "open": { - "version": "8.4.0", - "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", - "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", - "dev": true, - "requires": { - "define-lazy-prop": "^2.0.0", - "is-docker": "^2.1.1", - "is-wsl": "^2.2.0" - } - }, - "opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", - "dev": true - }, - "optionator": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", - "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", - "dev": true, - "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" - } - }, - "ora": { - "version": "5.4.1", - "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", - "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", - "dev": true, - "requires": { - "bl": "^4.1.0", - "chalk": "^4.1.0", - "cli-cursor": "^3.1.0", - "cli-spinners": "^2.5.0", - "is-interactive": "^1.0.0", - "is-unicode-supported": "^0.1.0", - "log-symbols": "^4.1.0", - "strip-ansi": "^6.0.0", - "wcwidth": "^1.0.1" - } - }, - "ordered-read-streams": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", - "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", - "dev": true, - "requires": { - "readable-stream": "^2.0.1" - } - }, - "p-cancelable": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", - "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", - "dev": true - }, - "p-limit": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", - "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", - "dev": true, - "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==", - "dev": true, - "requires": { - "p-limit": "^3.0.2" - } - }, - "p-map": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", - "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", - "dev": true, - "requires": { - "aggregate-error": "^3.0.0" - } - }, - "p-retry": { - "version": "4.6.1", - "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.1.tgz", - "integrity": "sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA==", - "dev": true, - "requires": { - "@types/retry": "^0.12.0", - "retry": "^0.13.1" - }, - "dependencies": { - "retry": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", - "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", - "dev": true - } - } - }, - "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==" - }, - "pako": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", - "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", - "dev": true - }, - "param-case": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", - "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", - "dev": true, - "requires": { - "dot-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "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-entities": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", - "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==", - "dev": true, - "requires": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.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==", - "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": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", - "dev": true - }, - "parse5-htmlparser2-tree-adapter": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", - "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", - "dev": true, - "requires": { - "parse5": "^6.0.1" - } - }, - "parseurl": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", - "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true - }, - "pascal-case": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", - "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", - "dev": true, - "requires": { - "no-case": "^3.0.4", - "tslib": "^2.0.3" - } - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "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==", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", - "dev": true - }, - "path-key": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", - "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", - "dev": true - }, - "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==" - }, - "path-posix": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/path-posix/-/path-posix-1.0.0.tgz", - "integrity": "sha1-BrJhE/Vr6rBCVFojv6iAA8ysJg8=", - "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": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", - "dev": true - }, - "path-type": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", - "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" - }, - "pend": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", - "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", - "dev": true - }, - "picocolors": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", - "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" - }, - "picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" - }, - "pidtree": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.5.0.tgz", - "integrity": "sha512-9nxspIM7OpZuhBxPg73Zvyq7j1QMPMPsGKTqRc2XOaFQauDvoNz9fM1Wdkjmeo7l9GXOZiRs97sPkuayl39wjA==", - "dev": true - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": 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" - } - } - } - }, - "pkg-up": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", - "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", - "requires": { - "find-up": "^3.0.0" - }, - "dependencies": { - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "requires": { - "locate-path": "^3.0.0" - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "p-limit": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", - "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "requires": { - "p-limit": "^2.0.0" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==" - } - } - }, - "plist": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.6.tgz", - "integrity": "sha512-WiIVYyrp8TD4w8yCvyeIr+lkmrGRd5u0VbRnU+tP/aRLxP/YadJUYOMZJ/6hIa3oUyVCsycXvtNRgd5XBJIbiA==", - "dev": true, - "requires": { - "base64-js": "^1.5.1", - "xmlbuilder": "^15.1.1" - } - }, - "portfinder": { - "version": "1.0.28", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", - "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", - "dev": true, - "requires": { - "async": "^2.6.2", - "debug": "^3.1.1", - "mkdirp": "^0.5.5" - }, - "dependencies": { - "async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "dev": true, - "requires": { - "lodash": "^4.17.14" - } - }, - "debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - } - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", - "dev": true - }, - "postcss": { - "version": "8.4.20", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz", - "integrity": "sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==", - "dev": true, - "requires": { - "nanoid": "^3.3.4", - "picocolors": "^1.0.0", - "source-map-js": "^1.0.2" - } - }, - "postcss-calc": { - "version": "8.2.4", - "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", - "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", - "dev": true, - "requires": { - "postcss-selector-parser": "^6.0.9", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-colormin": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.0.tgz", - "integrity": "sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg==", - "dev": true, - "requires": { - "browserslist": "^4.16.6", - "caniuse-api": "^3.0.0", - "colord": "^2.9.1", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-convert-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.0.tgz", - "integrity": "sha512-GkyPbZEYJiWtQB0KZ0X6qusqFHUepguBCNFi9t5JJc7I2OTXG7C0twbTLvCfaKOLl3rSXmpAwV7W5txd91V84g==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-discard-comments": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.1.tgz", - "integrity": "sha512-5JscyFmvkUxz/5/+TB3QTTT9Gi9jHkcn8dcmmuN68JQcv3aQg4y88yEHHhwFB52l/NkaJ43O0dbksGMAo49nfQ==", - "dev": true, - "requires": {} - }, - "postcss-discard-duplicates": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", - "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", - "dev": true, - "requires": {} - }, - "postcss-discard-empty": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", - "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", - "dev": true, - "requires": {} - }, - "postcss-discard-overridden": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", - "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", - "dev": true, - "requires": {} - }, - "postcss-html": { - "version": "0.36.0", - "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-0.36.0.tgz", - "integrity": "sha512-HeiOxGcuwID0AFsNAL0ox3mW6MHH5cstWN1Z3Y+n6H+g12ih7LHdYxWwEA/QmrebctLjo79xz9ouK3MroHwOJw==", - "dev": true, - "requires": { - "htmlparser2": "^3.10.0" - }, - "dependencies": { - "dom-serializer": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", - "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", - "dev": true, - "requires": { - "domelementtype": "^2.0.1", - "entities": "^2.0.0" - }, - "dependencies": { - "domelementtype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", - "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", - "dev": true + "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" }, - "entities": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", - "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", - "dev": true + "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 + } } - } }, - "domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", - "dev": true - }, - "domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", - "dev": true, - "requires": { - "domelementtype": "1" - } - }, - "domutils": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", - "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", - "dev": true, - "requires": { - "dom-serializer": "0", - "domelementtype": "1" - } - }, - "entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", - "dev": true - }, - "htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "dev": true, - "requires": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" - } - }, - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "postcss-jsx": { - "version": "0.36.4", - "resolved": "https://registry.npmjs.org/postcss-jsx/-/postcss-jsx-0.36.4.tgz", - "integrity": "sha512-jwO/7qWUvYuWYnpOb0+4bIIgJt7003pgU3P6nETBLaOyBXuTD55ho21xnals5nBrlpTIFodyd3/jBi6UO3dHvA==", - "dev": true, - "requires": { - "@babel/core": ">=7.2.2" - } - }, - "postcss-less": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-3.1.4.tgz", - "integrity": "sha512-7TvleQWNM2QLcHqvudt3VYjULVB49uiW6XzEUFmvwHzvsOEF5MwBrIXZDJQvJNFGjJQTzSzZnDoCJ8h/ljyGXA==", - "dev": true, - "requires": { - "postcss": "^7.0.14" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.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 - } - } - }, - "postcss-markdown": { - "version": "0.36.0", - "resolved": "https://registry.npmjs.org/postcss-markdown/-/postcss-markdown-0.36.0.tgz", - "integrity": "sha512-rl7fs1r/LNSB2bWRhyZ+lM/0bwKv9fhl38/06gF6mKMo/NPnp55+K1dSTosSVjFZc0e1ppBlu+WT91ba0PMBfQ==", - "dev": true, - "requires": { - "remark": "^10.0.1", - "unist-util-find-all-after": "^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-merge-longhand": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.4.tgz", - "integrity": "sha512-hbqRRqYfmXoGpzYKeW0/NCZhvNyQIlQeWVSao5iKWdyx7skLvCfQFGIUsP9NUs3dSbPac2IC4Go85/zG+7MlmA==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0", - "stylehacks": "^5.1.0" - } - }, - "postcss-merge-rules": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.1.tgz", - "integrity": "sha512-8wv8q2cXjEuCcgpIB1Xx1pIy8/rhMPIQqYKNzEdyx37m6gpq83mQQdCxgIkFgliyEnKvdwJf/C61vN4tQDq4Ww==", - "dev": true, - "requires": { - "browserslist": "^4.16.6", - "caniuse-api": "^3.0.0", - "cssnano-utils": "^3.1.0", - "postcss-selector-parser": "^6.0.5" - } - }, - "postcss-minify-font-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", - "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-minify-gradients": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", - "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", - "dev": true, - "requires": { - "colord": "^2.9.1", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-minify-params": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.2.tgz", - "integrity": "sha512-aEP+p71S/urY48HWaRHasyx4WHQJyOYaKpQ6eXl8k0kxg66Wt/30VR6/woh8THgcpRbonJD5IeD+CzNhPi1L8g==", - "dev": true, - "requires": { - "browserslist": "^4.16.6", - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-minify-selectors": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.0.tgz", - "integrity": "sha512-vYxvHkW+iULstA+ctVNx0VoRAR4THQQRkG77o0oa4/mBS0OzGvvzLIvHDv/nNEM0crzN2WIyFU5X7wZhaUK3RA==", - "dev": true, - "requires": { - "postcss-selector-parser": "^6.0.5" - } - }, - "postcss-modules-extract-imports": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", - "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", - "dev": true, - "requires": {} - }, - "postcss-modules-local-by-default": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", - "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", - "dev": true, - "requires": { - "icss-utils": "^5.0.0", - "postcss-selector-parser": "^6.0.2", - "postcss-value-parser": "^4.1.0" - } - }, - "postcss-modules-scope": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", - "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", - "dev": true, - "requires": { - "postcss-selector-parser": "^6.0.4" - } - }, - "postcss-modules-values": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", - "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", - "dev": true, - "requires": { - "icss-utils": "^5.0.0" - } - }, - "postcss-normalize-charset": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", - "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", - "dev": true, - "requires": {} - }, - "postcss-normalize-display-values": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", - "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-positions": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.0.tgz", - "integrity": "sha512-8gmItgA4H5xiUxgN/3TVvXRoJxkAWLW6f/KKhdsH03atg0cB8ilXnrB5PpSshwVu/dD2ZsRFQcR1OEmSBDAgcQ==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-repeat-style": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.0.tgz", - "integrity": "sha512-IR3uBjc+7mcWGL6CtniKNQ4Rr5fTxwkaDHwMBDGGs1x9IVRkYIT/M4NelZWkAOBdV6v3Z9S46zqaKGlyzHSchw==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-string": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", - "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-timing-functions": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", - "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-unicode": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.0.tgz", - "integrity": "sha512-J6M3MizAAZ2dOdSjy2caayJLQT8E8K9XjLce8AUQMwOrCvjCHv24aLC/Lps1R1ylOfol5VIDMaM/Lo9NGlk1SQ==", - "dev": true, - "requires": { - "browserslist": "^4.16.6", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-url": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", - "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", - "dev": true, - "requires": { - "normalize-url": "^6.0.1", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-normalize-whitespace": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", - "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-ordered-values": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.1.tgz", - "integrity": "sha512-7lxgXF0NaoMIgyihL/2boNAEZKiW0+HkMhdKMTD93CjW8TdCy2hSdj8lsAo+uwm7EDG16Da2Jdmtqpedl0cMfw==", - "dev": true, - "requires": { - "cssnano-utils": "^3.1.0", - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-reduce-initial": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.0.tgz", - "integrity": "sha512-5OgTUviz0aeH6MtBjHfbr57tml13PuedK/Ecg8szzd4XRMbYxH4572JFG067z+FqBIf6Zp/d+0581glkvvWMFw==", - "dev": true, - "requires": { - "browserslist": "^4.16.6", - "caniuse-api": "^3.0.0" - } - }, - "postcss-reduce-transforms": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", - "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0" - } - }, - "postcss-reporter": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-6.0.1.tgz", - "integrity": "sha512-LpmQjfRWyabc+fRygxZjpRxfhRf9u/fdlKf4VHG4TSPbV2XNsuISzYW1KL+1aQzx53CAppa1bKG4APIB/DOXXw==", - "dev": true, - "requires": { - "chalk": "^2.4.1", - "lodash": "^4.17.11", - "log-symbols": "^2.2.0", - "postcss": "^7.0.7" - }, - "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 - }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "requires": { - "chalk": "^2.0.1" - } - }, - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.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 - }, - "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" - } - } - } - }, - "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-sass": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.3.5.tgz", - "integrity": "sha512-B5z2Kob4xBxFjcufFnhQ2HqJQ2y/Zs/ic5EZbCywCkxKd756Q40cIQ/veRDwSrw1BF6+4wUgmpm0sBASqVi65A==", - "dev": true, - "requires": { - "gonzales-pe": "^4.2.3", - "postcss": "^7.0.1" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.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 - } - } - }, - "postcss-scss": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.4.tgz", - "integrity": "sha512-aBBbVyzA8b3hUL0MGrpydxxXKXFZc5Eqva0Q3V9qsBOLEMsjb6w49WfpsoWzpEgcqJGW4t7Rio8WXVU9Gd8vWg==", - "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-sorting": { - "version": "7.0.1", - "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-7.0.1.tgz", - "integrity": "sha512-iLBFYz6VRYyLJEJsBJ8M3TCqNcckVzz4wFounSc5Oez35ogE/X+aoC5fFu103Ot7NyvjU3/xqIXn93Gp3kJk4g==", - "dev": true, - "requires": {} - }, - "postcss-svgo": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", - "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", - "dev": true, - "requires": { - "postcss-value-parser": "^4.2.0", - "svgo": "^2.7.0" - } - }, - "postcss-syntax": { - "version": "0.36.2", - "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz", - "integrity": "sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==", - "dev": true, - "requires": {} - }, - "postcss-unique-selectors": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", - "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", - "dev": true, - "requires": { - "postcss-selector-parser": "^6.0.5" - } - }, - "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==" - }, - "prelude-ls": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", - "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", - "dev": true - }, - "prettier": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz", - "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==", - "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-error": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", - "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", - "dev": true, - "requires": { - "lodash": "^4.17.20", - "renderkid": "^3.0.0" - } - }, - "pretty-format": { - "version": "27.5.1", - "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", - "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", - "dev": true, - "requires": { - "ansi-regex": "^5.0.1", - "ansi-styles": "^5.0.0", - "react-is": "^17.0.1" - }, - "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 - } - } - }, - "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==", - "dev": true - }, - "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "promise-map-series": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/promise-map-series/-/promise-map-series-0.3.0.tgz", - "integrity": "sha512-3npG2NGhTc8BWBolLLf8l/92OxMGaRLbqvIh9wjCHhDXNvk4zsxaTaCpiCunW09qWPrN2zeNSNwRLVBrQQtutA==", - "dev": true - }, - "promise-retry": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", - "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", - "dev": true, - "requires": { - "err-code": "^2.0.2", - "retry": "^0.12.0" - } - }, - "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" - } - }, - "prop-types": { - "version": "15.8.1", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", - "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.13.1" - }, - "dependencies": { - "react-is": { - "version": "16.13.1", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" - } - } - }, - "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==", - "dev": true, - "requires": { - "forwarded": "0.2.0", - "ipaddr.js": "1.9.1" - }, - "dependencies": { - "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==", - "dev": true - } - } - }, - "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.8.0", - "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", - "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", - "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==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": 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.10.3", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", - "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", - "dev": true, - "requires": { - "side-channel": "^1.0.4" - } - }, - "queue-microtask": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", - "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", - "dev": true - }, - "queue-tick": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", - "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", - "dev": true - }, - "quick-lru": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", - "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", - "dev": true - }, - "quick-temp": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/quick-temp/-/quick-temp-0.1.8.tgz", - "integrity": "sha1-urAqJCq4+w3XWKPJd2sy+aXZRAg=", - "dev": true, - "requires": { - "mktemp": "~0.4.0", - "rimraf": "^2.5.4", - "underscore.string": "~3.3.4" - }, - "dependencies": { - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "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==", - "dev": true - }, - "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==", - "dev": true, - "requires": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" - }, - "dependencies": { - "bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true - }, - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } - } - }, - "react": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", - "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", - "requires": { - "loose-envify": "^1.1.0" - } - }, - "react-dom": { - "version": "18.2.0", - "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", - "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", - "requires": { - "loose-envify": "^1.1.0", - "scheduler": "^0.23.0" - }, - "dependencies": { - "scheduler": { - "version": "0.23.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", - "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", - "requires": { - "loose-envify": "^1.1.0" - } - } - } - }, - "react-error-boundary": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz", - "integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==", - "requires": { - "@babel/runtime": "^7.12.5" - } - }, - "react-fast-compare": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", - "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" - }, - "react-i18next": { - "version": "11.16.7", - "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.16.7.tgz", - "integrity": "sha512-7yotILJLnKfvUfrl/nt9eK9vFpVFjZPLWAwBzWL6XppSZZEvlmlKk0GBGDCAPfLfs8oND7WAbry8wGzdoiW5Nw==", - "requires": { - "@babel/runtime": "^7.14.5", - "html-escaper": "^2.0.2", - "html-parse-stringify": "^3.0.1" - } - }, - "react-icons": { - "version": "4.8.0", - "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.8.0.tgz", - "integrity": "sha512-N6+kOLcihDiAnj5Czu637waJqSnwlMNROzVZMhfX68V/9bu9qHaMIJC4UdozWoOk57gahFCNHwVvWzm0MTzRjg==", - "requires": {} - }, - "react-is": { - "version": "17.0.2", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", - "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" - }, - "react-player": { - "version": "2.11.0", - "resolved": "https://registry.npmjs.org/react-player/-/react-player-2.11.0.tgz", - "integrity": "sha512-fIrwpuXOBXdEg1FiyV9isKevZOaaIsAAtZy5fcjkQK9Nhmk1I2NXzY/hkPos8V0zb/ZX416LFy8gv7l/1k3a5w==", - "requires": { - "deepmerge": "^4.0.0", - "load-script": "^1.0.0", - "memoize-one": "^5.1.1", - "prop-types": "^15.7.2", - "react-fast-compare": "^3.0.1" - }, - "dependencies": { - "memoize-one": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", - "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" - } - } - }, - "react-refresh": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.12.0.tgz", - "integrity": "sha512-suLIhrU2IHKL5JEKR/fAwJv7bbeq4kJ+pJopf77jHwuR+HmJS/HbrPIGsTBUVfw7tXPOmYv7UJ7PCaN49e8x4A==", - "dev": true - }, - "react-refresh-typescript": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/react-refresh-typescript/-/react-refresh-typescript-2.0.4.tgz", - "integrity": "sha512-ySsBExEFik5Jjf7NoXtFbzUk2rYWM4gF5gg+wRTNmp9p7B2uMpAAa339FHWqmB8EAr0e6mzzskAXxc0Jd04fBw==", - "dev": true, - "requires": {} - }, - "react-remove-scroll": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", - "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", - "requires": { - "react-remove-scroll-bar": "^2.3.3", - "react-style-singleton": "^2.2.1", - "tslib": "^2.1.0", - "use-callback-ref": "^1.3.0", - "use-sidecar": "^1.1.2" - } - }, - "react-remove-scroll-bar": { - "version": "2.3.4", - "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz", - "integrity": "sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==", - "requires": { - "react-style-singleton": "^2.2.1", - "tslib": "^2.0.0" - } - }, - "react-router": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.5.0.tgz", - "integrity": "sha512-fqqUSU0NC0tSX0sZbyuxzuAzvGqbjiZItBQnyicWlOUmzhAU8YuLgRbaCL2hf3sJdtRy4LP/WBrWtARkMvdGPQ==", - "requires": { - "@remix-run/router": "1.1.0" - } - }, - "react-router-dom": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.5.0.tgz", - "integrity": "sha512-/XzRc5fq80gW1ctiIGilyKFZC/j4kfe75uivMsTChFbkvrK4ZrF3P3cGIc1f/SSkQ4JiJozPrf+AwUHHWVehVg==", - "requires": { - "@remix-run/router": "1.1.0", - "react-router": "6.5.0" - } - }, - "react-shallow-renderer": { - "version": "16.15.0", - "resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz", - "integrity": "sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA==", - "dev": true, - "requires": { - "object-assign": "^4.1.1", - "react-is": "^16.12.0 || ^17.0.0 || ^18.0.0" - } - }, - "react-simple-img": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/react-simple-img/-/react-simple-img-3.0.0.tgz", - "integrity": "sha512-I0sG/GgY9c+04BgWf1YRlipWBQxR3oG2s/bagU8EO7zals3/Vkfk1PJMeYh/wHfjxJtUmal+y7HWEBm4MzXVsQ==", - "requires": {} - }, - "react-style-singleton": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", - "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", - "requires": { - "get-nonce": "^1.0.0", - "invariant": "^2.2.4", - "tslib": "^2.0.0" - } - }, - "react-test-renderer": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-18.0.0.tgz", - "integrity": "sha512-SyZTP/FSkwfiKOZuTZiISzsrC8A80KNlQ8PyyoGoOq+VzMAab6Em1POK/CiX3+XyXG6oiJa1C53zYDbdrJu9fw==", - "dev": true, - "requires": { - "react-is": "^18.0.0", - "react-shallow-renderer": "^16.13.1", - "scheduler": "^0.21.0" - }, - "dependencies": { - "react-is": { - "version": "18.0.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.0.0.tgz", - "integrity": "sha512-yUcBYdBBbo3QiPsgYDcfQcIkGZHfxOaoE6HLSnr1sPzMhdyxusbfKOSUbSd/ocGi32dxcj366PsTj+5oggeKKw==", - "dev": true - } - } - }, - "react-textarea-autosize": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.4.tgz", - "integrity": "sha512-CdtmP8Dc19xL8/R6sWvtknD/eCXkQr30dtvC4VmGInhRsfF8X/ihXCq6+9l9qbxmKRiq407/7z5fxE7cVWQNgQ==", - "requires": { - "@babel/runtime": "^7.10.2", - "use-composed-ref": "^1.3.0", - "use-latest": "^1.2.1" - } - }, - "react-transition-group": { - "version": "4.4.2", - "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", - "integrity": "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==", - "requires": { - "@babel/runtime": "^7.5.5", - "dom-helpers": "^5.0.1", - "loose-envify": "^1.4.0", - "prop-types": "^15.6.2" - } - }, - "react-virtualized-auto-sizer": { - "version": "1.0.17", - "resolved": "https://registry.npmjs.org/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.17.tgz", - "integrity": "sha512-XtojyZHGo/iYmGkOEL8psTQsr5XI4fd+QxCD16ru00mnJhuvXFXcPLHXj5cKJh/xUttxPCglnpUI8d2u6gUgzw==", - "requires": {} - }, - "react-window": { - "version": "1.8.9", - "resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.9.tgz", - "integrity": "sha512-+Eqx/fj1Aa5WnhRfj9dJg4VYATGwIUP2ItwItiJ6zboKWA6EX3lYDAXfGF2hyNqplEprhbtjbipiADEcwQ823Q==", - "requires": { - "@babel/runtime": "^7.0.0", - "memoize-one": ">=3.1.1 <6" - }, - "dependencies": { - "memoize-one": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", - "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" - } - } - }, - "react-window-infinite-loader": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/react-window-infinite-loader/-/react-window-infinite-loader-1.0.9.tgz", - "integrity": "sha512-5Hg89IdU4Vrp0RT8kZYKeTIxWZYhNkVXeI1HbKo01Vm/Z7qztDvXljwx16sMzsa9yapRJQW3ODZfMUw38SOWHw==", - "requires": {} - }, - "read-config-file": { - "version": "6.3.2", - "resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-6.3.2.tgz", - "integrity": "sha512-M80lpCjnE6Wt6zb98DoW8WHR09nzMSpu8XHtPkiTHrJ5Az9CybfeQhTJ8D7saeBHpGhLPIVyA8lcL6ZmdKwY6Q==", - "dev": true, - "requires": { - "config-file-ts": "^0.2.4", - "dotenv": "^9.0.2", - "dotenv-expand": "^5.1.0", - "js-yaml": "^4.1.0", - "json5": "^2.2.0", - "lazy-val": "^1.0.4" - } - }, - "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==", - "dev": 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" - } - }, - "readdirp": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", - "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", - "dev": true, - "requires": { - "picomatch": "^2.2.1" - } - }, - "rechoir": { - "version": "0.7.1", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", - "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", - "dev": true, - "requires": { - "resolve": "^1.9.0" - } - }, - "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" - } - }, - "regenerator-runtime": { - "version": "0.13.9", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", - "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "regexp.prototype.flags": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", - "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.3", - "functions-have-names": "^1.2.2" - } - }, - "regexpp": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", - "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", - "dev": true - }, - "relateurl": { - "version": "0.2.7", - "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", - "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", - "dev": true - }, - "remark": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/remark/-/remark-10.0.1.tgz", - "integrity": "sha512-E6lMuoLIy2TyiokHprMjcWNJ5UxfGQjaMSMhV+f4idM625UjjK4j798+gPs5mfjzDE6vL0oFKVeZM6gZVSVrzQ==", - "dev": true, - "requires": { - "remark-parse": "^6.0.0", - "remark-stringify": "^6.0.0", - "unified": "^7.0.0" - } - }, - "remark-parse": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-6.0.3.tgz", - "integrity": "sha512-QbDXWN4HfKTUC0hHa4teU463KclLAnwpn/FBn87j9cKYJWWawbiLgMfP2Q4XwhxxuuuOxHlw+pSN0OKuJwyVvg==", - "dev": true, - "requires": { - "collapse-white-space": "^1.0.2", - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "is-word-character": "^1.0.0", - "markdown-escapes": "^1.0.0", - "parse-entities": "^1.1.0", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "trim": "0.0.1", - "trim-trailing-lines": "^1.0.0", - "unherit": "^1.0.4", - "unist-util-remove-position": "^1.0.0", - "vfile-location": "^2.0.0", - "xtend": "^4.0.1" - } - }, - "remark-stringify": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-6.0.4.tgz", - "integrity": "sha512-eRWGdEPMVudijE/psbIDNcnJLRVx3xhfuEsTDGgH4GsFF91dVhw5nhmnBppafJ7+NWINW6C7ZwWbi30ImJzqWg==", - "dev": true, - "requires": { - "ccount": "^1.0.0", - "is-alphanumeric": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "longest-streak": "^2.0.1", - "markdown-escapes": "^1.0.0", - "markdown-table": "^1.1.0", - "mdast-util-compact": "^1.0.0", - "parse-entities": "^1.0.2", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "stringify-entities": "^1.0.1", - "unherit": "^1.0.4", - "xtend": "^4.0.1" - } - }, - "remove-accents": { - "version": "0.4.2", - "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz", - "integrity": "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA==" - }, - "remove-bom-buffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", - "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5", - "is-utf8": "^0.2.1" - } - }, - "remove-bom-stream": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", - "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", - "dev": true, - "requires": { - "remove-bom-buffer": "^3.0.0", - "safe-buffer": "^5.1.0", - "through2": "^2.0.3" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "renderkid": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", - "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", - "dev": true, - "requires": { - "css-select": "^4.1.3", - "dom-converter": "^0.2.0", - "htmlparser2": "^6.1.0", - "lodash": "^4.17.21", - "strip-ansi": "^6.0.1" - } - }, - "repeat-element": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", - "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "replace-ext": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", - "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", - "dev": true - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "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==" - }, - "requireindex": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", - "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", - "dev": true - }, - "requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", - "dev": true - }, - "resolve": { - "version": "1.22.1", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", - "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", - "requires": { - "is-core-module": "^2.9.0", - "path-parse": "^1.0.7", - "supports-preserve-symlinks-flag": "^1.0.0" - } - }, - "resolve-alpn": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", - "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", - "dev": true - }, - "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" - }, - "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-options": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", - "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", - "dev": true, - "requires": { - "value-or-function": "^3.0.0" - } - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "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": "2.0.1", - "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", - "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", - "dev": true, - "requires": { - "lowercase-keys": "^2.0.0" - } - }, - "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", - "dev": true, - "requires": { - "onetime": "^5.1.0", - "signal-exit": "^3.0.2" - } - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "retry": { - "version": "0.12.0", - "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", - "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", - "dev": true - }, - "reusify": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", - "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", - "dev": true - }, - "rfdc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", - "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", - "dev": true - }, - "rimraf": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", - "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", - "dev": true, - "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==", - "dev": true, - "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" - } - }, - "rsvp": { - "version": "4.8.5", - "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", - "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", - "dev": true - }, - "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==", - "dev": true, - "requires": { - "queue-microtask": "^1.2.2" - } - }, - "runtime-required": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/runtime-required/-/runtime-required-1.1.0.tgz", - "integrity": "sha512-yX97f5E0WfNpcQnfVjap6vzQcvErkYYCx6eTK4siqGEdC8lglwypUFgZVTX7ShvIlgfkC4XGFl9O1KTYcff0pw==", - "dev": true - }, - "rxjs": { - "version": "6.6.7", - "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", - "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } - } - }, - "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==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "safe-regex-test": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", - "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "get-intrinsic": "^1.1.3", - "is-regex": "^1.1.4" - } - }, - "safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true - }, - "sanitize-filename": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", - "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", - "dev": true, - "requires": { - "truncate-utf8-bytes": "^1.0.0" - } - }, - "sass": { - "version": "1.50.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.50.0.tgz", - "integrity": "sha512-cLsD6MEZ5URXHStxApajEh7gW189kkjn4Rc8DQweMyF+o5HF5nfEz8QYLMlPsTOD88DknatTmBWkOcw5/LnJLQ==", - "dev": true, - "requires": { - "chokidar": ">=3.0.0 <4.0.0", - "immutable": "^4.0.0", - "source-map-js": ">=0.6.2 <2.0.0" - } - }, - "sass-loader": { - "version": "12.6.0", - "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz", - "integrity": "sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==", - "dev": true, - "requires": { - "klona": "^2.0.4", - "neo-async": "^2.6.2" - } - }, - "sax": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", - "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" - }, - "saxes": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", - "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", - "dev": true, - "requires": { - "xmlchars": "^2.2.0" - } - }, - "scheduler": { - "version": "0.21.0", - "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", - "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", - "dev": true, - "requires": { - "loose-envify": "^1.1.0" - } - }, - "schema-utils": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz", - "integrity": "sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.8", - "ajv": "^6.12.5", - "ajv-keywords": "^3.5.2" - } - }, - "select-hose": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", - "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", - "dev": true - }, - "selfsigned": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.0.1.tgz", - "integrity": "sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ==", - "dev": true, - "requires": { - "node-forge": "^1" - } - }, - "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", - "requires": { - "lru-cache": "^6.0.0" - } - }, - "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==", - "dev": true, - "optional": true - }, - "send": { - "version": "0.18.0", - "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", - "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", - "dev": true, - "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" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - }, - "dependencies": { - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - } - } - }, - "depd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", - "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true - }, - "mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true - }, - "ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true - }, - "statuses": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", - "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", - "dev": true - } - } - }, - "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==", - "dev": true, - "optional": true, - "requires": { - "type-fest": "^0.13.1" - }, - "dependencies": { - "type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "dev": true, - "optional": true - } - } - }, - "serialize-javascript": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", - "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", - "dev": true, - "requires": { - "randombytes": "^2.1.0" - } - }, - "serve-index": { - "version": "1.9.1", - "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", - "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", - "dev": true, - "requires": { - "accepts": "~1.3.4", - "batch": "0.6.1", - "debug": "2.6.9", - "escape-html": "~1.0.3", - "http-errors": "~1.6.2", - "mime-types": "~2.1.17", - "parseurl": "~1.3.2" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "http-errors": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", - "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", - "dev": true, - "requires": { - "depd": "~1.1.2", - "inherits": "2.0.3", - "setprototypeof": "1.1.0", - "statuses": ">= 1.4.0 < 2" - } - }, - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", - "dev": true - }, - "setprototypeof": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", - "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", - "dev": 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==", - "dev": true, - "requires": { - "encodeurl": "~1.0.2", - "escape-html": "~1.0.3", - "parseurl": "~1.3.3", - "send": "0.18.0" - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-immediate-shim": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", - "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true - } - } - }, - "setprototypeof": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", - "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true - }, - "shallow-clone": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", - "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", - "dev": true, - "requires": { - "kind-of": "^6.0.2" - } - }, - "shallowequal": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", - "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" - }, - "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==", - "dev": true, - "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==", - "dev": true - }, - "side-channel": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", - "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", - "dev": true, - "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 - }, - "simple-update-notifier": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", - "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", - "dev": true, - "requires": { - "semver": "~7.0.0" - }, - "dependencies": { - "semver": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", - "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", - "dev": true - } - } - }, - "sirv": { - "version": "1.0.19", - "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.19.tgz", - "integrity": "sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==", - "dev": true, - "requires": { - "@polka/url": "^1.0.0-next.20", - "mrmime": "^1.0.0", - "totalist": "^1.0.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": "3.0.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", - "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", - "dev": true, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - }, - "smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", - "dev": true - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "dev": true, - "requires": { - "ms": "2.0.0" - } - }, - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", - "dev": true - }, - "source-map-resolve": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", - "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "sockjs": { - "version": "0.3.24", - "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", - "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", - "dev": true, - "requires": { - "faye-websocket": "^0.11.3", - "uuid": "^8.3.2", - "websocket-driver": "^0.7.4" - } - }, - "socks": { - "version": "2.6.2", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz", - "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==", - "dev": true, - "requires": { - "ip": "^1.1.5", - "smart-buffer": "^4.2.0" - } - }, - "sort-keys": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-5.0.0.tgz", - "integrity": "sha512-Pdz01AvCAottHTPQGzndktFNdbRA75BgOfeT1hH+AMnJFv8lynkPi42rfeEhpx1saTEI3YNMWxfqu0sFD1G8pw==", - "dev": true, - "requires": { - "is-plain-obj": "^4.0.0" - }, - "dependencies": { - "is-plain-obj": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", - "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", - "dev": true - } - } - }, - "source-map": { - "version": "0.7.3", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", - "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", - "dev": true - }, - "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-resolve": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", - "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", - "dev": true, - "requires": { - "atob": "^2.1.2", - "decode-uri-component": "^0.2.0" - } - }, - "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==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - }, - "dependencies": { - "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 - } - } - }, - "source-map-url": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", - "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", - "dev": true - }, - "spawn-command": { - "version": "0.0.2-1", - "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", - "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=", - "dev": true - }, - "spdx-correct": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", - "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", - "dev": true, - "requires": { - "spdx-expression-parse": "^3.0.0", - "spdx-license-ids": "^3.0.0" - } - }, - "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==", - "dev": true, - "requires": { - "spdx-exceptions": "^2.1.0", - "spdx-license-ids": "^3.0.0" - } - }, - "spdx-license-ids": { - "version": "3.0.11", - "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", - "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", - "dev": true - }, - "spdy": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", - "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "handle-thing": "^2.0.0", - "http-deceiver": "^1.2.7", - "select-hose": "^2.0.0", - "spdy-transport": "^3.0.0" - } - }, - "spdy-transport": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", - "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", - "dev": true, - "requires": { - "debug": "^4.1.0", - "detect-node": "^2.0.4", - "hpack.js": "^2.1.6", - "obuf": "^1.1.2", - "readable-stream": "^3.0.6", - "wbuf": "^1.7.3" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "specificity": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.4.1.tgz", - "integrity": "sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", - "dev": true - }, - "ssr-window": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/ssr-window/-/ssr-window-4.0.2.tgz", - "integrity": "sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ==" - }, - "stable": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", - "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", - "dev": 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==", - "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 - } - } - }, - "stackframe": { - "version": "1.3.4", - "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", - "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", - "dev": true - }, - "stat-mode": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz", - "integrity": "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==", - "dev": true - }, - "state-toggle": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", - "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==", - "dev": true - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - } - }, - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "statuses": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", - "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", - "dev": true - }, - "stream-shift": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", - "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", - "dev": true - }, - "streamx": { - "version": "2.13.2", - "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.13.2.tgz", - "integrity": "sha512-+TWqixPhGDXEG9L/XczSbhfkmwAtGs3BJX5QNU6cvno+pOLKeszByWcnaTu6dg8efsTYqR8ZZuXWHhZfgrxMvA==", - "dev": true, - "requires": { - "fast-fifo": "^1.1.0", - "queue-tick": "^1.0.1" - } - }, - "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==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "string-argv": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", - "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", - "dev": true - }, - "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, - "requires": { - "char-regex": "^1.0.2", - "strip-ansi": "^6.0.0" - } - }, - "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": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "dependencies": { - "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 - } - } - }, - "string.prototype.matchall": { - "version": "4.0.8", - "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", - "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4", - "get-intrinsic": "^1.1.3", - "has-symbols": "^1.0.3", - "internal-slot": "^1.0.3", - "regexp.prototype.flags": "^1.4.3", - "side-channel": "^1.0.4" - } - }, - "string.prototype.trimend": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", - "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "string.prototype.trimstart": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", - "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "define-properties": "^1.1.4", - "es-abstract": "^1.20.4" - } - }, - "stringify-entities": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.2.tgz", - "integrity": "sha512-nrBAQClJAPN2p+uGCVJRPIPakKeKWZ9GtBCmormE7pWOSlHat7+x5A8gx85M7HM5Dt0BP3pP5RhVW77WdbJJ3A==", - "dev": true, - "requires": { - "character-entities-html4": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-hexadecimal": "^1.0.0" - } - }, - "strip-ansi": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "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" - } - }, - "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==", - "dev": true - }, - "style-loader": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz", - "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==", - "dev": true, - "requires": {} - }, - "style-search": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", - "integrity": "sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=", - "dev": true - }, - "styled-components": { - "version": "5.3.11", - "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.11.tgz", - "integrity": "sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==", - "requires": { - "@babel/helper-module-imports": "^7.0.0", - "@babel/traverse": "^7.4.5", - "@emotion/is-prop-valid": "^1.1.0", - "@emotion/stylis": "^0.8.4", - "@emotion/unitless": "^0.7.4", - "babel-plugin-styled-components": ">= 1.12.0", - "css-to-react-native": "^3.0.0", - "hoist-non-react-statics": "^3.0.0", - "shallowequal": "^1.1.0", - "supports-color": "^5.5.0" - }, - "dependencies": { - "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==" - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "stylehacks": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.0.tgz", - "integrity": "sha512-SzLmvHQTrIWfSgljkQCw2++C9+Ne91d/6Sp92I8c5uHTcy/PgeHamwITIbBW9wnFTY/3ZfSXR9HIL6Ikqmcu6Q==", - "dev": true, - "requires": { - "browserslist": "^4.16.6", - "postcss-selector-parser": "^6.0.4" - } - }, - "stylelint": { - "version": "14.9.1", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.9.1.tgz", - "integrity": "sha512-RdAkJdPiLqHawCSnu21nE27MjNXaVd4WcOHA4vK5GtIGjScfhNnaOuWR2wWdfKFAvcWQPOYe311iveiVKSmwsA==", - "dev": true, - "requires": { - "@csstools/selector-specificity": "^2.0.1", - "balanced-match": "^2.0.0", - "colord": "^2.9.2", - "cosmiconfig": "^7.0.1", - "css-functions-list": "^3.1.0", - "debug": "^4.3.4", - "execall": "^2.0.0", - "fast-glob": "^3.2.11", - "fastest-levenshtein": "^1.0.12", - "file-entry-cache": "^6.0.1", - "get-stdin": "^8.0.0", - "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.14", - "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.2.0", - "svg-tags": "^1.0.0", - "table": "^6.8.0", - "v8-compile-cache": "^2.3.0", - "write-file-atomic": "^4.0.1" - }, - "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 - }, - "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 - }, - "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 - }, - "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 - }, - "write-file-atomic": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz", - "integrity": "sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "signal-exit": "^3.0.7" - } - } - } - }, - "stylelint-config-rational-order": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/stylelint-config-rational-order/-/stylelint-config-rational-order-0.1.2.tgz", - "integrity": "sha512-Qo7ZQaihCwTqijfZg4sbdQQHtugOX/B1/fYh018EiDZHW+lkqH9uHOnsDwDPGZrYJuB6CoyI7MZh2ecw2dOkew==", - "dev": true, - "requires": { - "stylelint": "^9.10.1", - "stylelint-order": "^2.2.1" - }, - "dependencies": { - "@nodelib/fs.stat": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", - "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", - "dev": true + "ansi-html-community": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/ansi-html-community/-/ansi-html-community-0.0.8.tgz", + "integrity": "sha512-1APHAyr3+PCamwNw3bXCPp4HFLONZt/yIH0sZp0/469KWNTEy+qN5jQ3GVX6DMZ1UXAi34yVwtTeaG/HpBuuzw==", + "dev": true }, "ansi-regex": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", - "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", - "dev": true + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz", + "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==", + "dev": true }, "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" - } + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "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" + } + }, + "app-builder-bin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/app-builder-bin/-/app-builder-bin-4.0.0.tgz", + "integrity": "sha512-xwdG0FJPQMe0M0UA4Tz0zEB8rBJTRA5a476ZawAqiBkMv16GRK5xpXThOjMaEOFnZ6zabejjG4J3da0SXG63KA==", + "dev": true + }, + "app-builder-lib": { + "version": "24.0.0-alpha.13", + "resolved": "https://registry.npmjs.org/app-builder-lib/-/app-builder-lib-24.0.0-alpha.13.tgz", + "integrity": "sha512-fQa3zDl948PS+EvDaAtPTM3UvrXKns9TEQ7dR3BYWJbpIs7s0e1FxlwVLrINYGLv7hxdLkhbJ0ewPxKyj/ahpQ==", + "dev": true, + "requires": { + "@develar/schema-utils": "~2.6.5", + "@electron/notarize": "^1.2.3", + "@electron/osx-sign": "^1.0.4", + "@electron/rebuild": "^3.2.10", + "@electron/universal": "1.3.4", + "@malept/flatpak-bundler": "^0.4.0", + "7zip-bin": "~5.1.1", + "async-exit-hook": "^2.0.1", + "bluebird-lst": "^1.0.9", + "builder-util": "24.0.0-alpha.13", + "builder-util-runtime": "9.2.0-alpha.3", + "chromium-pickle-js": "^0.2.0", + "debug": "^4.3.4", + "ejs": "^3.1.8", + "electron-publish": "24.0.0-alpha.13", + "form-data": "^4.0.0", + "fs-extra": "^10.1.0", + "hosted-git-info": "^4.1.0", + "is-ci": "^3.0.0", + "isbinaryfile": "^5.0.0", + "js-yaml": "^4.1.0", + "lazy-val": "^1.0.5", + "minimatch": "^5.1.1", + "read-config-file": "6.3.2", + "sanitize-filename": "^1.6.3", + "semver": "^7.3.8", + "tar": "^6.1.12", + "temp-file": "^3.4.0" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "builder-util-runtime": { + "version": "9.2.0-alpha.3", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.0-alpha.3.tgz", + "integrity": "sha512-1pOggEqknxVyhdASumips0/RaMaXwSCQMzwhk2jeOGOotBQuOHQHVy25kH5OaeXSFx9L7PckZHXjwZauD72zRw==", + "dev": true, + "requires": { + "debug": "^4.3.4", + "sax": "^1.2.4" + } + }, + "fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, + "append-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/append-buffer/-/append-buffer-1.0.2.tgz", + "integrity": "sha1-2CIM9GYIFSXv6lBhTz3mUU36WPE=", + "dev": true, + "requires": { + "buffer-equal": "^1.0.0" + } + }, + "aproba": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", + "integrity": "sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==", + "dev": true + }, + "are-we-there-yet": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-3.0.0.tgz", + "integrity": "sha512-0GWpv50YSOcLXaN6/FAKY3vfRbllXWV2xvfA/oKJF8pzFhWXPV+yjhJXDBbjscDYowv7Yw1A3uigpzn5iEGTyw==", + "dev": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^3.6.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true }, "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" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==" + }, + "aria-hidden": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/aria-hidden/-/aria-hidden-1.2.2.tgz", + "integrity": "sha512-6y/ogyDTk/7YAe91T3E2PR1ALVKyM2QbTio5HwM+N1Q6CMlCKhvClyIjkckBswa0f2xJhjsfzIGa1yVSe1UMVA==", + "requires": { + "tslib": "^2.0.0" + } + }, + "aria-query": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-5.0.0.tgz", + "integrity": "sha512-V+SM7AbUwJ+EBnB8+DXs0hPZHO0W6pqBcc0dW90OwtVG02PswOu/teuARoLQjdDOH+t9pJgGnW5/Qmouf3gPJg==", + "dev": true + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==", + "dev": true + }, + "array-find": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-find/-/array-find-1.0.0.tgz", + "integrity": "sha1-bI4obRHtdoMn+OYuzuhzU8o+eLg=", + "dev": true + }, + "array-find-index": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-find-index/-/array-find-index-1.0.2.tgz", + "integrity": "sha512-M1HQyIXcBGtVywBt8WVdim+lrNaK7VHp99Qt5pSNziXznKHViIBbXWtfRTpEFpF/c4FdfxNAsCCwPp5phBYJtw==", + "dev": true + }, + "array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "dev": true + }, + "array-includes": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz", + "integrity": "sha512-sgTbLvL6cNnw24FnbaDyjmvddQ2ML8arZsgaJhoABMoplz/4QRhtrYS+alr1BUM1Bwp6dhx8vVCBSLG+StwOFw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "is-string": "^1.0.7" + } }, "array-union": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", - "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", - "dev": true, - "requires": { - "array-uniq": "^1.0.1" - } + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", + "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==", + "dev": true + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha512-MNha4BWQ6JbwhFhj03YK552f7cb3AzoE8SzeljgChvL1dl3IcvggXVz1DilzySZkCja+CXuZbdW7yATchWn8/Q==", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==", + "dev": true + }, + "array.prototype.flat": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.0.tgz", + "integrity": "sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.2", + "es-shim-unscopables": "^1.0.0" + } + }, + "array.prototype.flatmap": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.1.tgz", + "integrity": "sha512-8UGn9O1FDVvMNB0UlLv4voxRMze7+FpHyF5mSMRjWHUMlpoDViniy05870VlxhfgTnLbpuwTzvD76MTtWxB/mQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0" + } + }, + "array.prototype.tosorted": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array.prototype.tosorted/-/array.prototype.tosorted-1.1.1.tgz", + "integrity": "sha512-pZYPXPRl2PqWcsUs6LOMn+1f1532nEoPTYowBtqLwAW+W8vSVhkIGnmOX1t/UQjD6YGI0vcD2B1U7ZFGQH9jnQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.1.3" + } + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==", + "dev": true + }, + "assert-plus": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz", + "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==", + "dev": true, + "optional": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==", + "dev": true + }, + "ast-metadata-inferer": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/ast-metadata-inferer/-/ast-metadata-inferer-0.7.0.tgz", + "integrity": "sha512-OkMLzd8xelb3gmnp6ToFvvsHLtS6CbagTkFQvQ+ZYFe3/AIl9iKikNR9G7pY3GfOR/2Xc222hwBjzI7HLkE76Q==", + "dev": true, + "requires": { + "@mdn/browser-compat-data": "^3.3.14" + }, + "dependencies": { + "@mdn/browser-compat-data": { + "version": "3.3.14", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-3.3.14.tgz", + "integrity": "sha512-n2RC9d6XatVbWFdHLimzzUJxJ1KY8LdjqrW6YvGPiRmsHkhOUx74/Ct10x5Yo7bC/Jvqx7cDEW8IMPv/+vwEzA==", + "dev": true + } + } + }, + "ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", + "dev": true }, "astral-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", - "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", - "dev": true + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-2.0.0.tgz", + "integrity": "sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==", + "dev": true + }, + "async": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/async/-/async-3.2.4.tgz", + "integrity": "sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==", + "dev": true + }, + "async-exit-hook": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/async-exit-hook/-/async-exit-hook-2.0.1.tgz", + "integrity": "sha512-NW2cX8m1Q7KPA7a5M2ULQeZ2wR5qI5PAbw5L0UOMxdioVk9PMZ0h1TmyZEkPYrCvYjDlFICusOu1dlEKAAeXBw==", + "dev": true + }, + "asynckit": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz", + "integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=" + }, + "at-least-node": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", + "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "atomically": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/atomically/-/atomically-1.7.0.tgz", + "integrity": "sha512-Xcz9l0z7y9yQ9rdDaxlmaI4uJHf/T8g9hOEzJcsEqX2SjCj4J20uK7+ldkDHMbpJDK76wF7xEIgxc/vSlsfw5w==" + }, + "autoprefixer": { + "version": "9.8.8", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.8.tgz", + "integrity": "sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==", + "dev": true, + "requires": { + "browserslist": "^4.12.0", + "caniuse-lite": "^1.0.30001109", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "picocolors": "^0.2.1", + "postcss": "^7.0.32", + "postcss-value-parser": "^4.1.0" + }, + "dependencies": { + "picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "requires": { + "picocolors": "^0.2.1", + "source-map": "^0.6.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 + } + } + }, + "axe-core": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/axe-core/-/axe-core-4.6.1.tgz", + "integrity": "sha512-lCZN5XRuOnpG4bpMq8v0khrWtUOn+i8lZSb6wHZH56ZfbIEv6XwJV84AAueh9/zi7qPVJ/E4yz6fmsiyOmXR4w==", + "dev": true + }, + "axios": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", + "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", + "requires": { + "follow-redirects": "^1.15.0", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "axobject-query": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.2.0.tgz", + "integrity": "sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==", + "dev": true + }, + "babel-jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-27.5.1.tgz", + "integrity": "sha512-cdQ5dXjGRd0IBRATiQ4mZGlGlRE8kJpjPOixdNRdT+m3UcNqmYWN6rK6nvtXYfY3D76cb8s/O1Ss8ea24PIwcg==", + "dev": true, + "requires": { + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__core": "^7.1.14", + "babel-plugin-istanbul": "^6.1.1", + "babel-preset-jest": "^27.5.1", + "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": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-27.5.1.tgz", + "integrity": "sha512-50wCwD5EMNW4aRpOwtqzyZHIewTYNxLA4nhB+09d8BIssfNfzBRhkBIHiaPv1Si226TQSvp8gxAJm2iY2qs2hQ==", + "dev": true, + "requires": { + "@babel/template": "^7.3.3", + "@babel/types": "^7.3.3", + "@types/babel__core": "^7.0.0", + "@types/babel__traverse": "^7.0.6" + } + }, + "babel-plugin-macros": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", + "integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==", + "requires": { + "@babel/runtime": "^7.12.5", + "cosmiconfig": "^7.0.0", + "resolve": "^1.19.0" + } + }, + "babel-plugin-styled-components": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.7.tgz", + "integrity": "sha512-i7YhvPgVqRKfoQ66toiZ06jPNA3p6ierpfUuEWxNF+fV27Uv5gxBkf8KZLHUCc1nFA9j6+80pYoIpqCeyW3/bA==", + "requires": { + "@babel/helper-annotate-as-pure": "^7.16.0", + "@babel/helper-module-imports": "^7.16.0", + "babel-plugin-syntax-jsx": "^6.18.0", + "lodash": "^4.17.11", + "picomatch": "^2.3.0" + } + }, + "babel-plugin-syntax-jsx": { + "version": "6.18.0", + "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", + "integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==" + }, + "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": "27.5.1", + "resolved": "https://registry.npmjs.org/babel-preset-jest/-/babel-preset-jest-27.5.1.tgz", + "integrity": "sha512-Nptf2FzlPCWYuJg41HBqXVT8ym6bXOevuCTbhxlUpjwtysGaIWFvDEjp4y+G7fl13FgOdjs7P/DmErqH7da0Ag==", + "dev": true, + "requires": { + "babel-plugin-jest-hoist": "^27.5.1", + "babel-preset-current-node-syntax": "^1.0.0" + } + }, + "bail": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", + "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + } + } + }, + "base64-js": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", + "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", + "dev": true + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "dev": true + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "bl": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", + "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", + "dev": true, + "requires": { + "buffer": "^5.5.0", + "inherits": "^2.0.4", + "readable-stream": "^3.4.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "bluebird-lst": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/bluebird-lst/-/bluebird-lst-1.0.9.tgz", + "integrity": "sha512-7B1Rtx82hjnSD4PGLAjVWeYH3tHAcVUmChh85a3lltKQm6FresXh9ErQo6oAv6CqxttczC3/kEg8SY5NluPuUw==", + "dev": true, + "requires": { + "bluebird": "^3.5.5" + } + }, + "body-parser": { + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.0.tgz", + "integrity": "sha512-DfJ+q6EPcGKZD1QWUjSpqp+Q7bDQTsQIF4zfUAtZ6qk+H/3/QRhg9CEp39ss+/T2vw0+HaidC0ecJj/DRLIaKg==", + "dev": true, + "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.10.3", + "raw-body": "2.5.1", + "type-is": "~1.6.18", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "bonjour-service": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/bonjour-service/-/bonjour-service-1.0.11.tgz", + "integrity": "sha512-drMprzr2rDTCtgEE3VgdA9uUFaUHF+jXduwYSThHJnKMYM+FhI9Z3ph+TX3xy0LtgYHae6CHYPJ/2UnK8nQHcA==", + "dev": true, + "requires": { + "array-flatten": "^2.1.2", + "dns-equal": "^1.0.0", + "fast-deep-equal": "^3.1.3", + "multicast-dns": "^7.2.4" + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, + "boolean": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.2.0.tgz", + "integrity": "sha512-d0II/GO9uf9lfUHH2BQsjxzRJZBdsjgsBiW4BvhWk/3qoKwQFjIDVN19PfX8F2D/r9PCMTtLWjYVCFrpeYUzsw==", + "dev": true, + "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==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } }, "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } + "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" + } + }, + "broccoli-node-api": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/broccoli-node-api/-/broccoli-node-api-1.7.0.tgz", + "integrity": "sha512-QIqLSVJWJUVOhclmkmypJJH9u9s/aWH4+FH6Q6Ju5l+Io4dtwqdPUNmDfw40o6sxhbZHhqGujDJuHTML1wG8Yw==", + "dev": true + }, + "broccoli-node-info": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/broccoli-node-info/-/broccoli-node-info-2.2.0.tgz", + "integrity": "sha512-VabSGRpKIzpmC+r+tJueCE5h8k6vON7EIMMWu6d/FyPdtijwLQ7QvzShEw+m3mHoDzUaj/kiZsDYrS8X2adsBg==", + "dev": true + }, + "broccoli-output-wrapper": { + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/broccoli-output-wrapper/-/broccoli-output-wrapper-3.2.5.tgz", + "integrity": "sha512-bQAtwjSrF4Nu0CK0JOy5OZqw9t5U0zzv2555EA/cF8/a8SLDTIetk9UgrtMVw7qKLKdSpOZ2liZNeZZDaKgayw==", + "dev": true, + "requires": { + "fs-extra": "^8.1.0", + "heimdalljs-logger": "^0.1.10", + "symlink-or-copy": "^1.2.0" + } + }, + "broccoli-plugin": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/broccoli-plugin/-/broccoli-plugin-4.0.7.tgz", + "integrity": "sha512-a4zUsWtA1uns1K7p9rExYVYG99rdKeGRymW0qOCNkvDPHQxVi3yVyJHhQbM3EZwdt2E0mnhr5e0c/bPpJ7p3Wg==", + "dev": true, + "requires": { + "broccoli-node-api": "^1.7.0", + "broccoli-output-wrapper": "^3.2.5", + "fs-merger": "^3.2.1", + "promise-map-series": "^0.3.0", + "quick-temp": "^0.1.8", + "rimraf": "^3.0.2", + "symlink-or-copy": "^1.3.1" + } + }, + "browser-process-hrtime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/browser-process-hrtime/-/browser-process-hrtime-1.0.0.tgz", + "integrity": "sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==", + "dev": true + }, + "browserslist": { + "version": "4.21.4", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.21.4.tgz", + "integrity": "sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==", + "requires": { + "caniuse-lite": "^1.0.30001400", + "electron-to-chromium": "^1.4.251", + "node-releases": "^2.0.6", + "update-browserslist-db": "^1.0.9" + } + }, + "browserslist-config-erb": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/browserslist-config-erb/-/browserslist-config-erb-0.0.3.tgz", + "integrity": "sha512-y47DryCY92lxkKyRVMlaZvXAolIY7U33q9e4CS0MdWeJkoAht7OzsrkfdZFCBOP3H5q1EVUxS0L7VVsKM6gZCQ==", + "dev": true, + "requires": {} + }, + "bs-logger": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/bs-logger/-/bs-logger-0.2.6.tgz", + "integrity": "sha512-pd8DCoxmbgc7hyPKOvxtqNcjYoOsABPQdcCUjGp3d42VR2CX1ORhk2A87oqqu5R1kk+76nsxZupkmyd+MVtCog==", + "dev": true, + "requires": { + "fast-json-stable-stringify": "2.x" + } + }, + "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": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", + "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", + "dev": true, + "requires": { + "base64-js": "^1.3.1", + "ieee754": "^1.1.13" + } + }, + "buffer-crc32": { + "version": "0.2.13", + "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true + }, + "buffer-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/buffer-equal/-/buffer-equal-1.0.0.tgz", + "integrity": "sha1-WWFrSYME1Var1GaWayLu2j7KX74=", + "dev": 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==", + "dev": true + }, + "builder-util": { + "version": "24.0.0-alpha.13", + "resolved": "https://registry.npmjs.org/builder-util/-/builder-util-24.0.0-alpha.13.tgz", + "integrity": "sha512-S8u+ETQ9GV4hJdrxJgVh2V0Cp14WiTrXRy7NsRSlM+DXaNtCIO3VNJSlEg4Btn1cJLUhfo1Fse8FIryV3gRj0Q==", + "dev": true, + "requires": { + "@types/debug": "^4.1.6", + "@types/fs-extra": "^9.0.11", + "7zip-bin": "~5.1.1", + "app-builder-bin": "4.0.0", + "bluebird-lst": "^1.0.9", + "builder-util-runtime": "9.2.0-alpha.3", + "chalk": "^4.1.2", + "cross-spawn": "^7.0.3", + "debug": "^4.3.4", + "fs-extra": "^10.1.0", + "http-proxy-agent": "^5.0.0", + "https-proxy-agent": "^5.0.1", + "is-ci": "^3.0.0", + "js-yaml": "^4.1.0", + "source-map-support": "^0.5.19", + "stat-mode": "^1.0.0", + "temp-file": "^3.4.0" + }, + "dependencies": { + "builder-util-runtime": { + "version": "9.2.0-alpha.3", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.0-alpha.3.tgz", + "integrity": "sha512-1pOggEqknxVyhdASumips0/RaMaXwSCQMzwhk2jeOGOotBQuOHQHVy25kH5OaeXSFx9L7PckZHXjwZauD72zRw==", + "dev": true, + "requires": { + "debug": "^4.3.4", + "sax": "^1.2.4" + } + }, + "fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, + "builder-util-runtime": { + "version": "8.9.2", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-8.9.2.tgz", + "integrity": "sha512-rhuKm5vh7E0aAmT6i8aoSfEjxzdYEFX7zDApK+eNgOhjofnWb74d9SRJv0H/8nsgOkos0TZ4zxW0P8J4N7xQ2A==", + "requires": { + "debug": "^4.3.2", + "sax": "^1.2.4" + } + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "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==", + "dev": true + }, + "cacheable-request": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.2.tgz", + "integrity": "sha512-pouW8/FmiPQbuGpkXQ9BAPv/Mo5xDGANgSNXzTzJ8DrKGuXOssM4wIQRjfanNRh3Yu5cfYPvcorqbhg2KIJtew==", + "dev": true, + "requires": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + } + }, + "call-bind": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.2.tgz", + "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "get-intrinsic": "^1.0.2" + } + }, + "call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha512-wCyFsDQkKPwwF8BDwOiWNx/9K45L/hvggQiDbve+viMNMQnWhrlYIuBk09offfwCRtCO9P6XwUttufzU11WCVw==", + "dev": true + }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==", + "dev": true, + "requires": { + "callsites": "^2.0.0" + }, + "dependencies": { + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==", + "dev": true + } + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==", + "dev": true, + "requires": { + "caller-callsite": "^2.0.0" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==" + }, + "camel-case": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-4.1.2.tgz", + "integrity": "sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==", + "dev": true, + "requires": { + "pascal-case": "^3.1.2", + "tslib": "^2.0.3" } - } }, "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==", - "dev": true + "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": "4.2.0", - "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", - "integrity": "sha512-Ej37YKYbFUI8QiYlvj9YHb6/Z60dZyPJW0Cs8sFilMbd2lP0bw3ylAq9yJkK4lcTA2dID5fG8LjmJYbO7kWb7Q==", - "dev": true, - "requires": { - "camelcase": "^4.1.0", - "map-obj": "^2.0.0", - "quick-lru": "^1.0.0" - } + "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" + }, + "dependencies": { + "quick-lru": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", + "integrity": "sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==", + "dev": true + } + } + }, + "camelize": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/camelize/-/camelize-1.0.1.tgz", + "integrity": "sha512-dU+Tx2fsypxTgtLoE36npi3UqcjSSMNYfkqgmoEhtZrraP5VWq0K7FkWVTYa8eMPtnU/G2txVsfdCJTn9uzpuQ==" + }, + "caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "caniuse-lite": { + "version": "1.0.30001439", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001439.tgz", + "integrity": "sha512-1MgUzEkoMO6gKfXflStpYgZDlFM7M/ck/bgfVCACO5vnAf0fXoNVHdWtqGU+MYca+4bL9Z5bpOVmR33cWW9G2A==" + }, + "ccount": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", + "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==", + "dev": true }, "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" - } + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, + "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 + }, + "character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "dev": true + }, + "character-entities-html4": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz", + "integrity": "sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g==", + "dev": true + }, + "character-entities-legacy": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-1.1.4.tgz", + "integrity": "sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==", + "dev": true + }, + "character-reference-invalid": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-1.1.4.tgz", + "integrity": "sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==", + "dev": true + }, + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=" + }, + "cheerio": { + "version": "1.0.0-rc.10", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.10.tgz", + "integrity": "sha512-g0J0q/O6mW8z5zxQ3A8E8J1hUgp4SMOvEoW/x84OwyHKe/Zccz83PVT4y5Crcr530FV6NgmKI1qvGTKVl9XXVw==", + "dev": true, + "requires": { + "cheerio-select": "^1.5.0", + "dom-serializer": "^1.3.2", + "domhandler": "^4.2.0", + "htmlparser2": "^6.1.0", + "parse5": "^6.0.1", + "parse5-htmlparser2-tree-adapter": "^6.0.1", + "tslib": "^2.2.0" + } + }, + "cheerio-select": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-1.6.0.tgz", + "integrity": "sha512-eq0GdBvxVFbqWgmCm7M3XGs1I8oLy/nExUnh6oLqmBditPO9AqQJrkslDpMun/hZ0yyTs8L0m85OHp4ho6Qm9g==", + "dev": true, + "requires": { + "css-select": "^4.3.0", + "css-what": "^6.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.3.1", + "domutils": "^2.8.0" + } + }, + "chokidar": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.3.tgz", + "integrity": "sha512-Dr3sfKRP6oTcjf2JmUmFJfeVMvXBdegxB0iVQ5eb2V10uFJUCAS8OByZdVAyVb8xXNz3GjjTgj9kLWsZTqE6kw==", + "dev": true, + "requires": { + "anymatch": "~3.1.2", + "braces": "~3.0.2", + "fsevents": "~2.3.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" + }, + "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" + } + } + } + }, + "chownr": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-2.0.0.tgz", + "integrity": "sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==", + "dev": true + }, + "chrome-trace-event": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz", + "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", + "dev": true + }, + "chromium-pickle-js": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/chromium-pickle-js/-/chromium-pickle-js-0.2.0.tgz", + "integrity": "sha512-1R5Fho+jBq0DDydt+/vHWj5KJNJCKdARKOCwZUen84I5BreWoLqRLANH1U87eJy1tiASPtMnGqJJq0ZsLoRPOw==", + "dev": true + }, + "ci-info": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.3.0.tgz", + "integrity": "sha512-riT/3vI5YpVH6/qomlDnJow6TBee2PBKSEpx3O32EGPYbWGIRsIlGRms3Sm74wYE1JMo8RnO04Hb12+v1J5ICw==", + "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 + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "clean-css": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.0.tgz", + "integrity": "sha512-YYuuxv4H/iNb1Z/5IbMRoxgrzjWGhOEFfd+groZ5dMCVkpENiMZmwspdrzBo9286JjM1gZJPAyL7ZIdzuvu2AQ==", + "dev": true, + "requires": { + "source-map": "~0.6.0" + }, + "dependencies": { + "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 + } + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dev": true, + "requires": { + "restore-cursor": "^3.1.0" + } + }, + "cli-spinners": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.6.1.tgz", + "integrity": "sha512-x/5fWmGMnbKQAaNwN+UZlV79qBLM9JFnJuJ03gIi5whrob0xV0ofNVHy9DhwGdsMJQc2OKv0oGmLzvaqvAVv+g==", + "dev": true + }, + "cli-truncate": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-2.1.0.tgz", + "integrity": "sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==", + "dev": true, + "requires": { + "slice-ansi": "^3.0.0", + "string-width": "^4.2.0" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + } + }, + "clone": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz", + "integrity": "sha1-2jCcwmPfFZlMaIypAheco8fNfH4=", + "dev": true + }, + "clone-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-buffer/-/clone-buffer-1.0.0.tgz", + "integrity": "sha1-4+JbIHrE5wGvch4staFnksrD3Fg=", + "dev": true + }, + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } }, "clone-regexp": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-1.0.1.tgz", - "integrity": "sha512-Fcij9IwRW27XedRIJnSOEupS7RVcXtObJXbcUOX93UCLqqOdRpkvzKywOOSizmEK/Is3S/RHX9dLdfo6R1Q1mw==", - "dev": true, - "requires": { - "is-regexp": "^1.0.0", - "is-supported-regexp-flag": "^1.0.0" - } + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-2.2.0.tgz", + "integrity": "sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==", + "dev": true, + "requires": { + "is-regexp": "^2.0.0" + } + }, + "clone-response": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.2.tgz", + "integrity": "sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=", + "dev": true, + "requires": { + "mimic-response": "^1.0.0" + } + }, + "clone-stats": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/clone-stats/-/clone-stats-1.0.0.tgz", + "integrity": "sha1-s3gt/4u1R04Yuba/D9/ngvh3doA=", + "dev": true + }, + "cloneable-readable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/cloneable-readable/-/cloneable-readable-1.1.3.tgz", + "integrity": "sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "process-nextick-args": "^2.0.0", + "readable-stream": "^2.3.5" + } + }, + "clsx": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/clsx/-/clsx-1.1.1.tgz", + "integrity": "sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA==" + }, + "cmdk": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/cmdk/-/cmdk-0.2.0.tgz", + "integrity": "sha512-JQpKvEOb86SnvMZbYaFKYhvzFntWBeSZdyii0rZPhKJj9uwJBxu4DaVYDrRN7r3mPop56oPhRw+JYWTKs66TYw==", + "requires": { + "@radix-ui/react-dialog": "1.0.0", + "command-score": "0.1.2" + } + }, + "co": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", + "integrity": "sha1-bqa989hTrlTMuOR7+gvz+QMfsYQ=", + "dev": true + }, + "collapse-white-space": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", + "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", + "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 + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.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" - } + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } }, "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 + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "color-support": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz", + "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", + "dev": true + }, + "colord": { + "version": "2.9.2", + "resolved": "https://registry.npmjs.org/colord/-/colord-2.9.2.tgz", + "integrity": "sha512-Uqbg+J445nc1TKn4FoDPS6ZZqAvEDnwrH42yo8B40JSOgSLxMZ/gt3h4nmCtPLQeXhjJJkqBx7SCY35WnIixaQ==", + "dev": true + }, + "colorette": { + "version": "2.0.16", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.16.tgz", + "integrity": "sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g==", + "dev": true + }, + "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" + } + }, + "command-score": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/command-score/-/command-score-0.1.2.tgz", + "integrity": "sha512-VtDvQpIJBvBatnONUsPzXYFVKQQAhuf3XTNOAsdBxCNO/QCtUUd8LSgjn0GVarBkCad6aJCZfXgrjYbl/KRr7w==" + }, + "commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true + }, + "common-path-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/common-path-prefix/-/common-path-prefix-3.0.0.tgz", + "integrity": "sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==", + "dev": true + }, + "compare-version": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/compare-version/-/compare-version-0.1.2.tgz", + "integrity": "sha512-pJDh5/4wrEnXX/VWRZvruAGHkzKdr46z11OlTPN+VrATlWWhSKewNCJ1futCO5C7eJB3nPMFZA1LeYtcFboZ2A==", + "dev": true + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "requires": { + "mime-db": ">= 1.43.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "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==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concurrently": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/concurrently/-/concurrently-7.1.0.tgz", + "integrity": "sha512-Bz0tMlYKZRUDqJlNiF/OImojMB9ruKUz6GCfmhFnSapXgPe+3xzY4byqoKG9tUZ7L2PGEUjfLPOLfIX3labnmw==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "date-fns": "^2.16.1", + "lodash": "^4.17.21", + "rxjs": "^6.6.3", + "spawn-command": "^0.0.2-1", + "supports-color": "^8.1.0", + "tree-kill": "^1.2.2", + "yargs": "^16.2.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" + } + } + } + }, + "conf": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/conf/-/conf-10.2.0.tgz", + "integrity": "sha512-8fLl9F04EJqjSqH+QjITQfJF8BrOVaYr1jewVgSRAEWePfxT0sku4w2hrGQ60BC/TNLGQ2pgxNlTbWQmMPFvXg==", + "requires": { + "ajv": "^8.6.3", + "ajv-formats": "^2.1.1", + "atomically": "^1.7.0", + "debounce-fn": "^4.0.0", + "dot-prop": "^6.0.1", + "env-paths": "^2.2.1", + "json-schema-typed": "^7.0.3", + "onetime": "^5.1.2", + "pkg-up": "^3.1.0", + "semver": "^7.3.5" + }, + "dependencies": { + "ajv": { + "version": "8.11.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.11.0.tgz", + "integrity": "sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==", + "requires": { + "fast-deep-equal": "^3.1.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2", + "uri-js": "^4.2.2" + } + }, + "dot-prop": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz", + "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==", + "requires": { + "is-obj": "^2.0.0" + } + }, + "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==" + } + } + }, + "config-file-ts": { + "version": "0.2.4", + "resolved": "https://registry.npmjs.org/config-file-ts/-/config-file-ts-0.2.4.tgz", + "integrity": "sha512-cKSW0BfrSaAUnxpgvpXPLaaW/umg4bqg4k3GO1JqlRfpx+d5W0GDXznCMkWotJQek5Mmz1MJVChQnz3IVaeMZQ==", + "dev": true, + "requires": { + "glob": "^7.1.6", + "typescript": "^4.0.2" + } + }, + "confusing-browser-globals": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/confusing-browser-globals/-/confusing-browser-globals-1.0.11.tgz", + "integrity": "sha512-JsPKdmh8ZkmnHxDk55FZ1TqVLvEQTvoByJZRN9jzI0UjxK/QgAmsphz7PGtqgPieQZ/CQcHWXCR7ATDNhGe+YA==", + "dev": true + }, + "connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "dev": true + }, + "console-control-strings": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz", + "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "safe-buffer": "5.2.1" + }, + "dependencies": { + "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==", + "dev": true + } + } + }, + "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==", + "dev": true + }, + "convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cookie": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz", + "integrity": "sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw==", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "copy-anything": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-3.0.2.tgz", + "integrity": "sha512-CzATjGXzUQ0EvuvgOCI6A4BGOo2bcVx8B+eC2nF862iv9fopnPQwlrbACakNCHRIJbCSBj+J/9JeDf60k64MkA==", + "requires": { + "is-what": "^4.1.6" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==", + "dev": true + }, + "core-js": { + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.21.1.tgz", + "integrity": "sha512-FRq5b/VMrWlrmCzwRrpDYNxyHP9BcAZC+xHJaqTgIE5091ZV1NTmyh0sGOg5XqpnHvR0svdy0sv1gWA1zmhxig==", + "dev": true + }, + "core-js-pure": { + "version": "3.21.1", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.21.1.tgz", + "integrity": "sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ==", + "dev": true + }, + "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==", + "dev": true }, "cosmiconfig": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", - "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", - "dev": true, - "requires": { - "import-fresh": "^2.0.0", - "is-directory": "^0.3.1", - "js-yaml": "^3.13.1", - "parse-json": "^4.0.0" - } + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.0.1.tgz", + "integrity": "sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==", + "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" + } + }, + "crc": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/crc/-/crc-3.8.0.tgz", + "integrity": "sha512-iX3mfgcTMIq3ZKLIsVFAbv7+Mc10kxabAGQb8HvjA1o3T1PIYprbakQ65d3I+2HGHt6nSKkM9PYjgoJO2KcFBQ==", + "dev": true, + "optional": true, + "requires": { + "buffer": "^5.1.0" + } + }, + "create-require": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", + "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", + "dev": true + }, + "cross-env": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.3.tgz", + "integrity": "sha512-+/HKd6EgcQCJGh2PSjZuUitQBQynKor4wrFbRg4DtAgS1aWO+gU52xpH7M9ScGgXSYmAVS9bIJ8EzuaGw0oNAw==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.1" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "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": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=" + }, + "css": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", + "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "source-map": "^0.6.1", + "source-map-resolve": "^0.6.0" + }, + "dependencies": { + "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 + } + } + }, + "css-color-keywords": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", + "integrity": "sha512-FyyrDHZKEjXDpNJYvVsV960FiqQyXc/LlYmsxl2BcdMb2WPx0OGRVgTg55rPSyLSNMqP52R9r8geSp7apN3Ofg==" + }, + "css-declaration-sorter": { + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-6.2.2.tgz", + "integrity": "sha512-Ufadglr88ZLsrvS11gjeu/40Lw74D9Am/Jpr3LlYm5Q4ZP5KdlUhG+6u2EjyXeZcxmZ2h1ebCKngDjolpeLHpg==", + "dev": true, + "requires": {} + }, + "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 + }, + "css-loader": { + "version": "6.7.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-6.7.1.tgz", + "integrity": "sha512-yB5CNFa14MbPJcomwNh3wLThtkZgcNyI2bNMRt8iE5Z8Vwl7f8vQXFAzn2HDOJvtDq2NTZBUGMSUNNyrv3/+cw==", + "dev": true, + "requires": { + "icss-utils": "^5.1.0", + "postcss": "^8.4.7", + "postcss-modules-extract-imports": "^3.0.0", + "postcss-modules-local-by-default": "^4.0.0", + "postcss-modules-scope": "^3.0.0", + "postcss-modules-values": "^4.0.0", + "postcss-value-parser": "^4.2.0", + "semver": "^7.3.5" + } + }, + "css-minimizer-webpack-plugin": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/css-minimizer-webpack-plugin/-/css-minimizer-webpack-plugin-3.4.1.tgz", + "integrity": "sha512-1u6D71zeIfgngN2XNRJefc/hY7Ybsxd74Jm4qngIXyUEk7fss3VUzuHxLAq/R8NAba4QU9OUSaMZlbpRc7bM4Q==", + "dev": true, + "requires": { + "cssnano": "^5.0.6", + "jest-worker": "^27.0.2", + "postcss": "^8.3.5", + "schema-utils": "^4.0.0", + "serialize-javascript": "^6.0.0", + "source-map": "^0.6.1" + }, + "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" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "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 + }, + "schema-utils": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" + } + }, + "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 + } + } + }, + "css-select": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-4.3.0.tgz", + "integrity": "sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^6.0.1", + "domhandler": "^4.3.1", + "domutils": "^2.8.0", + "nth-check": "^2.0.1" + } + }, + "css-to-react-native": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.0.0.tgz", + "integrity": "sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==", + "requires": { + "camelize": "^1.0.0", + "css-color-keywords": "^1.0.0", + "postcss-value-parser": "^4.0.2" + } + }, + "css-tree": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.1.3.tgz", + "integrity": "sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==", + "dev": true, + "requires": { + "mdn-data": "2.0.14", + "source-map": "^0.6.1" + }, + "dependencies": { + "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 + } + } + }, + "css-what": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz", + "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==", + "dev": true + }, + "css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=", + "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 + }, + "cssnano": { + "version": "5.1.7", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-5.1.7.tgz", + "integrity": "sha512-pVsUV6LcTXif7lvKKW9ZrmX+rGRzxkEdJuVJcp5ftUjWITgwam5LMZOgaTvUrWPkcORBey6he7JKb4XAJvrpKg==", + "dev": true, + "requires": { + "cssnano-preset-default": "^5.2.7", + "lilconfig": "^2.0.3", + "yaml": "^1.10.2" + } + }, + "cssnano-preset-default": { + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-5.2.7.tgz", + "integrity": "sha512-JiKP38ymZQK+zVKevphPzNSGHSlTI+AOwlasoSRtSVMUU285O7/6uZyd5NbW92ZHp41m0sSHe6JoZosakj63uA==", + "dev": true, + "requires": { + "css-declaration-sorter": "^6.2.2", + "cssnano-utils": "^3.1.0", + "postcss-calc": "^8.2.3", + "postcss-colormin": "^5.3.0", + "postcss-convert-values": "^5.1.0", + "postcss-discard-comments": "^5.1.1", + "postcss-discard-duplicates": "^5.1.0", + "postcss-discard-empty": "^5.1.1", + "postcss-discard-overridden": "^5.1.0", + "postcss-merge-longhand": "^5.1.4", + "postcss-merge-rules": "^5.1.1", + "postcss-minify-font-values": "^5.1.0", + "postcss-minify-gradients": "^5.1.1", + "postcss-minify-params": "^5.1.2", + "postcss-minify-selectors": "^5.2.0", + "postcss-normalize-charset": "^5.1.0", + "postcss-normalize-display-values": "^5.1.0", + "postcss-normalize-positions": "^5.1.0", + "postcss-normalize-repeat-style": "^5.1.0", + "postcss-normalize-string": "^5.1.0", + "postcss-normalize-timing-functions": "^5.1.0", + "postcss-normalize-unicode": "^5.1.0", + "postcss-normalize-url": "^5.1.0", + "postcss-normalize-whitespace": "^5.1.1", + "postcss-ordered-values": "^5.1.1", + "postcss-reduce-initial": "^5.1.0", + "postcss-reduce-transforms": "^5.1.0", + "postcss-svgo": "^5.1.0", + "postcss-unique-selectors": "^5.1.1" + } + }, + "cssnano-utils": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cssnano-utils/-/cssnano-utils-3.1.0.tgz", + "integrity": "sha512-JQNR19/YZhz4psLX/rQ9M83e3z2Wf/HdJbryzte4a3NSuafyp9w/I4U+hx5C2S9g41qlstH7DEWnZaaj83OuEA==", + "dev": true, + "requires": {} + }, + "csso": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.2.0.tgz", + "integrity": "sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==", + "dev": true, + "requires": { + "css-tree": "^1.1.2" + } + }, + "cssom": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/cssom/-/cssom-0.4.4.tgz", + "integrity": "sha512-p3pvU7r1MyyqbTk+WbNJIgJjG2VmTIaB10rI93LzVPrmDJKkzKYMtxxyAvQXR/NS6otuzveI7+7BBq3SjBS2mw==", + "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 + } + } + }, + "csstype": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.0.11.tgz", + "integrity": "sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==" + }, + "currently-unhandled": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/currently-unhandled/-/currently-unhandled-0.4.1.tgz", + "integrity": "sha512-/fITjgjGU50vjQ4FH6eUoYu+iUoUKIXws2hL15JJpIR+BbTxaXQsMuuyjtNh2WqsSBS5nsaZHFsFecyw5CCAng==", + "dev": true, + "requires": { + "array-find-index": "^1.0.1" + } + }, + "damerau-levenshtein": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.8.tgz", + "integrity": "sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==", + "dev": true + }, + "data-urls": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/data-urls/-/data-urls-2.0.0.tgz", + "integrity": "sha512-X5eWTSXO/BJmpdIKCRuKUgSCgAN0OwliVK3yPKbwIWU1Tdw5BRajxlzMidvh+gwko9AfQ9zIj52pzF91Q3YAvQ==", + "dev": true, + "requires": { + "abab": "^2.0.3", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.0.0" + } + }, + "date-fns": { + "version": "2.28.0", + "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.28.0.tgz", + "integrity": "sha512-8d35hViGYx/QH0icHYCeLmsLmMUheMmTyV9Fcm6gvNwdw31yXXH+O85sOBJ+OLnLQMKZowvpKb6FgMIQjcpvQw==", + "dev": true + }, + "dayjs": { + "version": "1.11.6", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.6.tgz", + "integrity": "sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ==" + }, + "de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=", + "dev": true + }, + "debounce-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/debounce-fn/-/debounce-fn-4.0.0.tgz", + "integrity": "sha512-8pYCQiL9Xdcg0UPSD3d+0KMlOjp+KGU5EPwYddgzQ7DATsg4fuUDjQtsYLmWjnk2obnNHgV3vE2Y4jejSOJVBQ==", + "requires": { + "mimic-fn": "^3.0.0" + }, + "dependencies": { + "mimic-fn": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", + "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==" + } + } + }, + "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.3.1", + "resolved": "https://registry.npmjs.org/decimal.js/-/decimal.js-10.3.1.tgz", + "integrity": "sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", + "integrity": "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ==", + "dev": true + }, + "decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "requires": { + "mimic-response": "^3.1.0" + }, + "dependencies": { + "mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true + } + } + }, + "dedent": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", + "integrity": "sha1-JJXduvbrh0q7Dhvp3yLS5aVEMmw=", + "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==", + "dev": true + }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" + }, + "default-gateway": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-6.0.3.tgz", + "integrity": "sha512-fwSOJsbbNzZ/CUFpqFBqYfYNLj1NbMPm8MMCIzHjC83iSJRBEGmDUxU+WP661BaBQImeC2yHwXtz+P/O9o+XEg==", + "dev": true, + "requires": { + "execa": "^5.0.0" + } + }, + "defaults": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", + "integrity": "sha1-xlYFHpgX2f8I7YgUd/P+QBnz730=", + "dev": true, + "requires": { + "clone": "^1.0.2" + } + }, + "defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true + }, + "define-lazy-prop": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", + "integrity": "sha512-Ds09qNh8yw3khSjiJjiUInaGX9xlqZDY7JVryGxdxV7NPeuqQfplOpQ66yJFZut3jLa5zOwkXw1g9EI2uKh4Og==", + "dev": true + }, + "define-properties": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz", + "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==", + "dev": true, + "requires": { + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + } + }, + "delayed-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", + "integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=" + }, + "delegates": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz", + "integrity": "sha1-hMbhWbgZBP3KWaDvRM2HDTElD5o=", + "dev": true + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "destroy": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", + "integrity": "sha512-2sJGJTaXIIaR1w4iJSNoN0hnMY7Gpc/n8D4qSCJw8QqFWXf7cuAgnEHxBpweaVcPevC2l3KpjYCx3NypQQgaJg==", + "dev": true + }, + "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==", + "dev": true + }, + "detect-node-es": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", + "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==" + }, + "detect-port": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/detect-port/-/detect-port-1.3.0.tgz", + "integrity": "sha512-E+B1gzkl2gqxt1IhUzwjrxBKRqx1UzC3WLONHinn8S3T6lwV/agVCyitiFOsGJ/eYuEUBvD71MZHy3Pv1G9doQ==", + "dev": true, + "requires": { + "address": "^1.0.1", + "debug": "^2.6.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "diff-sequences": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/diff-sequences/-/diff-sequences-27.5.1.tgz", + "integrity": "sha512-k1gCAXAsNgLwEL+Y8Wvl+M6oEFj5bgazfZULpS5CneoPPXRaCCW7dm+q21Ky2VEE5X+VeRDBVg1Pcvvsr4TtNQ==", + "dev": true + }, + "dir-compare": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/dir-compare/-/dir-compare-3.3.0.tgz", + "integrity": "sha512-J7/et3WlGUCxjdnD3HAAzQ6nsnc0WL6DD7WcwJb7c39iH1+AWfg+9OqzJNaI6PkBwBvm1mhZNL9iY/nRiZXlPg==", + "dev": true, + "requires": { + "buffer-equal": "^1.0.0", + "minimatch": "^3.0.4" + } }, "dir-glob": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", - "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", - "dev": true, - "requires": { - "path-type": "^3.0.0" - } + "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" + } + }, + "dmg-builder": { + "version": "24.0.0-alpha.13", + "resolved": "https://registry.npmjs.org/dmg-builder/-/dmg-builder-24.0.0-alpha.13.tgz", + "integrity": "sha512-+2tnaKVKEboVjXeR+CcoOPy/cnTKY+QVPw4sgS2Z50/GO5tjKAttQJ7ZoCl7BUIqBuP9P7ZvCG7mUzhZKHofgQ==", + "dev": true, + "requires": { + "app-builder-lib": "24.0.0-alpha.13", + "builder-util": "24.0.0-alpha.13", + "builder-util-runtime": "9.2.0-alpha.3", + "dmg-license": "^1.0.11", + "fs-extra": "^10.1.0", + "iconv-lite": "^0.6.2", + "js-yaml": "^4.1.0" + }, + "dependencies": { + "builder-util-runtime": { + "version": "9.2.0-alpha.3", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.0-alpha.3.tgz", + "integrity": "sha512-1pOggEqknxVyhdASumips0/RaMaXwSCQMzwhk2jeOGOotBQuOHQHVy25kH5OaeXSFx9L7PckZHXjwZauD72zRw==", + "dev": true, + "requires": { + "debug": "^4.3.4", + "sax": "^1.2.4" + } + }, + "fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, + "dmg-license": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/dmg-license/-/dmg-license-1.0.11.tgz", + "integrity": "sha512-ZdzmqwKmECOWJpqefloC5OJy1+WZBBse5+MR88z9g9Zn4VY+WYUkAyojmhzJckH5YbbZGcYIuGAkY5/Ys5OM2Q==", + "dev": true, + "optional": true, + "requires": { + "@types/plist": "^3.0.1", + "@types/verror": "^1.10.3", + "ajv": "^6.10.0", + "crc": "^3.8.0", + "iconv-corefoundation": "^1.1.7", + "plist": "^3.0.4", + "smart-buffer": "^4.0.2", + "verror": "^1.10.0" + } + }, + "dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", + "dev": true + }, + "dns-packet": { + "version": "5.6.0", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-5.6.0.tgz", + "integrity": "sha512-rza3UH1LwdHh9qyPXp8lkwpjSNk/AMD3dPytUoRoqnypDUhY0xvbdmVhWOfxO68frEfV9BU8V12Ez7ZsHGZpCQ==", + "dev": true, + "requires": { + "@leichtgewicht/ip-codec": "^2.0.1" + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "dom-accessibility-api": { + "version": "0.5.13", + "resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.13.tgz", + "integrity": "sha512-R305kwb5CcMDIpSHUnLyIAp7SrSPBx6F0VfQFB3M75xVMHhXJJIdePYgbPPh1o57vCHNu5QztokWUPsLjWzFqw==", + "dev": true + }, + "dom-converter": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/dom-converter/-/dom-converter-0.2.0.tgz", + "integrity": "sha512-gd3ypIPfOMr9h5jIKq8E3sHOTCjeirnl0WK5ZdS1AW0Odt0b1PaWaHdJ4Qk4klv+YB9aJBS7mESXjFoDQPu6DA==", + "dev": true, + "requires": { + "utila": "~0.4" + } + }, + "dom-helpers": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz", + "integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==", + "requires": { + "@babel/runtime": "^7.8.7", + "csstype": "^3.0.2" + } + }, + "dom-serializer": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-1.3.2.tgz", + "integrity": "sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.2.0", + "entities": "^2.0.0" + } + }, + "domelementtype": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.2.0.tgz", + "integrity": "sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==", + "dev": true + }, + "domexception": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domexception/-/domexception-2.0.1.tgz", + "integrity": "sha512-yxJ2mFy/sibVQlu5qHjOkf9J3K6zgmCxgJ94u2EdvDOV09H+32LtRswEcUsmUWN72pVLOEnTSRaIVVzVQgS0dg==", + "dev": true, + "requires": { + "webidl-conversions": "^5.0.0" + }, + "dependencies": { + "webidl-conversions": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-5.0.0.tgz", + "integrity": "sha512-VlZwKPCkYKxQgeSbH5EyngOmRp7Ww7I9rQLERETtf5ofd9pGeswWiOtogpEO850jziPRarreGxn5QIiTqpb2wA==", + "dev": true + } + } + }, + "domhandler": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-4.3.1.tgz", + "integrity": "sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==", + "dev": true, + "requires": { + "domelementtype": "^2.2.0" + } + }, + "domutils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-2.8.0.tgz", + "integrity": "sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==", + "dev": true, + "requires": { + "dom-serializer": "^1.0.1", + "domelementtype": "^2.2.0", + "domhandler": "^4.2.0" + } + }, + "dot-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-3.0.4.tgz", + "integrity": "sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "dot-prop": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz", + "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "dotenv": { + "version": "9.0.2", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-9.0.2.tgz", + "integrity": "sha512-I9OvvrHp4pIARv4+x9iuewrWycX6CcZtoAu1XrzPxc5UygMJXJZYmBsynku8IkrJwgypE5DGNjDPmPRhDCptUg==", + "dev": true + }, + "dotenv-expand": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-5.1.0.tgz", + "integrity": "sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==", + "dev": true + }, + "duplexer": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz", + "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", + "dev": true + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "eastasianwidth": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", + "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", + "dev": true + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "ejs": { + "version": "3.1.9", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-3.1.9.tgz", + "integrity": "sha512-rC+QVNMJWv+MtPgkt0y+0rVEIdbtxVADApW9JXrUVlzHetgcyczP/E7DJmWJ4fJCZF2cPcBk0laWO9ZHMG3DmQ==", + "dev": true, + "requires": { + "jake": "^10.8.5" + } + }, + "electron": { + "version": "22.3.1", + "resolved": "https://registry.npmjs.org/electron/-/electron-22.3.1.tgz", + "integrity": "sha512-iDltL9j12bINK3aOp8ZoGq4NFBFjJhw1AYHelbWj93XUCAIT4fdA+PRsq0aaTHg3bthLLlLRvIZVgNsZPqWcqg==", + "dev": true, + "requires": { + "@electron/get": "^2.0.0", + "@types/node": "^16.11.26", + "extract-zip": "^2.0.1" + }, + "dependencies": { + "@types/node": { + "version": "16.18.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-16.18.13.tgz", + "integrity": "sha512-l0/3XZ153UTlNOnZK8xSNoJlQda9/WnYgiTdcKKPJSZjdjI9MU+A9oMXOesAWLSnqAaaJhj3qfQsU07Dr8OUwg==", + "dev": true + } + } + }, + "electron-builder": { + "version": "24.0.0-alpha.13", + "resolved": "https://registry.npmjs.org/electron-builder/-/electron-builder-24.0.0-alpha.13.tgz", + "integrity": "sha512-YLDlzySvfBZKoCp4hNf4cx849vrew+3jxfNx5malT2PGd3y2GPYKCEvFc15AGShmah2Pt0gGoVQRot/dC6Nb9g==", + "dev": true, + "requires": { + "@types/yargs": "^17.0.16", + "app-builder-lib": "24.0.0-alpha.13", + "builder-util": "24.0.0-alpha.13", + "builder-util-runtime": "9.2.0-alpha.3", + "chalk": "^4.1.2", + "dmg-builder": "24.0.0-alpha.13", + "fs-extra": "^10.1.0", + "is-ci": "^3.0.0", + "lazy-val": "^1.0.5", + "read-config-file": "6.3.2", + "simple-update-notifier": "^1.1.0", + "yargs": "^17.6.2" + }, + "dependencies": { + "builder-util-runtime": { + "version": "9.2.0-alpha.3", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.0-alpha.3.tgz", + "integrity": "sha512-1pOggEqknxVyhdASumips0/RaMaXwSCQMzwhk2jeOGOotBQuOHQHVy25kH5OaeXSFx9L7PckZHXjwZauD72zRw==", + "dev": true, + "requires": { + "debug": "^4.3.4", + "sax": "^1.2.4" + } + }, + "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" + } + }, + "fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + }, + "yargs": { + "version": "17.6.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz", + "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==", + "dev": true, + "requires": { + "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.1.1" + } + }, + "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 + } + } + }, + "electron-debug": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/electron-debug/-/electron-debug-3.2.0.tgz", + "integrity": "sha512-7xZh+LfUvJ52M9rn6N+tPuDw6oRAjxUj9SoxAZfJ0hVCXhZCsdkrSt7TgXOiWiEOBgEV8qwUIO/ScxllsPS7ow==", + "requires": { + "electron-is-dev": "^1.1.0", + "electron-localshortcut": "^3.1.0" + } + }, + "electron-devtools-installer": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/electron-devtools-installer/-/electron-devtools-installer-3.2.0.tgz", + "integrity": "sha512-t3UczsYugm4OAbqvdImMCImIMVdFzJAHgbwHpkl5jmfu1izVgUcP/mnrPqJIpEeCK1uZGpt+yHgWEN+9EwoYhQ==", + "dev": true, + "requires": { + "rimraf": "^3.0.2", + "semver": "^7.2.1", + "tslib": "^2.1.0", + "unzip-crx-3": "^0.2.0" + } + }, + "electron-is-accelerator": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/electron-is-accelerator/-/electron-is-accelerator-0.1.2.tgz", + "integrity": "sha1-UJ5RDCala1Xhf4Y6SwThEYRqsns=" + }, + "electron-is-dev": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/electron-is-dev/-/electron-is-dev-1.2.0.tgz", + "integrity": "sha512-R1oD5gMBPS7PVU8gJwH6CtT0e6VSoD0+SzSnYpNm+dBkcijgA+K7VAMHDfnRq/lkKPZArpzplTW6jfiMYosdzw==" + }, + "electron-localshortcut": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/electron-localshortcut/-/electron-localshortcut-3.2.1.tgz", + "integrity": "sha512-DWvhKv36GsdXKnaFFhEiK8kZZA+24/yFLgtTwJJHc7AFgDjNRIBJZ/jq62Y/dWv9E4ypYwrVWN2bVrCYw1uv7Q==", + "requires": { + "debug": "^4.0.1", + "electron-is-accelerator": "^0.1.0", + "keyboardevent-from-electron-accelerator": "^2.0.0", + "keyboardevents-areequal": "^0.2.1" + } + }, + "electron-log": { + "version": "4.4.6", + "resolved": "https://registry.npmjs.org/electron-log/-/electron-log-4.4.6.tgz", + "integrity": "sha512-nirYgRdY+F+vclr8ijdwy2vW03IzFpDHTaKNWu76dEN21Y76+smcES5knS7cgHUUB0qNLOi8vZO36taakjbSXA==" + }, + "electron-notarize": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/electron-notarize/-/electron-notarize-1.2.1.tgz", + "integrity": "sha512-u/ECWhIrhkSQpZM4cJzVZ5TsmkaqrRo5LDC/KMbGF0sPkm53Ng59+M0zp8QVaql0obfJy9vlVT+4iOkAi2UDlA==", + "dev": true, + "requires": { + "debug": "^4.1.1", + "fs-extra": "^9.0.1" + }, + "dependencies": { + "fs-extra": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", + "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "dev": true, + "requires": { + "at-least-node": "^1.0.0", + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, + "electron-publish": { + "version": "24.0.0-alpha.13", + "resolved": "https://registry.npmjs.org/electron-publish/-/electron-publish-24.0.0-alpha.13.tgz", + "integrity": "sha512-ur3XrX/8vLfZV+UisnbFvinX2ETD+Jdq8mUqG1sKlgITsQdjjjt8vKLiBgE71YhgDqFylpmFeWF8MJT91sSPnQ==", + "dev": true, + "requires": { + "@types/fs-extra": "^9.0.11", + "builder-util": "24.0.0-alpha.13", + "builder-util-runtime": "9.2.0-alpha.3", + "chalk": "^4.1.2", + "fs-extra": "^10.1.0", + "lazy-val": "^1.0.5", + "mime": "^2.5.2" + }, + "dependencies": { + "builder-util-runtime": { + "version": "9.2.0-alpha.3", + "resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.0-alpha.3.tgz", + "integrity": "sha512-1pOggEqknxVyhdASumips0/RaMaXwSCQMzwhk2jeOGOotBQuOHQHVy25kH5OaeXSFx9L7PckZHXjwZauD72zRw==", + "dev": true, + "requires": { + "debug": "^4.3.4", + "sax": "^1.2.4" + } + }, + "fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, + "electron-store": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/electron-store/-/electron-store-8.1.0.tgz", + "integrity": "sha512-2clHg/juMjOH0GT9cQ6qtmIvK183B39ZXR0bUoPwKwYHJsEF3quqyDzMFUAu+0OP8ijmN2CbPRAelhNbWUbzwA==", + "requires": { + "conf": "^10.2.0", + "type-fest": "^2.17.0" + }, + "dependencies": { + "type-fest": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-2.19.0.tgz", + "integrity": "sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==" + } + } + }, + "electron-to-chromium": { + "version": "1.4.284", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.284.tgz", + "integrity": "sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==" + }, + "electron-updater": { + "version": "4.6.5", + "resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-4.6.5.tgz", + "integrity": "sha512-kdTly8O9mSZfm9fslc1mnCY+mYOeaYRy7ERa2Fed240u01BKll3aiupzkd07qKw69KvhBSzuHroIW3mF0D8DWA==", + "requires": { + "@types/semver": "^7.3.6", + "builder-util-runtime": "8.9.2", + "fs-extra": "^10.0.0", + "js-yaml": "^4.1.0", + "lazy-val": "^1.0.5", + "lodash.escaperegexp": "^4.1.2", + "lodash.isequal": "^4.5.0", + "semver": "^7.3.5" + }, + "dependencies": { + "fs-extra": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.1.tgz", + "integrity": "sha512-NbdoVMZso2Lsrn/QwLXOy6rm0ufY2zEOKCDzJR/0kBsb0E6qed0P3iYK+Ath3BfvXEeu4JhEtXLgILx5psUfag==", + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==" + } + } + }, + "electronmon": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/electronmon/-/electronmon-2.0.2.tgz", + "integrity": "sha512-Yw1CXEp5HJT9P6Sns3UP3Krwm5eb2JKqTRAVczKdsUa+U/dMTgONwKIHkPbKSSmtyTV+5JwobxkhFPiRgegObA==", + "dev": true, + "requires": { + "chalk": "^3.0.0", + "import-from": "^3.0.0", + "runtime-required": "^1.1.0", + "watchboy": "^0.4.3" + }, + "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" + } + } + } + }, + "emittery": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/emittery/-/emittery-0.8.1.tgz", + "integrity": "sha512-uDfvUjVrfGJJhymx/kz6prltenw1u7WrCg1oa94zYY8xxVpLLUu045LAT0dhDZdXG58/EpPL/5kA180fQ/qudg==", + "dev": true }, "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", + "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", + "dev": true + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "encoding": { + "version": "0.1.13", + "resolved": "https://registry.npmjs.org/encoding/-/encoding-0.1.13.tgz", + "integrity": "sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==", + "dev": true, + "optional": true, + "requires": { + "iconv-lite": "^0.6.2" + } + }, + "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==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enhanced-resolve": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-0.9.1.tgz", + "integrity": "sha1-TW5omzcl+GCQknzMhs2fFjW4ni4=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.2.0", + "tapable": "^0.1.8" + }, + "dependencies": { + "tapable": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-0.1.10.tgz", + "integrity": "sha1-KcNXB8K3DlDQdIK10gLo7URtr9Q=", + "dev": true + } + } + }, + "ensure-posix-path": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ensure-posix-path/-/ensure-posix-path-1.1.1.tgz", + "integrity": "sha512-VWU0/zXzVbeJNXvME/5EmLuEj2TauvoaTz6aFYK1Z92JCBlDlZ3Gu0tuGR42kpW1754ywTs+QB0g5TP0oj9Zaw==", + "dev": true + }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "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==" + }, + "envinfo": { + "version": "7.8.1", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.8.1.tgz", + "integrity": "sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==", + "dev": true + }, + "eol": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/eol/-/eol-0.9.1.tgz", + "integrity": "sha512-Ds/TEoZjwggRoz/Q2O7SE3i4Jm66mqTDfmdHdq/7DKVk3bro9Q8h6WdXKdPqFLMoqxrDK5SVRzHVPOS6uuGtrg==", + "dev": true + }, + "err-code": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", + "integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==", + "dev": 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==", + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "error-stack-parser": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.7.tgz", + "integrity": "sha512-chLOW0ZGRf4s8raLrDxa5sdkvPec5YdvwbFnqJme4rk0rFajP8mPtrDL1+I+CwrQDCjswDA5sREX7jYQDQs9vA==", + "dev": true, + "requires": { + "stackframe": "^1.1.1" + } + }, + "es-abstract": { + "version": "1.20.5", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.5.tgz", + "integrity": "sha512-7h8MM2EQhsCA7pU/Nv78qOXFpD8Rhqd12gYiSJVkrH9+e8VuA8JlPJK/hQjjlLv6pJvx/z1iRFKzYb0XT/RuAQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "function.prototype.name": "^1.1.5", + "get-intrinsic": "^1.1.3", + "get-symbol-description": "^1.0.0", + "gopd": "^1.0.1", + "has": "^1.0.3", + "has-property-descriptors": "^1.0.0", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-weakref": "^1.0.2", + "object-inspect": "^1.12.2", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.4.3", + "safe-regex-test": "^1.0.0", + "string.prototype.trimend": "^1.0.6", + "string.prototype.trimstart": "^1.0.6", + "unbox-primitive": "^1.0.2" + } + }, + "es-module-lexer": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.2.1.tgz", + "integrity": "sha512-9978wrXM50Y4rTMmW5kXIC09ZdXQZqkE4mxhwkd8VbzsGkXGPgV4zWuqQJgCEzYngdo2dYDa0l8xhX4fkSwJSg==", + "dev": true + }, + "es-shim-unscopables": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz", + "integrity": "sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true, + "optional": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==" + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "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 + "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": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "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": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "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, + "optional": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + } + } + }, + "eslint": { + "version": "8.30.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.30.0.tgz", + "integrity": "sha512-MGADB39QqYuzEGov+F/qb18r4i7DohCDOfatHaxI2iGlPuC65bwG2gxgO+7DkyL38dRFaRH7RaRAgU6JKL9rMQ==", + "dev": true, + "requires": { + "@eslint/eslintrc": "^1.4.0", + "@humanwhocodes/config-array": "^0.11.8", + "@humanwhocodes/module-importer": "^1.0.1", + "@nodelib/fs.walk": "^1.2.8", + "ajv": "^6.10.0", + "chalk": "^4.0.0", + "cross-spawn": "^7.0.2", + "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.19.0", + "grapheme-splitter": "^1.0.4", + "ignore": "^5.2.0", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "is-glob": "^4.0.0", + "is-path-inside": "^3.0.3", + "js-sdsl": "^4.1.4", + "js-yaml": "^4.1.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "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" + }, + "dependencies": { + "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==", + "dev": true, + "requires": { + "esrecurse": "^4.3.0", + "estraverse": "^5.2.0" + } + } + } + }, + "eslint-config-airbnb-base": { + "version": "15.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-15.0.0.tgz", + "integrity": "sha512-xaX3z4ZZIcFLvh2oUNvcX5oEofXda7giYmuplVxoOg5A7EXJMrUyqRgR+mhDhPK8LZ4PttFOBvCYDbX3sUoUig==", + "dev": true, + "requires": { + "confusing-browser-globals": "^1.0.10", + "object.assign": "^4.1.2", + "object.entries": "^1.1.5", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "eslint-config-erb": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-config-erb/-/eslint-config-erb-4.0.3.tgz", + "integrity": "sha512-qZeiUSQanpCKKazkLzIvVaoM9NZcNvqhO7gYZ2jaEpBmadCu1aOzzvMMtjsoxaDytRQt6mt+uXjWGyJNqUYusw==", + "dev": true, + "requires": { + "@typescript-eslint/eslint-plugin": "^4.29.2", + "@typescript-eslint/parser": "^4.29.3", + "eslint-config-airbnb": "^18.2.1", + "eslint-config-airbnb-typescript": "^13.0.0", + "eslint-config-prettier": "^8.3.0", + "eslint-import-resolver-webpack": "^0.13.1", + "eslint-plugin-compat": "^3.13.0", + "eslint-plugin-import": "^2.24.1", + "eslint-plugin-jest": "^24.4.0", + "eslint-plugin-jsx-a11y": "6.4.1", + "eslint-plugin-prettier": "^3.4.1", + "eslint-plugin-promise": "^5.1.0", + "eslint-plugin-react": "^7.24.0", + "eslint-plugin-react-hooks": "^4.2.0" + }, + "dependencies": { + "@mdn/browser-compat-data": { + "version": "3.3.14", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-3.3.14.tgz", + "integrity": "sha512-n2RC9d6XatVbWFdHLimzzUJxJ1KY8LdjqrW6YvGPiRmsHkhOUx74/Ct10x5Yo7bC/Jvqx7cDEW8IMPv/+vwEzA==", + "dev": true + }, + "@typescript-eslint/eslint-plugin": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", + "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "4.33.0", + "@typescript-eslint/scope-manager": "4.33.0", + "debug": "^4.3.1", + "functional-red-black-tree": "^1.0.1", + "ignore": "^5.1.8", + "regexpp": "^3.1.0", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/parser": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", + "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", + "dev": true, + "requires": { + "@typescript-eslint/scope-manager": "4.33.0", + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/typescript-estree": "4.33.0", + "debug": "^4.3.1" + } + }, + "@typescript-eslint/scope-manager": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", + "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0" + } + }, + "@typescript-eslint/types": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", + "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", + "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.33.0", + "@typescript-eslint/visitor-keys": "4.33.0", + "debug": "^4.3.1", + "globby": "^11.0.3", + "is-glob": "^4.0.1", + "semver": "^7.3.5", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "4.33.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", + "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", + "dev": true, + "requires": { + "@typescript-eslint/types": "4.33.0", + "eslint-visitor-keys": "^2.0.0" + } + }, + "aria-query": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" + } + }, + "eslint-config-airbnb": { + "version": "18.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-18.2.1.tgz", + "integrity": "sha512-glZNDEZ36VdlZWoxn/bUR1r/sdFKPd1mHPbqUtkctgNG4yT2DLLtJ3D+yCV+jzZCc2V1nBVkmdknOJBZ5Hc0fg==", + "dev": true, + "requires": { + "eslint-config-airbnb-base": "^14.2.1", + "object.assign": "^4.1.2", + "object.entries": "^1.1.2" + }, + "dependencies": { + "eslint-config-airbnb-base": { + "version": "14.2.1", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-14.2.1.tgz", + "integrity": "sha512-GOrQyDtVEc1Xy20U7vsB2yAoB4nBlfH5HZJeatRXHleO+OS5Ot+MWij4Dpltw4/DyIkqUfqz1epfhVR5XWWQPA==", + "dev": true, + "requires": { + "confusing-browser-globals": "^1.0.10", + "object.assign": "^4.1.2", + "object.entries": "^1.1.2" + } + } + } + }, + "eslint-config-airbnb-typescript": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-13.0.1.tgz", + "integrity": "sha512-n7fGBDNV3xSKbWDUES2FfsNAJhuqADcwzshX6ci6qoszUnH6p4dzrLnSFqYkw5Sn7M+aarp2BTf7JDOK88M+bg==", + "dev": true, + "requires": {} + }, + "eslint-plugin-compat": { + "version": "3.13.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-3.13.0.tgz", + "integrity": "sha512-cv8IYMuTXm7PIjMVDN2y4k/KVnKZmoNGHNq27/9dLstOLydKblieIv+oe2BN2WthuXnFNhaNvv3N1Bvl4dbIGA==", + "dev": true, + "requires": { + "@mdn/browser-compat-data": "^3.3.14", + "ast-metadata-inferer": "^0.7.0", + "browserslist": "^4.16.8", + "caniuse-lite": "^1.0.30001251", + "core-js": "^3.16.2", + "find-up": "^5.0.0", + "lodash.memoize": "4.1.2", + "semver": "7.3.5" + } + }, + "eslint-plugin-jest": { + "version": "24.7.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-24.7.0.tgz", + "integrity": "sha512-wUxdF2bAZiYSKBclsUMrYHH6WxiBreNjyDxbRv345TIvPeoCEgPNEn3Sa+ZrSqsf1Dl9SqqSREXMHExlMMu1DA==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "^4.0.1" + } + }, + "eslint-plugin-jsx-a11y": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.4.1.tgz", + "integrity": "sha512-0rGPJBbwHoGNPU73/QCLP/vveMlM1b1Z9PponxO87jfr6tuH5ligXbDT6nHSSzBC8ovX2Z+BQu7Bk5D/Xgq9zg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.11.2", + "aria-query": "^4.2.2", + "array-includes": "^3.1.1", + "ast-types-flow": "^0.0.7", + "axe-core": "^4.0.2", + "axobject-query": "^2.2.0", + "damerau-levenshtein": "^1.0.6", + "emoji-regex": "^9.0.0", + "has": "^1.0.3", + "jsx-ast-utils": "^3.1.0", + "language-tags": "^1.0.5" + } + }, + "eslint-plugin-promise": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.2.0.tgz", + "integrity": "sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw==", + "dev": true, + "requires": {} + }, + "eslint-visitor-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-2.1.0.tgz", + "integrity": "sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==", + "dev": true + }, + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.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-import-resolver-node": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.6.tgz", + "integrity": "sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "resolve": "^1.20.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "eslint-import-resolver-typescript": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-2.7.1.tgz", + "integrity": "sha512-00UbgGwV8bSgUv34igBDbTOtKhqoRMy9bFjNehT40bXg6585PNIct8HhXZ0SybqB9rWtXj9crcku8ndDn/gIqQ==", + "dev": true, + "requires": { + "debug": "^4.3.4", + "glob": "^7.2.0", + "is-glob": "^4.0.3", + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" + } + }, + "eslint-import-resolver-webpack": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-webpack/-/eslint-import-resolver-webpack-0.13.2.tgz", + "integrity": "sha512-XodIPyg1OgE2h5BDErz3WJoK7lawxKTJNhgPNafRST6csC/MZC+L5P6kKqsZGRInpbgc02s/WZMrb4uGJzcuRg==", + "dev": true, + "requires": { + "array-find": "^1.0.0", + "debug": "^3.2.7", + "enhanced-resolve": "^0.9.1", + "find-root": "^1.1.0", + "has": "^1.0.3", + "interpret": "^1.4.0", + "is-core-module": "^2.7.0", + "is-regex": "^1.1.4", + "lodash": "^4.17.21", + "resolve": "^1.20.0", + "semver": "^5.7.1" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + } + } + }, + "eslint-module-utils": { + "version": "2.7.3", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.3.tgz", + "integrity": "sha512-088JEC7O3lDZM9xGe0RerkOMd0EjFl+Yvd1jPWIkMT5u3H9+HC34mWWPnqPrN13gieT9pBOO+Qt07Nb/6TresQ==", + "dev": true, + "requires": { + "debug": "^3.2.7", + "find-up": "^2.1.0" + }, + "dependencies": { + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + } + } + }, + "eslint-plugin-compat": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-compat/-/eslint-plugin-compat-4.0.2.tgz", + "integrity": "sha512-xqvoO54CLTVaEYGMzhu35Wzwk/As7rCvz/2dqwnFiWi0OJccEtGIn+5qq3zqIu9nboXlpdBN579fZcItC73Ycg==", + "dev": true, + "requires": { + "@mdn/browser-compat-data": "^4.1.5", + "ast-metadata-inferer": "^0.7.0", + "browserslist": "^4.16.8", + "caniuse-lite": "^1.0.30001304", + "core-js": "^3.16.2", + "find-up": "^5.0.0", + "lodash.memoize": "4.1.2", + "semver": "7.3.5" + }, + "dependencies": { + "semver": { + "version": "7.3.5", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.5.tgz", + "integrity": "sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ==", + "dev": true, + "requires": { + "lru-cache": "^6.0.0" + } + } + } + }, + "eslint-plugin-import": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.26.0.tgz", + "integrity": "sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==", + "dev": true, + "requires": { + "array-includes": "^3.1.4", + "array.prototype.flat": "^1.2.5", + "debug": "^2.6.9", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.6", + "eslint-module-utils": "^2.7.3", + "has": "^1.0.3", + "is-core-module": "^2.8.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.values": "^1.1.5", + "resolve": "^1.22.0", + "tsconfig-paths": "^3.14.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "eslint-plugin-jest": { + "version": "26.1.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest/-/eslint-plugin-jest-26.1.3.tgz", + "integrity": "sha512-Pju+T7MFpo5VFhFlwrkK/9jRUu18r2iugvgyrWOnnGRaVTFFmFXp+xFJpHyqmjjLmGJPKLeEFLVTAxezkApcpQ==", + "dev": true, + "requires": { + "@typescript-eslint/utils": "^5.10.0" + } + }, + "eslint-plugin-jsx-a11y": { + "version": "6.6.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.6.1.tgz", + "integrity": "sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==", + "dev": true, + "requires": { + "@babel/runtime": "^7.18.9", + "aria-query": "^4.2.2", + "array-includes": "^3.1.5", + "ast-types-flow": "^0.0.7", + "axe-core": "^4.4.3", + "axobject-query": "^2.2.0", + "damerau-levenshtein": "^1.0.8", + "emoji-regex": "^9.2.2", + "has": "^1.0.3", + "jsx-ast-utils": "^3.3.2", + "language-tags": "^1.0.5", + "minimatch": "^3.1.2", + "semver": "^6.3.0" + }, + "dependencies": { + "aria-query": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "eslint-plugin-prettier": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-3.4.1.tgz", + "integrity": "sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==", + "dev": true, + "requires": { + "prettier-linter-helpers": "^1.0.0" + } + }, + "eslint-plugin-promise": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-6.1.1.tgz", + "integrity": "sha512-tjqWDwVZQo7UIPMeDReOpUgHCmCiH+ePnVT+5zVapL0uuHnegBUs2smM13CzOs2Xb5+MHMRFTs9v24yjba4Oig==", + "dev": true, + "requires": {} + }, + "eslint-plugin-react": { + "version": "7.31.11", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.31.11.tgz", + "integrity": "sha512-TTvq5JsT5v56wPa9OYHzsrOlHzKZKjV+aLgS+55NJP/cuzdiQPC7PfYoUjMoxlffKtvijpk7vA/jmuqRb9nohw==", + "dev": true, + "requires": { + "array-includes": "^3.1.6", + "array.prototype.flatmap": "^1.3.1", + "array.prototype.tosorted": "^1.1.1", + "doctrine": "^2.1.0", + "estraverse": "^5.3.0", + "jsx-ast-utils": "^2.4.1 || ^3.0.0", + "minimatch": "^3.1.2", + "object.entries": "^1.1.6", + "object.fromentries": "^2.0.6", + "object.hasown": "^1.1.2", + "object.values": "^1.1.6", + "prop-types": "^15.8.1", + "resolve": "^2.0.0-next.3", + "semver": "^6.3.0", + "string.prototype.matchall": "^4.0.8" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "resolve": { + "version": "2.0.0-next.3", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.3.tgz", + "integrity": "sha512-W8LucSynKUIDu9ylraa7ueVZ7hc0uAgJBxVsQSKOXOyle8a93qXhcz+XAXZ8bIq2d6i4Ehddn6Evt+0/UwKk6Q==", + "dev": true, + "requires": { + "is-core-module": "^2.2.0", + "path-parse": "^1.0.6" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "eslint-plugin-react-hooks": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react-hooks/-/eslint-plugin-react-hooks-4.6.0.tgz", + "integrity": "sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==", + "dev": true, + "requires": {} + }, + "eslint-plugin-sort-keys-fix": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/eslint-plugin-sort-keys-fix/-/eslint-plugin-sort-keys-fix-1.1.2.tgz", + "integrity": "sha512-DNPHFGCA0/hZIsfODbeLZqaGY/+q3vgtshF85r+YWDNCQ2apd9PNs/zL6ttKm0nD1IFwvxyg3YOTI7FHl4unrw==", + "dev": true, + "requires": { + "espree": "^6.1.2", + "esutils": "^2.0.2", + "natural-compare": "^1.4.0", + "requireindex": "~1.2.0" + }, + "dependencies": { + "acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", + "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", + "dev": true + }, + "espree": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-6.2.1.tgz", + "integrity": "sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-jsx": "^5.2.0", + "eslint-visitor-keys": "^1.1.0" + } + } + } + }, + "eslint-plugin-typescript-sort-keys": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-typescript-sort-keys/-/eslint-plugin-typescript-sort-keys-2.1.0.tgz", + "integrity": "sha512-ET7ABypdz19m47QnKynzNfWPi4CTNQ5jQQC1X5d0gojIwblkbGiCa5IilsqzBTmqxZ0yXDqKBO/GBkBFQCOFsg==", + "dev": true, + "requires": { + "@typescript-eslint/experimental-utils": "^5.0.0", + "json-schema": "^0.4.0", + "natural-compare-lite": "^1.4.0" + }, + "dependencies": { + "@typescript-eslint/experimental-utils": { + "version": "5.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-5.25.0.tgz", + "integrity": "sha512-YTe9rmslCh1xAvNa3X+uZe4L2lsyb8V3WIeK9z46nNiPswk/V/0SGLJSfo8W9Hj4R7ak7bolazXGn3DErmb8QA==", + "dev": true, + "requires": { + "@typescript-eslint/utils": "5.25.0" + } + }, + "@typescript-eslint/scope-manager": { + "version": "5.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.25.0.tgz", + "integrity": "sha512-p4SKTFWj+2VpreUZ5xMQsBMDdQ9XdRvODKXN4EksyBjFp2YvQdLkyHqOffakYZPuWJUDNu3jVXtHALDyTv3cww==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.25.0", + "@typescript-eslint/visitor-keys": "5.25.0" + } + }, + "@typescript-eslint/types": { + "version": "5.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.25.0.tgz", + "integrity": "sha512-7fWqfxr0KNHj75PFqlGX24gWjdV/FDBABXL5dyvBOWHpACGyveok8Uj4ipPX/1fGU63fBkzSIycEje4XsOxUFA==", + "dev": true + }, + "@typescript-eslint/typescript-estree": { + "version": "5.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.25.0.tgz", + "integrity": "sha512-MrPODKDych/oWs/71LCnuO7NyR681HuBly2uLnX3r5i4ME7q/yBqC4hW33kmxtuauLTM0OuBOhhkFaxCCOjEEw==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.25.0", + "@typescript-eslint/visitor-keys": "5.25.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" + } + }, + "@typescript-eslint/utils": { + "version": "5.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.25.0.tgz", + "integrity": "sha512-qNC9bhnz/n9Kba3yI6HQgQdBLuxDoMgdjzdhSInZh6NaDnFpTUlwNGxplUFWfY260Ya0TRPvkg9dd57qxrJI9g==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "@typescript-eslint/scope-manager": "5.25.0", + "@typescript-eslint/types": "5.25.0", + "@typescript-eslint/typescript-estree": "5.25.0", + "eslint-scope": "^5.1.1", + "eslint-utils": "^3.0.0" + } + }, + "@typescript-eslint/visitor-keys": { + "version": "5.25.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.25.0.tgz", + "integrity": "sha512-yd26vFgMsC4h2dgX4+LR+GeicSKIfUvZREFLf3DDjZPtqgLx5AJZr6TetMNwFP9hcKreTTeztQYBTNbNoOycwA==", + "dev": true, + "requires": { + "@typescript-eslint/types": "5.25.0", + "eslint-visitor-keys": "^3.3.0" + } + } + } + }, + "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" + }, + "dependencies": { + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + } + } + }, + "eslint-utils": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", + "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", + "dev": true, + "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==", + "dev": true + } + } + }, + "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==", + "dev": true + }, + "espree": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.4.1.tgz", + "integrity": "sha512-XwctdmTO6SIvCzd9810yyNzIrOrqNYV9Koizx4C/mRhf9uq0o4yHoCEU/670pOxOL/MSraektvSAji79kX90Vg==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true, + "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==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, + "eventemitter3": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", + "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", + "dev": true + }, + "events": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", + "integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==", + "dev": true + }, + "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 + } + } }, "execall": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execall/-/execall-1.0.0.tgz", - "integrity": "sha512-/J0Q8CvOvlAdpvhfkD/WnTQ4H1eU0exze2nFGPj/RSC7jpQ0NkKe2r28T5eMkhEEs+fzepMZNy1kVRKNlC04nQ==", - "dev": true, - "requires": { - "clone-regexp": "^1.0.0" - } + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/execall/-/execall-2.0.0.tgz", + "integrity": "sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==", + "dev": true, + "requires": { + "clone-regexp": "^2.1.0" + } + }, + "exit": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/exit/-/exit-0.1.2.tgz", + "integrity": "sha1-BjJjj42HfMghB9MKD/8aF8uhzQw=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + } + } + }, + "expect": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/expect/-/expect-27.5.1.tgz", + "integrity": "sha512-E1q5hSUG2AmYQwQJ041nvgpkODHQvB+RKlB4IYdru6uJsyFTRyZAP463M+1lINorwbqAmUggi6+WwkD8lCS/Dw==", + "dev": true, + "requires": { + "@jest/types": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1" + } + }, + "express": { + "version": "4.18.0", + "resolved": "https://registry.npmjs.org/express/-/express-4.18.0.tgz", + "integrity": "sha512-EJEXxiTQJS3lIPrU1AE2vRuT7X7E+0KBbpm5GSoK524yl0K8X+er8zS2P14E64eqsVNoWbMCT7MpmQ+ErAhgRg==", + "dev": true, + "requires": { + "accepts": "~1.3.8", + "array-flatten": "1.1.1", + "body-parser": "1.20.0", + "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.10.3", + "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": { + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "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==", + "dev": true + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true + } + } + }, + "extend": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", + "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==", + "dev": true + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true + } + } + }, + "extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "requires": { + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + } + }, + "extsprintf": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.4.1.tgz", + "integrity": "sha512-Wrk35e8ydCKDj/ArClo1VrPVmN8zph5V4AtHwIuHhvMXsKf73UT3BOD+azBIW+3wOJ4FhEH7zyaJCFvChjYvMA==", + "dev": true, + "optional": true + }, + "fast-average-color": { + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/fast-average-color/-/fast-average-color-9.3.0.tgz", + "integrity": "sha512-FlPROSqDMOnoBgkFhWMHJODPvpS0Od0WDpedcKq4U/t0JVapGAkblNwxOr75qT+ZNd0dQM4qlgqrtnXbCJ8cNg==" + }, + "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-fifo": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.1.0.tgz", + "integrity": "sha512-Kl29QoNbNvn4nhDsLYjyIAaIqaJB6rBx5p3sL9VjaefJ+eMFBWVZiaoguaoZfzEKr5RhAti0UgM8703akGPJ6g==", + "dev": true }, "fast-glob": { - "version": "2.2.7", - "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", - "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", - "dev": true, - "requires": { - "@mrmlnc/readdir-enhanced": "^2.2.1", - "@nodelib/fs.stat": "^1.1.2", - "glob-parent": "^3.1.0", - "is-glob": "^4.0.0", - "merge2": "^1.2.3", - "micromatch": "^3.1.10" - } + "version": "3.2.11", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.11.tgz", + "integrity": "sha512-xrO3+1bxSo3ZVHAnqzyuewYT6aMFHRAd4Kcs92MAonjwQZLsK9d0SF1IyQ3k5PoirxTW0Oe/RqFgMQ6TcNE5Ew==", + "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==", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "fastest-levenshtein": { + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.12.tgz", + "integrity": "sha512-On2N+BpYJ15xIC974QNVuYGMOlEVt4s0EOI3wwMqOmK1fdDY+FN/zltPV8vosq4ad4c/gJ1KHScUn/6AWIgiow==", + "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==", + "dev": true, + "requires": { + "reusify": "^1.0.4" + } + }, + "faye-websocket": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.4.tgz", + "integrity": "sha512-CzbClwlXAuiRQAlUyfqPgvPoNKTckTPGfwZV4ZdAhVcP2lh9KUxJg2b5GkE7XbjKQ3YJnQ9z6D9ntLAlB+tP8g==", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "fb-watchman": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", + "integrity": "sha512-DkPJKQeY6kKwmuMretBhr7G6Vodr7bFwDYTXIkfG1gjvNpaxBTQV3PbXg6bR1c1UP4jPOX0jHUbbHANL9vRjVg==", + "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==", + "dev": true, + "requires": { + "pend": "~1.2.0" + } }, "file-entry-cache": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-4.0.0.tgz", - "integrity": "sha512-AVSwsnbV8vH/UVbvgEhf3saVQXORNv0ZzSkvkhQIaia5Tia+JhGTaa/ePUSVoPHQyGayQNmYfkzFi3WZV5zcpA==", - "dev": true, - "requires": { - "flat-cache": "^2.0.1" - } + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz", + "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==", + "dev": true, + "requires": { + "flat-cache": "^3.0.4" + } + }, + "file-loader": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-6.2.0.tgz", + "integrity": "sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw==", + "dev": true, + "requires": { + "loader-utils": "^2.0.0", + "schema-utils": "^3.0.0" + } + }, + "filelist": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", + "integrity": "sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==", + "dev": true, + "requires": { + "minimatch": "^5.0.1" + }, + "dependencies": { + "brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0" + } + }, + "minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "requires": { + "brace-expansion": "^2.0.1" + } + } + } }, "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } + "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==", + "dev": true, + "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==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true + } + } + }, + "find-root": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz", + "integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==" }, "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } }, "flat-cache": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", - "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", - "dev": true, - "requires": { - "flatted": "^2.0.0", - "rimraf": "2.6.3", - "write": "1.0.3" - } + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz", + "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==", + "dev": true, + "requires": { + "flatted": "^3.1.0", + "rimraf": "^3.0.2" + } }, "flatted": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", - "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", - "dev": true + "version": "3.2.5", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.5.tgz", + "integrity": "sha512-WIWGi2L3DyTUvUrwRKgGi9TwxQMUEqPOPQBVi71R96jZXJdFskXEmf54BoZaS1kknGODoIGASGEzBUYdyMCBJg==", + "dev": true + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "follow-redirects": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.2.tgz", + "integrity": "sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==" + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==", + "dev": true + }, + "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" + } + }, + "format-duration": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/format-duration/-/format-duration-2.0.0.tgz", + "integrity": "sha512-ARqJ9qXm71pw3SGAY7bibf8lRLvltOXLjWjzzR3UrUjHu1zdeYpA/Z+u+ltdhrfRa440OjEsHNzdmuZViqqQWQ==" + }, + "forwarded": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", + "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "framer-motion": { + "version": "9.1.7", + "resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-9.1.7.tgz", + "integrity": "sha512-nKxBkIO4IPkMEqcBbbATxsVjwPYShKl051yhBv9628iAH6JLeHD0siBHxkL62oQzMC1+GNX73XtPjgP753ufuw==", + "requires": { + "@emotion/is-prop-valid": "^0.8.2", + "tslib": "^2.4.0" + }, + "dependencies": { + "@emotion/is-prop-valid": { + "version": "0.8.8", + "resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz", + "integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==", + "optional": true, + "requires": { + "@emotion/memoize": "0.7.4" + } + }, + "@emotion/memoize": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz", + "integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==", + "optional": true + } + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs-merger": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/fs-merger/-/fs-merger-3.2.1.tgz", + "integrity": "sha512-AN6sX12liy0JE7C2evclwoo0aCG3PFulLjrTLsJpWh/2mM+DinhpSGqYLbHBBbIW1PLRNcFhJG8Axtz8mQW3ug==", + "dev": true, + "requires": { + "broccoli-node-api": "^1.7.0", + "broccoli-node-info": "^2.1.0", + "fs-extra": "^8.0.1", + "fs-tree-diff": "^2.0.1", + "walk-sync": "^2.2.0" + } + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "fs-mkdirp-stream": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs-mkdirp-stream/-/fs-mkdirp-stream-1.0.0.tgz", + "integrity": "sha1-C3gV/DIBxqaeFNuYzgmMFpNSWes=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "through2": "^2.0.3" + }, + "dependencies": { + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + } + } + }, + "fs-monkey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/fs-monkey/-/fs-monkey-1.0.3.tgz", + "integrity": "sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q==", + "dev": true + }, + "fs-tree-diff": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fs-tree-diff/-/fs-tree-diff-2.0.1.tgz", + "integrity": "sha512-x+CfAZ/lJHQqwlD64pYM5QxWjzWhSjroaVsr8PW831zOApL55qPibed0c+xebaLWVr2BnHFoHdrwOv8pzt8R5A==", + "dev": true, + "requires": { + "@types/symlink-or-copy": "^1.2.0", + "heimdalljs-logger": "^0.1.7", + "object-assign": "^4.1.0", + "path-posix": "^1.0.0", + "symlink-or-copy": "^1.1.8" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==" + }, + "function.prototype.name": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.5.tgz", + "integrity": "sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "es-abstract": "^1.19.0", + "functions-have-names": "^1.2.2" + } + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "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==", + "dev": true + }, + "fuse.js": { + "version": "6.6.2", + "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-6.6.2.tgz", + "integrity": "sha512-cJaJkxCCxC8qIIcPBF9yGxY0W/tVZS3uEISDxhYIdtk8OL93pe+6Zj7LjCqVV4dzbqcriOZ+kQ/NE4RXZHsIGA==" + }, + "gauge": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/gauge/-/gauge-4.0.4.tgz", + "integrity": "sha512-f9m+BEN5jkg6a0fZjleidjN51VE1X+mPFQ2DJ0uv1V39oCLCbsGe6yjbBnp7eK7z/+GAon99a3nHuqbuuthyPg==", + "dev": true, + "requires": { + "aproba": "^1.0.3 || ^2.0.0", + "color-support": "^1.1.3", + "console-control-strings": "^1.1.0", + "has-unicode": "^2.0.1", + "signal-exit": "^3.0.7", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1", + "wide-align": "^1.1.5" + } + }, + "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==" + }, + "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==", + "dev": true, + "requires": { + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.3" + } + }, + "get-nonce": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/get-nonce/-/get-nonce-1.0.1.tgz", + "integrity": "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==" + }, + "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-stdin": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", - "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", - "dev": true + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-8.0.0.tgz", + "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", + "dev": true + }, + "get-stream": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz", + "integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==", + "dev": true + }, + "glob": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.0.tgz", + "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } }, "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", + "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, + "requires": { + "is-glob": "^4.0.3" + } + }, + "glob-stream": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/glob-stream/-/glob-stream-6.1.0.tgz", + "integrity": "sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==", + "dev": true, + "requires": { + "extend": "^3.0.0", + "glob": "^7.1.1", + "glob-parent": "^3.1.0", + "is-negated-glob": "^1.0.0", + "ordered-read-streams": "^1.0.0", + "pumpify": "^1.3.5", + "readable-stream": "^2.1.5", + "remove-trailing-separator": "^1.0.1", + "to-absolute-glob": "^2.0.0", + "unique-stream": "^2.0.2" + }, + "dependencies": { + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + } + }, + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "glob-to-regexp": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.4.1.tgz", + "integrity": "sha512-lkX1HJXwyMcprw/5YUZc2s7DrpAiHB21/V+E1rHUrVNokkvB6bqMzT0VfV6/86ZNabt1k14YOIaT7nDvOX3Iiw==", + "dev": true + }, + "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==", + "dev": true, + "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" + } + }, + "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" + } + } + } + }, + "globals": { + "version": "13.19.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.19.0.tgz", + "integrity": "sha512-dkQ957uSRWHw7CFXLUtUHQI3g3aWApYhfNR2O6jn/907riyTYKVBmxYVROkBcY614FSSeSJh7Xm7SrUWCxvJMQ==", + "dev": true, + "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==", + "dev": true, + "optional": true, + "requires": { + "define-properties": "^1.1.3" } - } }, "globby": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", - "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", - "dev": true, - "requires": { - "@types/glob": "^7.1.1", - "array-union": "^1.0.2", - "dir-glob": "^2.2.2", - "fast-glob": "^2.2.6", - "glob": "^7.1.3", - "ignore": "^4.0.3", - "pify": "^4.0.1", - "slash": "^2.0.0" - }, - "dependencies": { - "ignore": { - "version": "4.0.6", - "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", - "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", - "dev": true + "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 + }, + "gonzales-pe": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/gonzales-pe/-/gonzales-pe-4.3.0.tgz", + "integrity": "sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.3" + } + }, + "got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dev": true, + "requires": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + } + }, + "graceful-fs": { + "version": "4.2.10", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.10.tgz", + "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==" + }, + "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==", + "dev": true + }, + "gulp-sort": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/gulp-sort/-/gulp-sort-2.0.0.tgz", + "integrity": "sha1-xnYqLx8N4KP8WVohWZ0/rI26Gso=", + "dev": true, + "requires": { + "through2": "^2.0.1" + }, + "dependencies": { + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + } + } + }, + "gzip-size": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-6.0.0.tgz", + "integrity": "sha512-ax7ZYomf6jqPTQ4+XCpUGyXKHk5WweS+e05MBO4/y3WJ5RkmPXNKvX+bx1behVILVwr6JSQvZAku021CHPXG3Q==", + "dev": true, + "requires": { + "duplexer": "^0.1.2" + } + }, + "handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "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 + }, + "harmony-reflect": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", + "integrity": "sha512-HIp/n38R9kQjDEziXyDTuW3vvoxxyxjxFzXLrBr18uB47GnSt+G9D29fqrpM5ZkspMcPICud3XsBJQ4Y2URg8g==", + "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-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==", + "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 + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true }, - "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 - }, - "html-tags": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz", - "integrity": "sha512-+Il6N8cCo2wB/Vd3gqy/8TZhTD3QvcVeQLCnZiGkGCH3JP28IgGAY41giccp2W4R3jfyJPAP318FQTa1yU7K7g==", - "dev": true - }, - "import-fresh": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", - "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", - "dev": true, - "requires": { - "caller-path": "^2.0.0", - "resolve-from": "^3.0.0" - }, - "dependencies": { - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true + "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==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.1" } - } }, - "import-lazy": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-3.1.0.tgz", - "integrity": "sha512-8/gvXvX2JMn0F+CDlSC4l6kOmVaLOO3XLkksI7CI3Ud95KDYJuYur2b9P/PUt/i/pDAMd/DulQsNbbbmRRsDIQ==", - "dev": true + "has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true }, - "indent-string": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", - "integrity": "sha512-BYqTHXTGUIvg7t1r4sJNKcbDZkL92nkXA8YtRpbjFHRHGDL/NtUeiBJMeE60kIFN/Mg8ESaWQvftaYMGJzQZCQ==", - "dev": true - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", - "dev": true - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } + "has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" } - } }, - "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 + "has-unicode": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/has-unicode/-/has-unicode-2.0.1.tgz", + "integrity": "sha1-4Ob+aijPUROIVeCG0Wkedx3iqLk=", + "dev": true }, - "is-regexp": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", - "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", - "dev": true - }, - "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" - } - }, - "known-css-properties": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.11.0.tgz", - "integrity": "sha512-bEZlJzXo5V/ApNNa5z375mJC6Nrz4vG43UgcSCrg2OHC+yuB6j0iDSrY7RQ/+PRofFB03wNIIt9iXIVLr4wc7w==", - "dev": true - }, - "leven": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", - "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==", - "dev": true - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "requires": { - "chalk": "^2.0.1" - } - }, - "map-obj": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", - "integrity": "sha512-TzQSV2DiMYgoF5RycneKVUzIa9bQsj/B3tTgsE3dOGqlzHnGIDaC7XBE7grnA+8kZPnfqSGFe95VHc2oc0VFUQ==", - "dev": true - }, - "meow": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz", - "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==", - "dev": true, - "requires": { - "camelcase-keys": "^4.0.0", - "decamelize-keys": "^1.0.0", - "loud-rejection": "^1.0.0", - "minimist-options": "^3.0.1", - "normalize-package-data": "^2.3.4", - "read-pkg-up": "^3.0.0", - "redent": "^2.0.0", - "trim-newlines": "^2.0.0", - "yargs-parser": "^10.0.0" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "minimist-options": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", - "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", - "dev": true, - "requires": { - "arrify": "^1.0.1", - "is-plain-obj": "^1.1.0" - } - }, - "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" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", - "dev": true - }, - "parse-json": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", - "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", - "dev": true, - "requires": { - "error-ex": "^1.3.1", - "json-parse-better-errors": "^1.0.1" - } - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", - "dev": true - }, - "path-type": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", - "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", - "dev": true, - "requires": { - "pify": "^3.0.0" - }, - "dependencies": { - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", - "dev": true - } - } - }, - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.1" - } - }, - "postcss-safe-parser": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz", - "integrity": "sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g==", - "dev": true, - "requires": { - "postcss": "^7.0.26" - } - }, - "postcss-scss": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.1.1.tgz", - "integrity": "sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA==", - "dev": true, - "requires": { - "postcss": "^7.0.6" - } - }, - "postcss-selector-parser": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", - "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", - "dev": true, - "requires": { - "dot-prop": "^5.2.0", - "indexes-of": "^1.0.1", - "uniq": "^1.0.1" - } - }, - "postcss-sorting": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-4.1.0.tgz", - "integrity": "sha512-r4T2oQd1giURJdHQ/RMb72dKZCuLOdWx2B/XhXN1Y1ZdnwXsKH896Qz6vD4tFy9xSjpKNYhlZoJmWyhH/7JUQw==", - "dev": true, - "requires": { - "lodash": "^4.17.4", - "postcss": "^7.0.0" - } - }, - "postcss-value-parser": { - "version": "3.3.1", - "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", - "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", - "dev": true - }, - "quick-lru": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", - "integrity": "sha512-tRS7sTgyxMXtLum8L65daJnHUhfDUgboRdcWW2bR9vBfrj2+O5HSMbQOJfJJjIVSPFqbBCF37FpwWXGitDc5tA==", - "dev": true - }, - "read-pkg": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", - "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", - "dev": true, - "requires": { - "load-json-file": "^4.0.0", - "normalize-package-data": "^2.3.2", - "path-type": "^3.0.0" - } - }, - "read-pkg-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", - "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", - "dev": true, - "requires": { - "find-up": "^2.0.0", - "read-pkg": "^3.0.0" - } - }, - "redent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", - "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", - "dev": true, - "requires": { - "indent-string": "^3.0.0", - "strip-indent": "^2.0.0" - } - }, - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "semver": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", - "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", - "dev": true - }, - "slash": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", - "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", - "dev": true - }, - "slice-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", - "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "astral-regex": "^1.0.0", - "is-fullwidth-code-point": "^2.0.0" - } - }, - "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 - }, - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "strip-indent": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", - "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", - "dev": true - }, - "stylelint": { - "version": "9.10.1", - "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-9.10.1.tgz", - "integrity": "sha512-9UiHxZhOAHEgeQ7oLGwrwoDR8vclBKlSX7r4fH0iuu0SfPwFaLkb1c7Q2j1cqg9P7IDXeAV2TvQML/fRQzGBBQ==", - "dev": true, - "requires": { - "autoprefixer": "^9.0.0", - "balanced-match": "^1.0.0", - "chalk": "^2.4.1", - "cosmiconfig": "^5.0.0", - "debug": "^4.0.0", - "execall": "^1.0.0", - "file-entry-cache": "^4.0.0", - "get-stdin": "^6.0.0", - "global-modules": "^2.0.0", - "globby": "^9.0.0", - "globjoin": "^0.1.4", - "html-tags": "^2.0.0", - "ignore": "^5.0.4", - "import-lazy": "^3.1.0", - "imurmurhash": "^0.1.4", - "known-css-properties": "^0.11.0", - "leven": "^2.1.0", - "lodash": "^4.17.4", - "log-symbols": "^2.0.0", - "mathml-tag-names": "^2.0.1", - "meow": "^5.0.0", - "micromatch": "^3.1.10", - "normalize-selector": "^0.2.0", - "pify": "^4.0.0", - "postcss": "^7.0.13", - "postcss-html": "^0.36.0", - "postcss-jsx": "^0.36.0", - "postcss-less": "^3.1.0", - "postcss-markdown": "^0.36.0", - "postcss-media-query-parser": "^0.2.3", - "postcss-reporter": "^6.0.0", - "postcss-resolve-nested-selector": "^0.1.1", - "postcss-safe-parser": "^4.0.0", - "postcss-sass": "^0.3.5", - "postcss-scss": "^2.0.0", - "postcss-selector-parser": "^3.1.0", - "postcss-syntax": "^0.36.2", - "postcss-value-parser": "^3.3.0", - "resolve-from": "^4.0.0", - "signal-exit": "^3.0.2", - "slash": "^2.0.0", - "specificity": "^0.4.1", - "string-width": "^3.0.0", - "style-search": "^0.1.0", - "sugarss": "^2.0.0", - "svg-tags": "^1.0.0", - "table": "^5.0.0" - } - }, - "stylelint-order": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-2.2.1.tgz", - "integrity": "sha512-019KBV9j8qp1MfBjJuotse6MgaZqGVtXMc91GU9MsS9Feb+jYUvUU3Z8XiClqPdqJZQ0ryXQJGg3U3PcEjXwfg==", - "dev": true, - "requires": { - "lodash": "^4.17.10", - "postcss": "^7.0.2", - "postcss-sorting": "^4.1.0" - } - }, - "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" - } - }, - "table": { - "version": "5.4.6", - "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", - "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", - "dev": true, - "requires": { - "ajv": "^6.10.2", - "lodash": "^4.17.14", - "slice-ansi": "^2.1.0", - "string-width": "^3.0.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "trim-newlines": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", - "integrity": "sha512-MTBWv3jhVjTU7XR3IQHllbiJs8sc75a80OEhB6or/q7pLTWgQ0bMGQXXYQSrSuXe6WiKWDZ5txXY5P59a/coVA==", - "dev": true - }, - "yargs-parser": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", - "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", - "dev": true, - "requires": { - "camelcase": "^4.1.0" - } - } - } - }, - "stylelint-config-recommended": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-7.0.0.tgz", - "integrity": "sha512-yGn84Bf/q41J4luis1AZ95gj0EQwRX8lWmGmBwkwBNSkpGSpl66XcPTulxGa/Z91aPoNGuIGBmFkcM1MejMo9Q==", - "dev": true, - "requires": {} - }, - "stylelint-config-recommended-scss": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-6.0.0.tgz", - "integrity": "sha512-6QOe2/OzXV2AP5FE12A7+qtKdZik7Saf42SMMl84ksVBBPpTdrV+9HaCbPYiRMiwELY9hXCVdH4wlJ+YJb5eig==", - "dev": true, - "requires": { - "postcss-scss": "^4.0.2", - "stylelint-config-recommended": "^7.0.0", - "stylelint-scss": "^4.0.0" - } - }, - "stylelint-config-standard": { - "version": "25.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-25.0.0.tgz", - "integrity": "sha512-21HnP3VSpaT1wFjFvv9VjvOGDtAviv47uTp3uFmzcN+3Lt+RYRv6oAplLaV51Kf792JSxJ6svCJh/G18E9VnCA==", - "dev": true, - "requires": { - "stylelint-config-recommended": "^7.0.0" - } - }, - "stylelint-config-standard-scss": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/stylelint-config-standard-scss/-/stylelint-config-standard-scss-4.0.0.tgz", - "integrity": "sha512-xizu8PTEyB6zYXBiVg6VtvUYn9m57x+6ZtaOdaxsfpbe5eagLPGNlbYnKfm/CfN69ArUpnwR6LjgsTHzlGbtXQ==", - "dev": true, - "requires": { - "stylelint-config-recommended-scss": "^6.0.0", - "stylelint-config-standard": "^25.0.0" - } - }, - "stylelint-config-styled-components": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/stylelint-config-styled-components/-/stylelint-config-styled-components-0.1.1.tgz", - "integrity": "sha512-z5Xz/9GmvxO6e/DLzBMwkB85zHxEEjN6K7Cj80Bi+o/9vR9eS3GX3E9VuMnX9WLFYulqbqLtTapGGY28JBiy9Q==", - "dev": true - }, - "stylelint-order": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-5.0.0.tgz", - "integrity": "sha512-OWQ7pmicXufDw5BlRqzdz3fkGKJPgLyDwD1rFY3AIEfIH/LQY38Vu/85v8/up0I+VPiuGRwbc2Hg3zLAsJaiyw==", - "dev": true, - "requires": { - "postcss": "^8.3.11", - "postcss-sorting": "^7.0.1" - } - }, - "stylelint-processor-styled-components": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/stylelint-processor-styled-components/-/stylelint-processor-styled-components-1.10.0.tgz", - "integrity": "sha512-g4HpN9rm0JD0LoHuIOcd/FIjTZCJ0ErQ+dC3VTxp+dSvnkV+MklKCCmCQEdz5K5WxF4vPuzfVgdbSDuPYGZhoA==", - "dev": true, - "requires": { - "@babel/parser": "^7.8.3", - "@babel/traverse": "^7.8.3", - "micromatch": "^4.0.2", - "postcss": "^7.0.26" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.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 - } - } - }, - "stylelint-scss": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-4.3.0.tgz", - "integrity": "sha512-GvSaKCA3tipzZHoz+nNO7S02ZqOsdBzMiCx9poSmLlb3tdJlGddEX/8QzCOD8O7GQan9bjsvLMsO5xiw6IhhIQ==", - "dev": true, - "requires": { - "lodash": "^4.17.21", - "postcss-media-query-parser": "^0.2.3", - "postcss-resolve-nested-selector": "^0.1.1", - "postcss-selector-parser": "^6.0.6", - "postcss-value-parser": "^4.1.0" - } - }, - "stylis": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz", - "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==" - }, - "sugarss": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-2.0.0.tgz", - "integrity": "sha512-WfxjozUk0UVA4jm+U1d736AUpzSrNsQcIbyOkoE364GrtWmIrFdk5lksEupgWMD4VaT/0kVx1dobpiDumSgmJQ==", - "dev": true, - "requires": { - "postcss": "^7.0.2" - }, - "dependencies": { - "picocolors": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", - "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", - "dev": true - }, - "postcss": { - "version": "7.0.39", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", - "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", - "dev": true, - "requires": { - "picocolors": "^0.2.1", - "source-map": "^0.6.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 - } - } - }, - "sumchecker": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", - "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", - "dev": true, - "requires": { - "debug": "^4.1.0" - } - }, - "superjson": { - "version": "1.11.0", - "resolved": "https://registry.npmjs.org/superjson/-/superjson-1.11.0.tgz", - "integrity": "sha512-6PfAg1FKhqkwWvPb2uXhH4MkMttdc17eJ91+Aoz4s1XUEDZFmLfFx/xVA3wgkPxAGy5dpozgGdK6V/n20Wj9yg==", - "requires": { - "copy-anything": "^3.0.2" - } - }, - "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==", - "dev": true, - "requires": { - "has-flag": "^4.0.0" - } - }, - "supports-hyperlinks": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", - "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", - "dev": true, - "requires": { - "has-flag": "^4.0.0", - "supports-color": "^7.0.0" - } - }, - "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==" - }, - "svg-tags": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", - "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", - "dev": true - }, - "svgo": { - "version": "2.8.0", - "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", - "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", - "dev": true, - "requires": { - "@trysound/sax": "0.2.0", - "commander": "^7.2.0", - "css-select": "^4.1.3", - "css-tree": "^1.1.3", - "csso": "^4.2.0", - "picocolors": "^1.0.0", - "stable": "^0.1.8" - }, - "dependencies": { - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true - } - } - }, - "swiper": { - "version": "9.3.1", - "resolved": "https://registry.npmjs.org/swiper/-/swiper-9.3.1.tgz", - "integrity": "sha512-YBDf0DLBLO7O4rwYHfz+HltkY4sDwKSbRf1it56rngpkYHxiKg0NkPMXAFmw2nGvMNQJwV14Dse47hQIifJzzA==", - "requires": { - "ssr-window": "^4.0.2" - } - }, - "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 - }, - "symlink-or-copy": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/symlink-or-copy/-/symlink-or-copy-1.3.1.tgz", - "integrity": "sha512-0K91MEXFpBUaywiwSSkmKjnGcasG/rVBXFLJz5DrgGabpYD6N+3yZrfD6uUIfpuTu65DZLHi7N8CizHc07BPZA==", - "dev": true - }, - "tabbable": { - "version": "6.1.1", - "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.1.1.tgz", - "integrity": "sha512-4kl5w+nCB44EVRdO0g/UGoOp3vlwgycUVtkk/7DPyeLZUCuNFFKCFG6/t/DgHLrUPHjrZg6s5tNm+56Q2B0xyg==" - }, - "table": { - "version": "6.8.0", - "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", - "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", - "dev": true, - "requires": { - "ajv": "^8.0.1", - "lodash.truncate": "^4.4.2", - "slice-ansi": "^4.0.0", - "string-width": "^4.2.3", - "strip-ansi": "^6.0.1" - }, - "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 - }, - "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, - "requires": { - "ansi-styles": "^4.0.0", - "astral-regex": "^2.0.0", - "is-fullwidth-code-point": "^3.0.0" - } - } - } - }, - "tapable": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", - "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", - "dev": true - }, - "tar": { - "version": "6.1.13", - "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz", - "integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==", - "dev": true, - "requires": { - "chownr": "^2.0.0", - "fs-minipass": "^2.0.0", - "minipass": "^4.0.0", - "minizlib": "^2.1.1", - "mkdirp": "^1.0.3", - "yallist": "^4.0.0" - }, - "dependencies": { - "minipass": { - "version": "4.2.5", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.5.tgz", - "integrity": "sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q==", - "dev": true - }, - "mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "dev": true - } - } - }, - "teex": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", - "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", - "dev": true, - "requires": { - "streamx": "^2.12.5" - } - }, - "temp-file": { - "version": "3.4.0", - "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz", - "integrity": "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==", - "dev": true, - "requires": { - "async-exit-hook": "^2.0.1", - "fs-extra": "^10.0.0" - }, - "dependencies": { - "fs-extra": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", - "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.0", - "jsonfile": "^6.0.1", - "universalify": "^2.0.0" - } - }, - "jsonfile": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", - "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.6", - "universalify": "^2.0.0" - } - }, - "universalify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", - "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", - "dev": true - } - } - }, - "terminal-link": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", - "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", - "dev": true, - "requires": { - "ansi-escapes": "^4.2.1", - "supports-hyperlinks": "^2.0.0" - } - }, - "terser": { - "version": "5.17.7", - "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.7.tgz", - "integrity": "sha512-/bi0Zm2C6VAexlGgLlVxA0P2lru/sdLyfCVaRMfKVo9nWxbmz7f/sD8VPybPeSUJaJcwmCJis9pBIhcVcG1QcQ==", - "dev": true, - "requires": { - "@jridgewell/source-map": "^0.3.3", - "acorn": "^8.8.2", - "commander": "^2.20.0", - "source-map-support": "~0.5.20" - }, - "dependencies": { - "commander": { - "version": "2.20.3", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", - "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", - "dev": true - } - } - }, - "terser-webpack-plugin": { - "version": "5.3.9", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", - "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", - "dev": true, - "requires": { - "@jridgewell/trace-mapping": "^0.3.17", - "jest-worker": "^27.4.5", - "schema-utils": "^3.1.1", - "serialize-javascript": "^6.0.1", - "terser": "^5.16.8" - } - }, - "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": { - "@istanbuljs/schema": "^0.1.2", - "glob": "^7.1.4", - "minimatch": "^3.0.4" - } - }, - "text-table": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", - "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", - "dev": true - }, - "throat": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", - "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", - "dev": true - }, - "through": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", - "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", - "dev": true - }, - "through2": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", - "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", - "dev": true, - "requires": { - "readable-stream": "3" - }, - "dependencies": { - "readable-stream": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", - "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - } - } - } - }, - "through2-filter": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", - "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", - "dev": true, - "requires": { - "through2": "~2.0.0", - "xtend": "~4.0.0" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "thunky": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", - "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", - "dev": true - }, - "tmp": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", - "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", - "dev": true, - "requires": { - "rimraf": "^3.0.0" - } - }, - "tmp-promise": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", - "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", - "dev": true, - "requires": { - "tmp": "^0.2.0" - } - }, - "tmpl": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", - "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", - "dev": true - }, - "to-absolute-glob": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", - "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", - "dev": true, - "requires": { - "is-absolute": "^1.0.0", - "is-negated-glob": "^1.0.0" - } - }, - "to-fast-properties": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", - "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", - "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", - "dev": true, - "requires": { - "is-number": "^7.0.0" - } - }, - "to-through": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", - "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", - "dev": true, - "requires": { - "through2": "^2.0.3" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "toidentifier": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", - "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true - }, - "totalist": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", - "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==", - "dev": true - }, - "tough-cookie": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", - "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", - "dev": true, - "requires": { - "psl": "^1.1.33", - "punycode": "^2.1.1", - "universalify": "^0.1.2" - } - }, - "tr46": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", - "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", - "dev": true, - "requires": { - "punycode": "^2.1.1" - } - }, - "tree-kill": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", - "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", - "dev": true - }, - "trim": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ==", - "dev": true - }, - "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 - }, - "trim-trailing-lines": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz", - "integrity": "sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==", - "dev": true - }, - "trough": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", - "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", - "dev": true - }, - "truncate-utf8-bytes": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", - "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", - "dev": true, - "requires": { - "utf8-byte-length": "^1.0.1" - } - }, - "ts-jest": { - "version": "27.1.4", - "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.4.tgz", - "integrity": "sha512-qjkZlVPWVctAezwsOD1OPzbZ+k7zA5z3oxII4dGdZo5ggX/PL7kvwTM0pXTr10fAtbiVpJaL3bWd502zAhpgSQ==", - "dev": true, - "requires": { - "bs-logger": "0.x", - "fast-json-stable-stringify": "2.x", - "jest-util": "^27.0.0", - "json5": "2.x", - "lodash.memoize": "4.x", - "make-error": "1.x", - "semver": "7.x", - "yargs-parser": "20.x" - } - }, - "ts-loader": { - "version": "9.2.8", - "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.2.8.tgz", - "integrity": "sha512-gxSak7IHUuRtwKf3FIPSW1VpZcqF9+MBrHOvBp9cjHh+525SjtCIJKVGjRKIAfxBwDGDGCFF00rTfzB1quxdSw==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.0.0", - "micromatch": "^4.0.0", - "semver": "^7.3.4" - }, - "dependencies": { - "enhanced-resolve": { - "version": "5.9.2", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.2.tgz", - "integrity": "sha512-GIm3fQfwLJ8YZx2smuHpBKkXC1yOk+OBEmKckVyL0i/ea8mqDEykK3ld5dgH1QYPNyT/lIllxV2LULnxCHaHkA==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - } - } - }, - "ts-node": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", - "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", - "dev": true, - "requires": { - "@cspotcode/source-map-support": "0.7.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.0", - "yn": "3.1.1" - }, - "dependencies": { - "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 - } - } - }, - "tsconfig-paths": { - "version": "3.14.1", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", - "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", - "dev": true, - "requires": { - "@types/json5": "^0.0.29", - "json5": "^1.0.1", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - }, - "dependencies": { - "json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", - "dev": true - } - } - }, - "tsconfig-paths-webpack-plugin": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.0.0.tgz", - "integrity": "sha512-fw/7265mIWukrSHd0i+wSwx64kYUSAKPfxRDksjKIYTxSAp9W9/xcZVBF4Kl0eqQd5eBpAQ/oQrc5RyM/0c1GQ==", - "dev": true, - "requires": { - "chalk": "^4.1.0", - "enhanced-resolve": "^5.7.0", - "tsconfig-paths": "^4.0.0" - }, - "dependencies": { - "enhanced-resolve": { - "version": "5.10.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", - "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - }, - "strip-bom": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", - "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", - "dev": true - }, - "tsconfig-paths": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.1.0.tgz", - "integrity": "sha512-AHx4Euop/dXFC+Vx589alFba8QItjF+8hf8LtmuiCwHyI4rHXQtOOENaM8kvYf5fR0dRChy3wzWIZ9WbB7FWow==", - "dev": true, - "requires": { - "json5": "^2.2.1", - "minimist": "^1.2.6", - "strip-bom": "^3.0.0" - } - } - } - }, - "tslib": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", - "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" - }, - "tsutils": { - "version": "3.21.0", - "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", - "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", - "dev": true, - "requires": { - "tslib": "^1.8.1" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", - "dev": true - } - } - }, - "type-check": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", - "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", - "dev": true, - "requires": { - "prelude-ls": "^1.2.1" - } - }, - "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 - }, - "type-fest": { - "version": "0.20.2", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", - "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", - "dev": true - }, - "type-is": { - "version": "1.6.18", - "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", - "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", - "dev": true, - "requires": { - "media-typer": "0.3.0", - "mime-types": "~2.1.24" - } - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "typedarray-to-buffer": { - "version": "3.1.5", - "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", - "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", - "dev": true, - "requires": { - "is-typedarray": "^1.0.0" - } - }, - "typescript": { - "version": "4.8.4", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", - "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", - "dev": true - }, - "typescript-plugin-styled-components": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/typescript-plugin-styled-components/-/typescript-plugin-styled-components-2.0.0.tgz", - "integrity": "sha512-Wu7F96dwuphgiACHfu63vTbRRg6tkPwLnpFJwdxM70Y0PLfeKLRnvs2Yo5MAySMwE120ODMKk9W4TtJgY1ZumA==", - "dev": true, - "requires": {} - }, - "unbox-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", - "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", - "dev": true, - "requires": { - "call-bind": "^1.0.2", - "has-bigints": "^1.0.2", - "has-symbols": "^1.0.3", - "which-boxed-primitive": "^1.0.2" - } - }, - "unc-path-regex": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", - "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", - "dev": true - }, - "underscore.string": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz", - "integrity": "sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ==", - "dev": true, - "requires": { - "sprintf-js": "^1.1.1", - "util-deprecate": "^1.0.2" - } - }, - "unherit": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", - "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", - "dev": true, - "requires": { - "inherits": "^2.0.0", - "xtend": "^4.0.0" - } - }, - "unified": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/unified/-/unified-7.1.0.tgz", - "integrity": "sha512-lbk82UOIGuCEsZhPj8rNAkXSDXd6p0QLzIuSsCdxrqnqU56St4eyOB+AlXsVgVeRmetPTYydIuvFfpDIed8mqw==", - "dev": true, - "requires": { - "@types/unist": "^2.0.0", - "@types/vfile": "^3.0.0", - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^1.1.0", - "trough": "^1.0.0", - "vfile": "^3.0.0", - "x-is-string": "^0.1.0" - }, - "dependencies": { - "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 - } - } - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", - "dev": true - } - } - }, - "uniq": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", - "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", - "dev": true - }, - "unique-stream": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", - "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", - "dev": true, - "requires": { - "json-stable-stringify-without-jsonify": "^1.0.1", - "through2-filter": "^3.0.0" - } - }, - "unist-util-find-all-after": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-1.0.5.tgz", - "integrity": "sha512-lWgIc3rrTMTlK1Y0hEuL+k+ApzFk78h+lsaa2gHf63Gp5Ww+mt11huDniuaoq1H+XMK2lIIjjPkncxXcDp3QDw==", - "dev": true, - "requires": { - "unist-util-is": "^3.0.0" - } - }, - "unist-util-is": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", - "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==", - "dev": true - }, - "unist-util-remove-position": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz", - "integrity": "sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==", - "dev": true, - "requires": { - "unist-util-visit": "^1.1.0" - } - }, - "unist-util-stringify-position": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", - "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==", - "dev": true - }, - "unist-util-visit": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", - "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", - "dev": true, - "requires": { - "unist-util-visit-parents": "^2.0.0" - } - }, - "unist-util-visit-parents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", - "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", - "dev": true, - "requires": { - "unist-util-is": "^3.0.0" - } - }, - "universalify": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", - "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", - "dev": true - }, - "unixify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unixify/-/unixify-1.0.0.tgz", - "integrity": "sha1-OmQcjC/7zk2mg6XHDwOkYpQMIJA=", - "dev": true, - "requires": { - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "unpipe": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", - "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", - "dev": true - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", - "dev": true, - "requires": { - "isarray": "1.0.0" - } + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" } - } }, "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", - "dev": true - } - } - }, - "unzip-crx-3": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/unzip-crx-3/-/unzip-crx-3-0.2.0.tgz", - "integrity": "sha512-0+JiUq/z7faJ6oifVB5nSwt589v1KCduqIJupNVDoWSXZtWDmjDGO3RAEOvwJ07w90aoXoP4enKsR7ecMrJtWQ==", - "dev": true, - "requires": { - "jszip": "^3.1.0", - "mkdirp": "^0.5.1", - "yaku": "^0.16.6" - } - }, - "update-browserslist-db": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", - "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", - "requires": { - "escalade": "^3.1.1", - "picocolors": "^1.0.0" - } - }, - "uri-js": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", - "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url-loader": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", - "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", - "dev": true, - "requires": { - "loader-utils": "^2.0.0", - "mime-types": "^2.1.27", - "schema-utils": "^3.0.0" - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "use-callback-ref": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.0.tgz", - "integrity": "sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==", - "requires": { - "tslib": "^2.0.0" - } - }, - "use-composed-ref": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.3.0.tgz", - "integrity": "sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==", - "requires": {} - }, - "use-isomorphic-layout-effect": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", - "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", - "requires": {} - }, - "use-latest": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.2.1.tgz", - "integrity": "sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==", - "requires": { - "use-isomorphic-layout-effect": "^1.1.1" - } - }, - "use-sidecar": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", - "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", - "requires": { - "detect-node-es": "^1.1.0", - "tslib": "^2.0.0" - } - }, - "use-sync-external-store": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", - "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", - "requires": {} - }, - "utf8-byte-length": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", - "integrity": "sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==", - "dev": true - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "utila": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", - "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", - "dev": true - }, - "utils-merge": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", - "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", - "dev": true - }, - "uuid": { - "version": "8.3.2", - "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", - "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", - "dev": true - }, - "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 - }, - "v8-compile-cache-lib": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", - "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", - "dev": true - }, - "v8-to-istanbul": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", - "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", - "dev": true, - "requires": { - "@types/istanbul-lib-coverage": "^2.0.1", - "convert-source-map": "^1.6.0", - "source-map": "^0.7.3" - } - }, - "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": { - "spdx-correct": "^3.0.0", - "spdx-expression-parse": "^3.0.0" - } - }, - "value-or-function": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", - "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", - "dev": true - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true - }, - "verror": { - "version": "1.10.1", - "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", - "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", - "dev": true, - "optional": true, - "requires": { - "assert-plus": "^1.0.0", - "core-util-is": "1.0.2", - "extsprintf": "^1.2.0" - }, - "dependencies": { - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true, - "optional": true - } - } - }, - "vfile": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-3.0.1.tgz", - "integrity": "sha512-y7Y3gH9BsUSdD4KzHsuMaCzRjglXN0W2EcMf0gpvu6+SbsGhMje7xDc8AEoeXy6mIwCKMI6BkjMsRjzQbhMEjQ==", - "dev": true, - "requires": { - "is-buffer": "^2.0.0", - "replace-ext": "1.0.0", - "unist-util-stringify-position": "^1.0.0", - "vfile-message": "^1.0.0" - }, - "dependencies": { - "is-buffer": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", - "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } }, - "replace-ext": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", - "dev": true + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true }, - "vfile-message": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz", - "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==", - "dev": true, - "requires": { - "unist-util-stringify-position": "^1.1.1" - } - } - } - }, - "vfile-location": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.6.tgz", - "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==", - "dev": true - }, - "vfile-message": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.2.tgz", - "integrity": "sha512-QjSNP6Yxzyycd4SVOtmKKyTsSvClqBPJcd00Z0zuPj3hOIjg0rUPG6DbFGPvUKRgYyaIWLPKpuEclcuvb3H8qA==", - "dev": true, - "requires": { - "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^3.0.0" - }, - "dependencies": { - "unist-util-stringify-position": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.2.tgz", - "integrity": "sha512-7A6eiDCs9UtjcwZOcCpM4aPII3bAAGv13E96IkawkOAW0OhH+yRxtY0lzo8KiHpzEMfH7Q+FizUmwp8Iqy5EWg==", - "dev": true, - "requires": { - "@types/unist": "^2.0.0" - } - } - } - }, - "vinyl": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", - "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", - "dev": true, - "requires": { - "clone": "^2.1.1", - "clone-buffer": "^1.0.0", - "clone-stats": "^1.0.0", - "cloneable-readable": "^1.0.0", - "remove-trailing-separator": "^1.0.1", - "replace-ext": "^1.0.0" - }, - "dependencies": { - "clone": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", - "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", - "dev": true - } - } - }, - "vinyl-fs": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", - "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", - "dev": true, - "requires": { - "fs-mkdirp-stream": "^1.0.0", - "glob-stream": "^6.1.0", - "graceful-fs": "^4.0.0", - "is-valid-glob": "^1.0.0", - "lazystream": "^1.0.0", - "lead": "^1.0.0", - "object.assign": "^4.0.4", - "pumpify": "^1.3.5", - "readable-stream": "^2.3.3", - "remove-bom-buffer": "^3.0.0", - "remove-bom-stream": "^1.2.0", - "resolve-options": "^1.1.0", - "through2": "^2.0.0", - "to-through": "^2.0.0", - "value-or-function": "^3.0.0", - "vinyl": "^2.0.0", - "vinyl-sourcemap": "^1.1.0" - }, - "dependencies": { - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - } - } - }, - "vinyl-sourcemap": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", - "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", - "dev": true, - "requires": { - "append-buffer": "^1.0.2", - "convert-source-map": "^1.5.0", - "graceful-fs": "^4.1.6", - "normalize-path": "^2.1.1", - "now-and-later": "^2.0.0", - "remove-bom-buffer": "^3.0.0", - "vinyl": "^2.0.0" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "void-elements": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", - "integrity": "sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=" - }, - "vue-template-compiler": { - "version": "2.6.14", - "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.14.tgz", - "integrity": "sha512-ODQS1SyMbjKoO1JBJZojSw6FE4qnh9rIpUZn2EUT86FKizx9uH5z6uXiIrm4/Nb/gwxTi/o17ZDEGWAXHvtC7g==", - "dev": true, - "requires": { - "de-indent": "^1.0.2", - "he": "^1.1.0" - } - }, - "w3c-hr-time": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", - "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", - "dev": true, - "requires": { - "browser-process-hrtime": "^1.0.0" - } - }, - "w3c-xmlserializer": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", - "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", - "dev": true, - "requires": { - "xml-name-validator": "^3.0.0" - } - }, - "walk-sync": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/walk-sync/-/walk-sync-2.2.0.tgz", - "integrity": "sha512-IC8sL7aB4/ZgFcGI2T1LczZeFWZ06b3zoHH7jBPyHxOtIIz1jppWHjjEXkOFvFojBVAK9pV7g47xOZ4LW3QLfg==", - "dev": true, - "requires": { - "@types/minimatch": "^3.0.3", - "ensure-posix-path": "^1.1.0", - "matcher-collection": "^2.0.0", - "minimatch": "^3.0.4" - } - }, - "walker": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", - "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", - "dev": true, - "requires": { - "makeerror": "1.0.12" - } - }, - "watchboy": { - "version": "0.4.3", - "resolved": "https://registry.npmjs.org/watchboy/-/watchboy-0.4.3.tgz", - "integrity": "sha512-GHs1HxwvxSMBsqd/WfTOZhj5gBdMqf5HQpfgtKxDfZRxrlYPDdVLRB61LCeRzJaWANmvSIMlfmRVDwVmJFgAKA==", - "dev": true, - "requires": { - "lodash.difference": "^4.5.0", - "micromatch": "^4.0.2", - "pify": "^4.0.1", - "unixify": "^1.0.0" - }, - "dependencies": { - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - } - } - }, - "watchpack": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", - "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", - "dev": true, - "requires": { - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.1.2" - } - }, - "wbuf": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", - "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", - "dev": true, - "requires": { - "minimalistic-assert": "^1.0.0" - } - }, - "wcwidth": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", - "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", - "dev": true, - "requires": { - "defaults": "^1.0.3" - } - }, - "webidl-conversions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", - "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", - "dev": true - }, - "webpack": { - "version": "5.85.0", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.85.0.tgz", - "integrity": "sha512-7gazTiYqwo5OSqwH1tigLDL2r3qDeP2dOKYgd+LlXpsUMqDTklg6tOghexqky0/+6QY38kb/R/uRPUleuL43zg==", - "dev": true, - "requires": { - "@types/eslint-scope": "^3.7.3", - "@types/estree": "^1.0.0", - "@webassemblyjs/ast": "^1.11.5", - "@webassemblyjs/wasm-edit": "^1.11.5", - "@webassemblyjs/wasm-parser": "^1.11.5", - "acorn": "^8.7.1", - "acorn-import-assertions": "^1.9.0", - "browserslist": "^4.14.5", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^5.14.1", - "es-module-lexer": "^1.2.1", - "eslint-scope": "5.1.1", - "events": "^3.2.0", - "glob-to-regexp": "^0.4.1", - "graceful-fs": "^4.2.9", - "json-parse-even-better-errors": "^2.3.1", - "loader-runner": "^4.2.0", - "mime-types": "^2.1.27", - "neo-async": "^2.6.2", - "schema-utils": "^3.1.2", - "tapable": "^2.1.1", - "terser-webpack-plugin": "^5.3.7", - "watchpack": "^2.4.0", - "webpack-sources": "^3.2.3" - }, - "dependencies": { - "enhanced-resolve": { - "version": "5.14.1", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.14.1.tgz", - "integrity": "sha512-Vklwq2vDKtl0y/vtwjSesgJ5MYS7Etuk5txS8VdKL4AOS1aUlD96zqIfsOSLQsdv3xgMRbtkWM8eG9XDfKUPow==", - "dev": true, - "requires": { - "graceful-fs": "^4.2.4", - "tapable": "^2.2.0" - } - } - } - }, - "webpack-bundle-analyzer": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.5.0.tgz", - "integrity": "sha512-GUMZlM3SKwS8Z+CKeIFx7CVoHn3dXFcUAjT/dcZQQmfSZGvitPfMob2ipjai7ovFFqPvTqkEZ/leL4O0YOdAYQ==", - "dev": true, - "requires": { - "acorn": "^8.0.4", - "acorn-walk": "^8.0.0", - "chalk": "^4.1.0", - "commander": "^7.2.0", - "gzip-size": "^6.0.0", - "lodash": "^4.17.20", - "opener": "^1.5.2", - "sirv": "^1.0.7", - "ws": "^7.3.1" - }, - "dependencies": { - "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 + "heimdalljs": { + "version": "0.2.6", + "resolved": "https://registry.npmjs.org/heimdalljs/-/heimdalljs-0.2.6.tgz", + "integrity": "sha512-o9bd30+5vLBvBtzCPwwGqpry2+n0Hi6H1+qwt6y+0kwRHGGF8TFIhJPmnuM0xO97zaKrDZMwO/V56fAnn8m/tA==", + "dev": true, + "requires": { + "rsvp": "~3.2.1" + }, + "dependencies": { + "rsvp": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-3.2.1.tgz", + "integrity": "sha1-B8tKXfJa3Z6Cbrxn3Mn9idsn2Eo=", + "dev": true + } + } }, - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true - } - } - }, - "webpack-cli": { - "version": "4.9.2", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.9.2.tgz", - "integrity": "sha512-m3/AACnBBzK/kMTcxWHcZFPrw/eQuY4Df1TxvIWfWM2x7mRqBQCqKEd96oCUa9jkapLBaFfRce33eGDb4Pr7YQ==", - "dev": true, - "requires": { - "@discoveryjs/json-ext": "^0.5.0", - "@webpack-cli/configtest": "^1.1.1", - "@webpack-cli/info": "^1.4.1", - "@webpack-cli/serve": "^1.6.1", - "colorette": "^2.0.14", - "commander": "^7.0.0", - "execa": "^5.0.0", - "fastest-levenshtein": "^1.0.12", - "import-local": "^3.0.2", - "interpret": "^2.2.0", - "rechoir": "^0.7.0", - "webpack-merge": "^5.7.3" - }, - "dependencies": { - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true + "heimdalljs-logger": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/heimdalljs-logger/-/heimdalljs-logger-0.1.10.tgz", + "integrity": "sha512-pO++cJbhIufVI/fmB/u2Yty3KJD0TqNPecehFae0/eps0hkZ3b4Zc/PezUMOpYuHFQbA7FxHZxa305EhmjLj4g==", + "dev": true, + "requires": { + "debug": "^2.2.0", + "heimdalljs": "^0.2.6" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "history": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/history/-/history-5.3.0.tgz", + "integrity": "sha512-ZqaKwjjrAYUYfLG+htGaIIZ4nioX2L70ZUMIFysS3xvBsSG4x/n1V6TXV3N8ZYNuFGlDirFg32T7B6WOUPDYcQ==", + "requires": { + "@babel/runtime": "^7.7.6" + } + }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } + } + }, + "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" + } + }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "html-encoding-sniffer": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-2.0.1.tgz", + "integrity": "sha512-D5JbOMBIR/TVZkubHT+OyT2705QvogUW4IBn6nHd756OwieSF9aDYFj4dv6HHEVGYbHaLETa3WggZYWWMyy3ZQ==", + "dev": true, + "requires": { + "whatwg-encoding": "^1.0.5" + } + }, + "html-entities": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.3.3.tgz", + "integrity": "sha512-DV5Ln36z34NNTDgnz0EWGBLZENelNAtkiFA4kyNOG2tDI6Mz1uSWiq1wAKdyjnJwyDiDO7Fa2SO1CTxPXL8VxA==", + "dev": true + }, + "html-escaper": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", + "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==" + }, + "html-minifier-terser": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/html-minifier-terser/-/html-minifier-terser-6.1.0.tgz", + "integrity": "sha512-YXxSlJBZTP7RS3tWnQw74ooKa6L9b9i9QYXY21eUEvhZ3u9XLfv6OnFsQq6RxkhHygsaUMvYsZRV5rU/OVNZxw==", + "dev": true, + "requires": { + "camel-case": "^4.1.2", + "clean-css": "^5.2.2", + "commander": "^8.3.0", + "he": "^1.2.0", + "param-case": "^3.0.4", + "relateurl": "^0.2.7", + "terser": "^5.10.0" + }, + "dependencies": { + "commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true + } + } + }, + "html-parse-stringify": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/html-parse-stringify/-/html-parse-stringify-3.0.1.tgz", + "integrity": "sha512-KknJ50kTInJ7qIScF3jeaFRpMpE8/lfiTdzf/twXyPBLAGrLRTmkz3AdTnKeh40X8k9L2fdYwEp/42WGXIRGcg==", + "requires": { + "void-elements": "3.1.0" + } + }, + "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 + }, + "html-webpack-plugin": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz", + "integrity": "sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==", + "dev": true, + "requires": { + "@types/html-minifier-terser": "^6.0.0", + "html-minifier-terser": "^6.0.2", + "lodash": "^4.17.21", + "pretty-error": "^4.0.0", + "tapable": "^2.0.0" + } + }, + "htmlparser2": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-6.1.0.tgz", + "integrity": "sha512-gyyPk6rgonLFEDGoeRgQNaEUvdJ4ktTmmUh/h2t7s+M8oPpIPxgNACWa+6ESR57kXstwqPiCut0V8NRpcwgU7A==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "domhandler": "^4.0.0", + "domutils": "^2.5.2", + "entities": "^2.0.0" + } + }, + "http-cache-semantics": { + "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==", + "dev": true + }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", + "dev": 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==", + "dev": true, + "requires": { + "depd": "2.0.0", + "inherits": "2.0.4", + "setprototypeof": "1.2.0", + "statuses": "2.0.1", + "toidentifier": "1.0.1" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true + } + } + }, + "http-parser-js": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/http-parser-js/-/http-parser-js-0.5.6.tgz", + "integrity": "sha512-vDlkRPDJn93swjcjqMSaGSPABbIarsr1TLAui/gLDXzV5VsJNdXNzMYDyNBLQkjWQCJ1uizu8T2oDMhmGt0PRA==", + "dev": true + }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "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" + } + }, + "http-proxy-middleware": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-2.0.4.tgz", + "integrity": "sha512-m/4FxX17SUvz4lJ5WPXOHDUuCwIqXLfLHs1s0uZ3oYjhoXlx9csYxaOa0ElDEJ+h8Q4iJ1s+lTMbiCa4EXIJqg==", + "dev": true, + "requires": { + "@types/http-proxy": "^1.17.8", + "http-proxy": "^1.18.1", + "is-glob": "^4.0.1", + "is-plain-obj": "^3.0.0", + "micromatch": "^4.0.2" + } + }, + "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==", + "dev": true, + "requires": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + } + }, + "https-proxy-agent": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", + "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 + }, + "humanize-ms": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz", + "integrity": "sha1-xG4xWaKT9riW2ikxbYtv6Lt5u+0=", + "dev": true, + "requires": { + "ms": "^2.0.0" + } + }, + "husky": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/husky/-/husky-7.0.4.tgz", + "integrity": "sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==", + "dev": true + }, + "i18next": { + "version": "21.6.16", + "resolved": "https://registry.npmjs.org/i18next/-/i18next-21.6.16.tgz", + "integrity": "sha512-xJlzrVxG9CyAGsbMP1aKuiNr1Ed2m36KiTB7hjGMG2Zo4idfw3p9THUEu+GjBwIgEZ7F11ZbCzJcfv4uyfKNuw==", + "requires": { + "@babel/runtime": "^7.17.2" + } + }, + "i18next-parser": { + "version": "6.6.0", + "resolved": "https://registry.npmjs.org/i18next-parser/-/i18next-parser-6.6.0.tgz", + "integrity": "sha512-yA3W6PL+7epCyUFTpUDdztKArfpeGMWRUOnB/4FZRodfXkjCIBcBg728h6b/lrBTbva4OlFjVgv1kCXbvZVRWQ==", + "dev": true, + "requires": { + "@babel/runtime": "^7.15.4", + "broccoli-plugin": "^4.0.7", + "cheerio": "^1.0.0-rc.2", + "colors": "1.4.0", + "commander": "~9.4.1", + "concat-stream": "~2.0.0", + "eol": "^0.9.1", + "fs-extra": "^10.0.0", + "gulp-sort": "^2.0.0", + "i18next": "^21.2.0", + "js-yaml": "4.1.0", + "rsvp": "^4.8.2", + "sort-keys": "^5.0.0", + "through2": "~4.0.2", + "typescript": "^4.2.4", + "vinyl": "~3.0.0", + "vinyl-fs": "^3.0.2", + "vue-template-compiler": "^2.6.11" + }, + "dependencies": { + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==", + "dev": true + }, + "colors": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/colors/-/colors-1.4.0.tgz", + "integrity": "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA==", + "dev": true + }, + "commander": { + "version": "9.4.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-9.4.1.tgz", + "integrity": "sha512-5EEkTNyHNGFPD2H+c/dXXfQZYa/scCKasxWcXJaWnNJ99pnQN9Vnmqow+p+PlFPE63Q6mThaZws1T+HxfpgtPw==", + "dev": true + }, + "concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "replace-ext": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-2.0.0.tgz", + "integrity": "sha512-UszKE5KVK6JvyD92nzMn9cDapSk6w/CaFZ96CnmDMUqH9oowfxF/ZjRITD25H4DnOQClLA4/j7jLGXXLVKxAug==", + "dev": true + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + }, + "vinyl": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-3.0.0.tgz", + "integrity": "sha512-rC2VRfAVVCGEgjnxHUnpIVh3AGuk62rP3tqVrn+yab0YH7UULisC085+NYH+mnqf3Wx4SpSi1RQMwudL89N03g==", + "dev": true, + "requires": { + "clone": "^2.1.2", + "clone-stats": "^1.0.0", + "remove-trailing-separator": "^1.1.0", + "replace-ext": "^2.0.0", + "teex": "^1.0.1" + } + } + } + }, + "iconv-corefoundation": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/iconv-corefoundation/-/iconv-corefoundation-1.1.7.tgz", + "integrity": "sha512-T10qvkw0zz4wnm560lOEg0PovVqUXuOFhhHAkixw8/sycy7TJt7v/RrkEKEQnAw2viPSJu6iAkErxnzR0g8PpQ==", + "dev": true, + "optional": true, + "requires": { + "cli-truncate": "^2.1.0", + "node-addon-api": "^1.6.3" + } + }, + "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==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + } + }, + "icss-utils": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-5.1.0.tgz", + "integrity": "sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA==", + "dev": true, + "requires": {} + }, + "identity-obj-proxy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz", + "integrity": "sha1-lNK9qWCERT7zb7xarsN+D3nx/BQ=", + "dev": true, + "requires": { + "harmony-reflect": "^1.4.6" + } + }, + "ieee754": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true + }, + "ignore": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz", + "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==", + "dev": true + }, + "immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", + "dev": true + }, + "immer": { + "version": "9.0.21", + "resolved": "https://registry.npmjs.org/immer/-/immer-9.0.21.tgz", + "integrity": "sha512-bc4NBHqOqSfRW7POMkHd51LvClaeMXpm8dx0e8oE2GORbq5aRK7Bxl4FyzVLdGtLmvLKL7BTDBG5ACQm4HWjTA==" + }, + "immutable": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/immutable/-/immutable-4.0.0.tgz", + "integrity": "sha512-zIE9hX70qew5qTUjSS7wi1iwj/l7+m54KWU247nhM3v806UdGj1yDndXj+IOYxxtW9zyLI+xqFNZjTuDaLUqFw==", + "dev": true + }, + "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-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-3.0.0.tgz", + "integrity": "sha512-CiuXOFFSzkU5x/CR0+z7T91Iht4CXgfCxVOFRhh2Zyhg5wOpWvvDLQUsWl+gcN+QscYBjez8hDCt85O7RLDttQ==", + "dev": true, + "requires": { + "resolve-from": "^5.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 + } + } + }, + "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": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "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 + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha512-bup+4tap3Hympa+JBJUG7XuOsdNQ6fxt0MHyXMKuLBKn0OqsTfvUxkUrroEX1+B2VsSHvCjiIcZVxRtYa4nllA==", + "dev": true + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "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==", + "dev": true + }, + "ini": { + "version": "1.3.8", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", + "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", + "dev": true + }, + "internal-slot": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz", + "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==", + "dev": true, + "requires": { + "get-intrinsic": "^1.1.0", + "has": "^1.0.3", + "side-channel": "^1.0.4" + } }, "interpret": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", - "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", - "dev": true - } - } - }, - "webpack-dev-middleware": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz", - "integrity": "sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg==", - "dev": true, - "requires": { - "colorette": "^2.0.10", - "memfs": "^3.4.1", - "mime-types": "^2.1.31", - "range-parser": "^1.2.1", - "schema-utils": "^4.0.0" - }, - "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" - } + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.4.0.tgz", + "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==", + "dev": true }, - "ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.3" - } + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "requires": { + "loose-envify": "^1.0.0" + } + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "ipaddr.js": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.0.1.tgz", + "integrity": "sha512-1qTgH9NG+IIJ4yfKs2e6Pp1bZg8wbDbKHT21HrLIeYBTRLgMYKnMTPAuI3Lcs61nfx5h1xlXnbJtH1kX5/d/ng==", + "dev": true + }, + "is-absolute": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-absolute/-/is-absolute-1.0.0.tgz", + "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==", + "dev": true, + "requires": { + "is-relative": "^1.0.0", + "is-windows": "^1.0.1" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-alphabetical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-1.0.4.tgz", + "integrity": "sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==", + "dev": true + }, + "is-alphanumeric": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz", + "integrity": "sha512-ZmRL7++ZkcMOfDuWZuMJyIVLr2keE1o/DeNWh1EmgqGhUcV+9BIVsx0BcSBOHTZqzjs4+dISzr2KAeBEWGgXeA==", + "dev": true + }, + "is-alphanumerical": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", + "integrity": "sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==", + "dev": true, + "requires": { + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0" + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=" + }, + "is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "requires": { + "has-bigints": "^1.0.1" + } + }, + "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==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "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==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==" + }, + "is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true + }, + "is-ci": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-3.0.1.tgz", + "integrity": "sha512-ZYvCgrefwqoQ6yTyYUbQu64HsITZ3NfKX1lzaEYdkTDcfKzzCI/wthRRYKkdjHKFVgNiXKAKm65Zo1pk2as/QQ==", + "dev": true, + "requires": { + "ci-info": "^3.2.0" + } + }, + "is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "requires": { + "has": "^1.0.3" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "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==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-decimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-1.0.4.tgz", + "integrity": "sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==", + "dev": true + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==", + "dev": true + }, + "is-docker": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-2.2.1.tgz", + "integrity": "sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==", + "dev": true + }, + "is-electron": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-electron/-/is-electron-2.2.2.tgz", + "integrity": "sha512-FO/Rhvz5tuw4MCWkpMzHFKWD2LsfHzIb7i6MdPYZ/KW7AlxawyLkqdy+jPZP1WubqEADE3O4FUENlJHDfQASRg==" + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-hexadecimal": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-1.0.4.tgz", + "integrity": "sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==", + "dev": true + }, + "is-interactive": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz", + "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==", + "dev": true + }, + "is-lambda": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-lambda/-/is-lambda-1.0.1.tgz", + "integrity": "sha1-PZh3iZ5qU+/AFgUEzeFfgubwYdU=", + "dev": true + }, + "is-negated-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-negated-glob/-/is-negated-glob-1.0.0.tgz", + "integrity": "sha1-aRC8pdqMleeEtXUbl2z1oQ/uNtI=", + "dev": true + }, + "is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==" + }, + "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==", + "dev": true + }, + "is-plain-obj": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "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-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + } + }, + "is-regexp": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-2.1.0.tgz", + "integrity": "sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==", + "dev": true + }, + "is-relative": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-relative/-/is-relative-1.0.0.tgz", + "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==", + "dev": true, + "requires": { + "is-unc-path": "^1.0.0" + } + }, + "is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "requires": { + "has-tostringtag": "^1.0.0" + } + }, + "is-supported-regexp-flag": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-supported-regexp-flag/-/is-supported-regexp-flag-1.0.1.tgz", + "integrity": "sha512-3vcJecUUrpgCqc/ca0aWeNu64UGgxcvO60K/Fkr1N6RSvfGCTU60UKN68JDmKokgba0rFFJs12EnzOQa14ubKQ==", + "dev": true + }, + "is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "requires": { + "has-symbols": "^1.0.2" + } + }, + "is-typedarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz", + "integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=", + "dev": true + }, + "is-unc-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-unc-path/-/is-unc-path-1.0.0.tgz", + "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==", + "dev": true, + "requires": { + "unc-path-regex": "^0.1.2" + } + }, + "is-unicode-supported": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz", + "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==", + "dev": true + }, + "is-utf8": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", + "integrity": "sha1-Sw2hRCEE0bM2NA6AeX6GXPOffXI=", + "dev": true + }, + "is-valid-glob": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-valid-glob/-/is-valid-glob-1.0.0.tgz", + "integrity": "sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao=", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "call-bind": "^1.0.2" + } + }, + "is-what": { + "version": "4.1.7", + "resolved": "https://registry.npmjs.org/is-what/-/is-what-4.1.7.tgz", + "integrity": "sha512-DBVOQNiPKnGMxRMLIYSwERAS5MVY1B7xYiGnpgctsOFvVDz9f9PFXXxMcTOHuoqYp4NK9qFYQaIC1NRRxLMpBQ==" + }, + "is-whitespace-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", + "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", + "dev": true + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-word-character": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", + "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", + "dev": true + }, + "is-wsl": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-2.2.0.tgz", + "integrity": "sha512-fKzAra0rGJUUBwGBgNkHZuToZcn+TtXHpeCgmkMJMMYx1sQDYaCSyjJBSCa2nH1DGm7s3n1oBnohoVTBaN7Lww==", + "dev": true, + "requires": { + "is-docker": "^2.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isbinaryfile": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/isbinaryfile/-/isbinaryfile-5.0.0.tgz", + "integrity": "sha512-UDdnyGvMajJUWCkib7Cei/dvyJrrvo4FIrsvSFWdPpXSUorzXrDJ0S+X5Q4ZlasfPjca4yqCNNsjbCeiy8FFeg==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "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.1.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-5.1.0.tgz", + "integrity": "sha512-czwUz525rkOFDJxfKK6mYfIs9zBKILyrZQxjz3ABhjQXhbhFsSbo1HW/BFcsDnfJYJWA6thRR5/TUY2qs5W99Q==", + "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" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "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" + }, + "dependencies": { + "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 + } + } + }, + "istanbul-reports": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.4.tgz", + "integrity": "sha512-r1/DshN4KSE7xWEknZLLLLDn5CJybV3nw01VTkp6D5jzLuELlcbudfj/eSQFvrKsJuTVCGnePO7ho82Nw9zzfw==", + "dev": true, + "requires": { + "html-escaper": "^2.0.0", + "istanbul-lib-report": "^3.0.0" + } + }, + "jake": { + "version": "10.8.5", + "resolved": "https://registry.npmjs.org/jake/-/jake-10.8.5.tgz", + "integrity": "sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==", + "dev": true, + "requires": { + "async": "^3.2.3", + "chalk": "^4.0.2", + "filelist": "^1.0.1", + "minimatch": "^3.0.4" + } + }, + "jest": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest/-/jest-27.5.1.tgz", + "integrity": "sha512-Yn0mADZB89zTtjkPJEXwrac3LHudkQMR+Paqa8uxJHCBr9agxztUifWCyiYrjhMPBoUVBjyny0I7XH6ozDr7QQ==", + "dev": true, + "requires": { + "@jest/core": "^27.5.1", + "import-local": "^3.0.2", + "jest-cli": "^27.5.1" + } + }, + "jest-changed-files": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-changed-files/-/jest-changed-files-27.5.1.tgz", + "integrity": "sha512-buBLMiByfWGCoMsLLzGUUSpAmIAGnbR2KJoMN10ziLhOLvP4e0SlypHnAel8iqQXTrcbmfEY9sSqae5sgUsTvw==", + "dev": true, + "requires": { + "@jest/types": "^27.5.1", + "execa": "^5.0.0", + "throat": "^6.0.1" + } + }, + "jest-circus": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-27.5.1.tgz", + "integrity": "sha512-D95R7x5UtlMA5iBYsOHFFbMD/GVA4R/Kdq15f7xYWUfWHBto9NYRsOvnSauTgdF+ogCpJ4tyKOXhUifxS65gdw==", + "dev": true, + "requires": { + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "dedent": "^0.7.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3", + "throat": "^6.0.1" + } + }, + "jest-cli": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-cli/-/jest-cli-27.5.1.tgz", + "integrity": "sha512-Hc6HOOwYq4/74/c62dEE3r5elx8wjYqxY0r0G/nFrLDPMFRu6RA/u8qINOIkvhxG7mMQ5EJsOGfRpI8L6eFUVw==", + "dev": true, + "requires": { + "@jest/core": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "exit": "^0.1.2", + "graceful-fs": "^4.2.9", + "import-local": "^3.0.2", + "jest-config": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "prompts": "^2.0.1", + "yargs": "^16.2.0" + } + }, + "jest-config": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-config/-/jest-config-27.5.1.tgz", + "integrity": "sha512-5sAsjm6tGdsVbW9ahcChPAFCk4IlkQUknH5AvKjuLTSlcO/wCZKyFdn7Rg0EkC+OGgWODEy2hDpWB1PgzH0JNA==", + "dev": true, + "requires": { + "@babel/core": "^7.8.0", + "@jest/test-sequencer": "^27.5.1", + "@jest/types": "^27.5.1", + "babel-jest": "^27.5.1", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "deepmerge": "^4.2.2", + "glob": "^7.1.1", + "graceful-fs": "^4.2.9", + "jest-circus": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-jasmine2": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runner": "^27.5.1", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "micromatch": "^4.0.4", + "parse-json": "^5.2.0", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "strip-json-comments": "^3.1.1" + } + }, + "jest-diff": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-diff/-/jest-diff-27.5.1.tgz", + "integrity": "sha512-m0NvkX55LDt9T4mctTEgnZk3fmEg3NRYutvMPWM/0iPnkFj2wIeF45O1718cMSOFO1vINkqmxqD8vE37uTEbqw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "diff-sequences": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + } + }, + "jest-docblock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-docblock/-/jest-docblock-27.5.1.tgz", + "integrity": "sha512-rl7hlABeTsRYxKiUfpHrQrG4e2obOiTQWfMEH3PxPjOtdsfLQO4ReWSZaQ7DETm4xu07rl4q/h4zcKXyU0/OzQ==", + "dev": true, + "requires": { + "detect-newline": "^3.0.0" + } + }, + "jest-each": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-each/-/jest-each-27.5.1.tgz", + "integrity": "sha512-1Ff6p+FbhT/bXQnEouYy00bkNSY7OUpfIcmdl8vZ31A1UUaurOLPA8a8BbJOF2RDUElwJhmeaV7LnagI+5UwNQ==", + "dev": true, + "requires": { + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1" + } + }, + "jest-environment-jsdom": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-jsdom/-/jest-environment-jsdom-27.5.1.tgz", + "integrity": "sha512-TFBvkTC1Hnnnrka/fUb56atfDtJ9VMZ94JkjTbggl1PEpwrYtUBKMezB3inLmWqQsXYLcMwNoDQwoBTAvFfsfw==", + "dev": true, + "requires": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1", + "jsdom": "^16.6.0" + } + }, + "jest-environment-node": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-27.5.1.tgz", + "integrity": "sha512-Jt4ZUnxdOsTGwSRAfKEnE6BcwsSPNOijjwifq5sDFSA2kesnXTvNqKHYgM0hDq3549Uf/KzdXNYn4wMZJPlFLw==", + "dev": true, + "requires": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "jest-mock": "^27.5.1", + "jest-util": "^27.5.1" + } + }, + "jest-get-type": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-27.5.1.tgz", + "integrity": "sha512-2KY95ksYSaK7DMBWQn6dQz3kqAf3BB64y2udeG+hv4KfSOb9qwcYQstTJc1KCbsix+wLZWZYN8t7nwX3GOBLRw==", + "dev": true + }, + "jest-haste-map": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-haste-map/-/jest-haste-map-27.5.1.tgz", + "integrity": "sha512-7GgkZ4Fw4NFbMSDSpZwXeBiIbx+t/46nJ2QitkOjvwPYyZmqttu2TDSimMHP1EkPOi4xUZAN1doE5Vd25H4Jng==", + "dev": true, + "requires": { + "@jest/types": "^27.5.1", + "@types/graceful-fs": "^4.1.2", + "@types/node": "*", + "anymatch": "^3.0.3", + "fb-watchman": "^2.0.0", + "fsevents": "^2.3.2", + "graceful-fs": "^4.2.9", + "jest-regex-util": "^27.5.1", + "jest-serializer": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "micromatch": "^4.0.4", + "walker": "^1.0.7" + } + }, + "jest-jasmine2": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-jasmine2/-/jest-jasmine2-27.5.1.tgz", + "integrity": "sha512-jtq7VVyG8SqAorDpApwiJJImd0V2wv1xzdheGHRGyuT7gZm6gG47QEskOlzsN1PG/6WNaCo5pmwMHDf3AkG2pQ==", + "dev": true, + "requires": { + "@jest/environment": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "co": "^4.6.0", + "expect": "^27.5.1", + "is-generator-fn": "^2.0.0", + "jest-each": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "pretty-format": "^27.5.1", + "throat": "^6.0.1" + } + }, + "jest-leak-detector": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-leak-detector/-/jest-leak-detector-27.5.1.tgz", + "integrity": "sha512-POXfWAMvfU6WMUXftV4HolnJfnPOGEu10fscNCA76KBpRRhcMN2c8d3iT2pxQS3HLbA+5X4sOUPzYO2NUyIlHQ==", + "dev": true, + "requires": { + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + } + }, + "jest-matcher-utils": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-matcher-utils/-/jest-matcher-utils-27.5.1.tgz", + "integrity": "sha512-z2uTx/T6LBaCoNWNFWwChLBKYxTMcGBRjAt+2SbP929/Fflb9aa5LGma654Rz8z9HLxsrUaYzxE9T/EFIL/PAw==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "pretty-format": "^27.5.1" + } + }, + "jest-message-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-message-util/-/jest-message-util-27.5.1.tgz", + "integrity": "sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.12.13", + "@jest/types": "^27.5.1", + "@types/stack-utils": "^2.0.0", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "micromatch": "^4.0.4", + "pretty-format": "^27.5.1", + "slash": "^3.0.0", + "stack-utils": "^2.0.3" + } + }, + "jest-mock": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-mock/-/jest-mock-27.5.1.tgz", + "integrity": "sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==", + "dev": true, + "requires": { + "@jest/types": "^27.5.1", + "@types/node": "*" + } + }, + "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": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", + "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", + "dev": true + }, + "jest-resolve": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve/-/jest-resolve-27.5.1.tgz", + "integrity": "sha512-FFDy8/9E6CV83IMbDpcjOhumAQPDyETnU2KZ1O98DwTnz8AOBsW/Xv3GySr1mOZdItLR+zDZ7I/UdTFbgSOVCw==", + "dev": true, + "requires": { + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-pnp-resolver": "^1.2.2", + "jest-util": "^27.5.1", + "jest-validate": "^27.5.1", + "resolve": "^1.20.0", + "resolve.exports": "^1.1.0", + "slash": "^3.0.0" + } + }, + "jest-resolve-dependencies": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-resolve-dependencies/-/jest-resolve-dependencies-27.5.1.tgz", + "integrity": "sha512-QQOOdY4PE39iawDn5rzbIePNigfe5B9Z91GDD1ae/xNDlu9kaat8QQ5EKnNmVWPV54hUdxCVwwj6YMgR2O7IOg==", + "dev": true, + "requires": { + "@jest/types": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-snapshot": "^27.5.1" + } + }, + "jest-runner": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runner/-/jest-runner-27.5.1.tgz", + "integrity": "sha512-g4NPsM4mFCOwFKXO4p/H/kWGdJp9V8kURY2lX8Me2drgXqG7rrZAx5kv+5H7wtt/cdFIjhqYx1HrlqWHaOvDaQ==", + "dev": true, + "requires": { + "@jest/console": "^27.5.1", + "@jest/environment": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "emittery": "^0.8.1", + "graceful-fs": "^4.2.9", + "jest-docblock": "^27.5.1", + "jest-environment-jsdom": "^27.5.1", + "jest-environment-node": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-leak-detector": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-runtime": "^27.5.1", + "jest-util": "^27.5.1", + "jest-worker": "^27.5.1", + "source-map-support": "^0.5.6", + "throat": "^6.0.1" + } + }, + "jest-runtime": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-runtime/-/jest-runtime-27.5.1.tgz", + "integrity": "sha512-o7gxw3Gf+H2IGt8fv0RiyE1+r83FJBRruoA+FXrlHw6xEyBsU8ugA6IPfTdVyA0w8HClpbK+DGJxH59UrNMx8A==", + "dev": true, + "requires": { + "@jest/environment": "^27.5.1", + "@jest/fake-timers": "^27.5.1", + "@jest/globals": "^27.5.1", + "@jest/source-map": "^27.5.1", + "@jest/test-result": "^27.5.1", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "chalk": "^4.0.0", + "cjs-module-lexer": "^1.0.0", + "collect-v8-coverage": "^1.0.0", + "execa": "^5.0.0", + "glob": "^7.1.3", + "graceful-fs": "^4.2.9", + "jest-haste-map": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-mock": "^27.5.1", + "jest-regex-util": "^27.5.1", + "jest-resolve": "^27.5.1", + "jest-snapshot": "^27.5.1", + "jest-util": "^27.5.1", + "slash": "^3.0.0", + "strip-bom": "^4.0.0" + } + }, + "jest-serializer": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-serializer/-/jest-serializer-27.5.1.tgz", + "integrity": "sha512-jZCyo6iIxO1aqUxpuBlwTDMkzOAJS4a3eYz3YzgxxVQFwLeSA7Jfq5cbqCY+JLvTDrWirgusI/0KwxKMgrdf7w==", + "dev": true, + "requires": { + "@types/node": "*", + "graceful-fs": "^4.2.9" + } + }, + "jest-snapshot": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-27.5.1.tgz", + "integrity": "sha512-yYykXI5a0I31xX67mgeLw1DZ0bJB+gpq5IpSuCAoyDi0+BhgU/RIrL+RTzDmkNTchvDFWKP8lp+w/42Z3us5sA==", + "dev": true, + "requires": { + "@babel/core": "^7.7.2", + "@babel/generator": "^7.7.2", + "@babel/plugin-syntax-typescript": "^7.7.2", + "@babel/traverse": "^7.7.2", + "@babel/types": "^7.0.0", + "@jest/transform": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/babel__traverse": "^7.0.4", + "@types/prettier": "^2.1.5", + "babel-preset-current-node-syntax": "^1.0.0", + "chalk": "^4.0.0", + "expect": "^27.5.1", + "graceful-fs": "^4.2.9", + "jest-diff": "^27.5.1", + "jest-get-type": "^27.5.1", + "jest-haste-map": "^27.5.1", + "jest-matcher-utils": "^27.5.1", + "jest-message-util": "^27.5.1", + "jest-util": "^27.5.1", + "natural-compare": "^1.4.0", + "pretty-format": "^27.5.1", + "semver": "^7.3.2" + } + }, + "jest-util": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-util/-/jest-util-27.5.1.tgz", + "integrity": "sha512-Kv2o/8jNvX1MQ0KGtw480E/w4fBCDOnH6+6DmeKi6LZUIlKA5kwY0YNdlzaWTiVgxqAqik11QyxDOKk543aKXw==", + "dev": true, + "requires": { + "@jest/types": "^27.5.1", + "@types/node": "*", + "chalk": "^4.0.0", + "ci-info": "^3.2.0", + "graceful-fs": "^4.2.9", + "picomatch": "^2.2.3" + } + }, + "jest-validate": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-27.5.1.tgz", + "integrity": "sha512-thkNli0LYTmOI1tDB3FI1S1RTp/Bqyd9pTarJwL87OIBFuqEb5Apv5EaApEudYg4g86e3CT6kM0RowkhtEnCBQ==", + "dev": true, + "requires": { + "@jest/types": "^27.5.1", + "camelcase": "^6.2.0", + "chalk": "^4.0.0", + "jest-get-type": "^27.5.1", + "leven": "^3.1.0", + "pretty-format": "^27.5.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": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-watcher/-/jest-watcher-27.5.1.tgz", + "integrity": "sha512-z676SuD6Z8o8qbmEGhoEUFOM1+jfEiL3DXHK/xgEiG2EyNYfFG60jluWcupY6dATjfEsKQuibReS1djInQnoVw==", + "dev": true, + "requires": { + "@jest/test-result": "^27.5.1", + "@jest/types": "^27.5.1", + "@types/node": "*", + "ansi-escapes": "^4.2.1", + "chalk": "^4.0.0", + "jest-util": "^27.5.1", + "string-length": "^4.0.1" + } + }, + "jest-worker": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz", + "integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==", + "dev": true, + "requires": { + "@types/node": "*", + "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.2.0", + "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", + "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "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" + } + }, + "jsdom": { + "version": "16.7.0", + "resolved": "https://registry.npmjs.org/jsdom/-/jsdom-16.7.0.tgz", + "integrity": "sha512-u9Smc2G1USStM+s/x1ru5Sxrl6mPYCbByG1U/hUmqaVsm4tbNyS7CicOSRyuGQYZhTu0h84qkZZQ/I+dzizSVw==", + "dev": true, + "requires": { + "abab": "^2.0.5", + "acorn": "^8.2.4", + "acorn-globals": "^6.0.0", + "cssom": "^0.4.4", + "cssstyle": "^2.3.0", + "data-urls": "^2.0.0", + "decimal.js": "^10.2.1", + "domexception": "^2.0.1", + "escodegen": "^2.0.0", + "form-data": "^3.0.0", + "html-encoding-sniffer": "^2.0.1", + "http-proxy-agent": "^4.0.1", + "https-proxy-agent": "^5.0.0", + "is-potential-custom-element-name": "^1.0.1", + "nwsapi": "^2.2.0", + "parse5": "6.0.1", + "saxes": "^5.0.1", + "symbol-tree": "^3.2.4", + "tough-cookie": "^4.0.0", + "w3c-hr-time": "^1.0.2", + "w3c-xmlserializer": "^2.0.0", + "webidl-conversions": "^6.1.0", + "whatwg-encoding": "^1.0.5", + "whatwg-mimetype": "^2.3.0", + "whatwg-url": "^8.5.0", + "ws": "^7.4.6", + "xml-name-validator": "^3.0.0" + }, + "dependencies": { + "@tootallnate/once": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", + "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==", + "dev": true + }, + "form-data": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-3.0.1.tgz", + "integrity": "sha512-RHkBKtLWUVwd7SqRIvCZMEvAMoGUp0XU+seQiZejj0COz3RI3hWP4sCv3gZWWLjJTd7rGwcsF5eKZGii0r/hbg==", + "dev": true, + "requires": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + } + }, + "http-proxy-agent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", + "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", + "dev": true, + "requires": { + "@tootallnate/once": "1", + "agent-base": "6", + "debug": "4" + } + } + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==" + }, + "json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-parse-even-better-errors": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz", + "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==" + }, + "json-schema": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", + "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==", + "dev": true }, "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 + "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==", + "dev": true + }, + "json-schema-typed": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-7.0.3.tgz", + "integrity": "sha512-7DE8mpG+/fVw+dTpjbxnx47TaMnDfOI1jwft9g1VybltZCduyRQPJPvc+zzKY9WPHxhPWczyFuYa6I8Mw4iU5A==" + }, + "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": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "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==", + "dev": true, + "optional": true + }, + "json5": { + "version": "2.2.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", + "integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==" + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "jsx-ast-utils": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-3.3.3.tgz", + "integrity": "sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==", + "dev": true, + "requires": { + "array-includes": "^3.1.5", + "object.assign": "^4.1.3" + } + }, + "jszip": { + "version": "3.9.1", + "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.9.1.tgz", + "integrity": "sha512-H9A60xPqJ1CuC4Ka6qxzXZeU8aNmgOeP5IFqwJbQQwtu2EUYxota3LdsiZWplF7Wgd9tkAd0mdu36nceSaPuYw==", + "dev": true, + "requires": { + "lie": "~3.3.0", + "pako": "~1.0.2", + "readable-stream": "~2.3.6", + "set-immediate-shim": "~1.0.1" + } + }, + "keyboardevent-from-electron-accelerator": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/keyboardevent-from-electron-accelerator/-/keyboardevent-from-electron-accelerator-2.0.0.tgz", + "integrity": "sha512-iQcmNA0M4ETMNi0kG/q0h/43wZk7rMeKYrXP7sqKIJbHkTU8Koowgzv+ieR/vWJbOwxx5nDC3UnudZ0aLSu4VA==" + }, + "keyboardevents-areequal": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/keyboardevents-areequal/-/keyboardevents-areequal-0.2.2.tgz", + "integrity": "sha512-Nv+Kr33T0mEjxR500q+I6IWisOQ0lK1GGOncV0kWE6n4KFmpcu7RUX5/2B0EUtX51Cb0HjZ9VJsSY3u4cBa0kw==" + }, + "keyv": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.2.tgz", + "integrity": "sha512-5MHbFaKn8cNSmVW7BYnijeAVlE4cYA/SVkifVgrh7yotnfhKmjuXpDKjrABLnT0SfHWV21P8ow07OGfRrNDg8g==", + "dev": true, + "requires": { + "json-buffer": "3.0.1" + } + }, + "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 + }, + "klona": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/klona/-/klona-2.0.5.tgz", + "integrity": "sha512-pJiBpiXMbt7dkzXe8Ghj/u4FfXOOa98fPW+bihOJ4SjnoijweJrNThJfd3ifXpXhREjpoF2mZVH1GfS9LV3kHQ==" + }, + "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 + }, + "language-subtag-registry": { + "version": "0.3.21", + "resolved": "https://registry.npmjs.org/language-subtag-registry/-/language-subtag-registry-0.3.21.tgz", + "integrity": "sha512-L0IqwlIXjilBVVYKFT37X9Ih11Um5NEl9cbJIuU/SwP/zEEAbBPOnEeeuxVMf45ydWQRDQN3Nqc96OgbH1K+Pg==", + "dev": true + }, + "language-tags": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/language-tags/-/language-tags-1.0.5.tgz", + "integrity": "sha1-0yHbxNowuovzAk4ED6XBRmH5GTo=", + "dev": true, + "requires": { + "language-subtag-registry": "~0.3.2" + } + }, + "lazy-val": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz", + "integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==" + }, + "lazystream": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.1.tgz", + "integrity": "sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==", + "dev": true, + "requires": { + "readable-stream": "^2.0.5" + } + }, + "lead": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lead/-/lead-1.0.0.tgz", + "integrity": "sha1-bxT5mje+Op3XhPVJVpDlkDRm7kI=", + "dev": true, + "requires": { + "flush-write-stream": "^1.0.2" + } + }, + "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==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1", + "type-check": "~0.4.0" + } + }, + "lie": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz", + "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==", + "dev": true, + "requires": { + "immediate": "~3.0.5" + } + }, + "lilconfig": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.5.tgz", + "integrity": "sha512-xaYmXZtTHPAw5m+xLN8ab9C+3a8YmV3asNSPOATITbtwrfbwaLJj8h66H1WMIpALCkqsIzK3h7oQ+PdX+LQ9Eg==", + "dev": true + }, + "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==" + }, + "lint-staged": { + "version": "12.3.7", + "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-12.3.7.tgz", + "integrity": "sha512-/S4D726e2GIsDVWIk1XGvheCaDm1SJRQp8efamZFWJxQMVEbOwSysp7xb49Oo73KYCdy97mIWinhlxcoNqIfIQ==", + "dev": true, + "requires": { + "cli-truncate": "^3.1.0", + "colorette": "^2.0.16", + "commander": "^8.3.0", + "debug": "^4.3.3", + "execa": "^5.1.1", + "lilconfig": "2.0.4", + "listr2": "^4.0.1", + "micromatch": "^4.0.4", + "normalize-path": "^3.0.0", + "object-inspect": "^1.12.0", + "pidtree": "^0.5.0", + "string-argv": "^0.3.1", + "supports-color": "^9.2.1", + "yaml": "^1.10.2" + }, + "dependencies": { + "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 + }, + "ansi-styles": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.1.0.tgz", + "integrity": "sha512-VbqNsoz55SYGczauuup0MFUyXNQviSpFTj1RQtFzmQLk18qbVSpTFFGMT293rmDaQuKCT6InmbuEyUne4mTuxQ==", + "dev": true + }, + "cli-truncate": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-3.1.0.tgz", + "integrity": "sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==", + "dev": true, + "requires": { + "slice-ansi": "^5.0.0", + "string-width": "^5.0.0" + } + }, + "commander": { + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-8.3.0.tgz", + "integrity": "sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww==", + "dev": true + }, + "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 + }, + "lilconfig": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-2.0.4.tgz", + "integrity": "sha512-bfTIN7lEsiooCocSISTWXkiWJkRqtL9wYtYy+8EK3Y41qh3mpwPU0ycTOgjdY9ErwXCc8QyrQp82bdL0Xkm9yA==", + "dev": true + }, + "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, + "requires": { + "ansi-styles": "^6.0.0", + "is-fullwidth-code-point": "^4.0.0" + } + }, + "string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "requires": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + } + }, + "strip-ansi": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.0.1.tgz", + "integrity": "sha512-cXNxvT8dFNRVfhVME3JAe98mkXDYN2O1l7jmcwMnOslDeESg1rF/OZMtK0nRAhiari1unG5cD4jG3rapUAkLbw==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "supports-color": { + "version": "9.2.2", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.2.2.tgz", + "integrity": "sha512-XC6g/Kgux+rJXmwokjm9ECpD6k/smUoS5LKlUCcsYr4IY3rW0XyAympon2RmxGrlnZURMpg5T18gWDP9CsHXFA==", + "dev": true + } + } + }, + "listr2": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/listr2/-/listr2-4.0.5.tgz", + "integrity": "sha512-juGHV1doQdpNT3GSTs9IUN43QJb7KHdF9uqg7Vufs/tG9VTzpFphqF4pm/ICdAABGQxsyNn9CiYA3StkI6jpwA==", + "dev": true, + "requires": { + "cli-truncate": "^2.1.0", + "colorette": "^2.0.16", + "log-update": "^4.0.0", + "p-map": "^4.0.0", + "rfdc": "^1.3.0", + "rxjs": "^7.5.5", + "through": "^2.3.8", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "rxjs": { + "version": "7.5.5", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.5.5.tgz", + "integrity": "sha512-sy+H0pQofO95VDmFLzyaw9xNJU4KTRSwQIGM6+iG3SypAtCiLDzpeG8sJrNCWn2Up9km+KhkvTdbkrdy+yzZdw==", + "dev": true, + "requires": { + "tslib": "^2.1.0" + } + } + } + }, + "load-json-file": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", + "integrity": "sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^4.0.0", + "pify": "^3.0.0", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "load-script": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz", + "integrity": "sha1-BJGTngvuVkPuSUp+PaPSuscMbKQ=" + }, + "loader-runner": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.2.0.tgz", + "integrity": "sha512-92+huvxMvYlMzMt0iIOukcwYBFpkYJdpl2xsZ7LrlayO7E8SOv+JJUEK17B/dJIHAOLMfh2dZZ/Y18WgmGtYNw==", + "dev": true + }, + "loader-utils": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-2.0.4.tgz", + "integrity": "sha512-xXqpXoINfFhgua9xiqD8fPFHgkoq1mmmpE92WlDbm9rNRd/EbRb+Gqf908T2DMfuHjjJlksiK2RbHVOdD/MqSw==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^2.1.2" + } + }, + "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==", + "dev": true, + "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.difference": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.difference/-/lodash.difference-4.5.0.tgz", + "integrity": "sha1-nMtOUF1Ia5FlE0V3KIWi3yf9AXw=", + "dev": true + }, + "lodash.escaperegexp": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz", + "integrity": "sha1-ZHYsSGGAglGKw99Mz11YhtriA0c=" + }, + "lodash.isequal": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz", + "integrity": "sha1-QVxEePK8wwEgwizhDtMib30+GOA=" + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "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==", + "dev": true + }, + "lodash.truncate": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/lodash.truncate/-/lodash.truncate-4.4.2.tgz", + "integrity": "sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==", + "dev": true + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "dev": true + }, + "log-symbols": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz", + "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "is-unicode-supported": "^0.1.0" + } + }, + "log-update": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-update/-/log-update-4.0.0.tgz", + "integrity": "sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==", + "dev": true, + "requires": { + "ansi-escapes": "^4.3.0", + "cli-cursor": "^3.1.0", + "slice-ansi": "^4.0.0", + "wrap-ansi": "^6.2.0" + }, + "dependencies": { + "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, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz", + "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + } + } + }, + "longest-streak": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", + "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "loud-rejection": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/loud-rejection/-/loud-rejection-1.6.0.tgz", + "integrity": "sha512-RPNliZOFkqFumDhvYqOaNY4Uz9oJM2K9tC6JWsJJsNdhuONW4LQHRBpb0qf4pJApVffI5N39SwzWZJuEhfd7eQ==", + "dev": true, + "requires": { + "currently-unhandled": "^0.4.1", + "signal-exit": "^3.0.0" + } + }, + "lower-case": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", + "integrity": "sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==", + "dev": true, + "requires": { + "tslib": "^2.0.3" + } + }, + "lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true + }, + "lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "requires": { + "yallist": "^4.0.0" + } + }, + "lz-string": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.4.4.tgz", + "integrity": "sha1-wNjq82BZ9wV5bh40SBHPTEmNOiY=", + "dev": true + }, + "lzma-native": { + "version": "8.0.6", + "resolved": "https://registry.npmjs.org/lzma-native/-/lzma-native-8.0.6.tgz", + "integrity": "sha512-09xfg67mkL2Lz20PrrDeNYZxzeW7ADtpYFbwSQh9U8+76RIzx5QsJBMy8qikv3hbUPfpy6hqwxt6FcGK81g9AA==", + "dev": true, + "requires": { + "node-addon-api": "^3.1.0", + "node-gyp-build": "^4.2.1", + "readable-stream": "^3.6.0" + }, + "dependencies": { + "node-addon-api": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz", + "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", + "dev": true + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "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" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "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-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==", + "dev": true + }, + "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 + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "markdown-escapes": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", + "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", + "dev": true + }, + "markdown-table": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", + "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==", + "dev": true + }, + "matcher": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/matcher/-/matcher-3.0.0.tgz", + "integrity": "sha512-OkeDaAZ/bQCxeFAozM55PKcKU0yJMPGifLwV4Qgjitu+5MoAfSQN4lsLJeXZ1b8w0x+/Emda6MZgXS1jvsapng==", + "dev": true, + "optional": true, + "requires": { + "escape-string-regexp": "^4.0.0" + } + }, + "matcher-collection": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/matcher-collection/-/matcher-collection-2.0.1.tgz", + "integrity": "sha512-daE62nS2ZQsDg9raM0IlZzLmI2u+7ZapXBwdoeBUKAYERPDDIc0qNqA8E0Rp2D+gspKR7BgIFP52GeujaGXWeQ==", + "dev": true, + "requires": { + "@types/minimatch": "^3.0.3", + "minimatch": "^3.0.2" + } + }, + "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" + } + }, + "mdast-util-compact": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.4.tgz", + "integrity": "sha512-3YDMQHI5vRiS2uygEFYaqckibpJtKq5Sj2c8JioeOQBU6INpKbdWzfyLqFFnDwEcEnRFIdMsguzs5pC1Jp4Isg==", + "dev": true, + "requires": { + "unist-util-visit": "^1.1.0" + } + }, + "mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==", + "dev": true + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "memfs": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.4.1.tgz", + "integrity": "sha512-1c9VPVvW5P7I85c35zAdEr1TD5+F11IToIHIlrVIcflfnzPkJa0ZoYEoEdYDP8KgPFoSZ/opDrUsAoZWym3mtw==", + "dev": true, + "requires": { + "fs-monkey": "1.0.3" + } + }, + "memoize-one": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz", + "integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==" + }, + "memory-fs": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.2.0.tgz", + "integrity": "sha1-8rslNovBIeORwlIN6Slpyu4KApA=", + "dev": true + }, + "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": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "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": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true + }, + "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": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true + }, + "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==" + }, + "mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": 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 + }, + "mini-css-extract-plugin": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mini-css-extract-plugin/-/mini-css-extract-plugin-2.6.0.tgz", + "integrity": "sha512-ndG8nxCEnAemsg4FSgS+yNyHKgkTB4nPKqCOgh65j3/30qqC5RaSQQXMm++Y6sb6E1zRSxPkztj9fqxhS1Eo6w==", + "dev": true, + "requires": { + "schema-utils": "^4.0.0" + }, + "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" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "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 + }, + "schema-utils": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" + } + } + } + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "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==", + "dev": 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": { + "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 + } + } + }, + "minipass": { + "version": "3.1.6", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.6.tgz", + "integrity": "sha512-rty5kpw9/z8SX9dmxblFA6edItUmwJgMeYDZRrwlIVN27i8gysGbznJwUggw2V/FVqFSDdWy040ZPS811DYAqQ==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-pipeline": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.4.tgz", + "integrity": "sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-sized": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/minipass-sized/-/minipass-sized-1.0.3.tgz", + "integrity": "sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minizlib": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-2.1.2.tgz", + "integrity": "sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==", + "dev": true, + "requires": { + "minipass": "^3.0.0", + "yallist": "^4.0.0" + } + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + } + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "requires": { + "minimist": "^1.2.6" + } + }, + "mktemp": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/mktemp/-/mktemp-0.4.0.tgz", + "integrity": "sha1-bQUVYRyKjITkhKogABKbmOmB/ws=", + "dev": true + }, + "mrmime": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-1.0.0.tgz", + "integrity": "sha512-a70zx7zFfVO7XpnQ2IX1Myh9yY4UYvfld/dikWRnsXxbyvMcfz+u6UfgNAtH+k2QqtJuzVpv6eLTx1G2+WKZbQ==", + "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==" + }, + "multicast-dns": { + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-7.2.4.tgz", + "integrity": "sha512-XkCYOU+rr2Ft3LI6w4ye51M3VK31qJXFIxu0XLw169PtKG0Zx47OrXeVW/GCYOfpC9s1yyyf1S+L8/4LY0J9Zw==", + "dev": true, + "requires": { + "dns-packet": "^5.2.2", + "thunky": "^1.0.2" + } + }, + "nanoid": { + "version": "3.3.4", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", + "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==" + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "natural-compare-lite": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz", + "integrity": "sha1-F7CVgZiJef3a/gIB6TG6kzyWy7Q=", + "dev": true + }, + "negotiator": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.3.tgz", + "integrity": "sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==", + "dev": true + }, + "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==", + "dev": true + }, + "net": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/net/-/net-1.0.2.tgz", + "integrity": "sha512-kbhcj2SVVR4caaVnGLJKmlk2+f+oLkjqdKeQlmUtz6nGzOpbcobwVIeSURNgraV/v3tlmGIX82OcPCl0K6RbHQ==" + }, + "no-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", + "integrity": "sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==", + "dev": true, + "requires": { + "lower-case": "^2.0.2", + "tslib": "^2.0.3" + } + }, + "node-abi": { + "version": "3.33.0", + "resolved": "https://registry.yarnpkg.com/node-abi/-/node-abi-3.33.0.tgz#8b23a0cec84e1c5f5411836de6a9b84bccf26e7f", + "integrity": "sha512-7GGVawqyHF4pfd0YFybhv/eM9JwTtPqx0mAanQ146O3FlSh3pA24zf9IRQTOsfTSqXTNzPSP5iagAJ94jjuVog==", + "dev": true, + "requires": { + "semver": "^7.3.5" + } + }, + "node-addon-api": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-1.7.2.tgz", + "integrity": "sha512-ibPK3iA+vaY1eEjESkQkM0BbCqFOaZMiXRTtdB0u7b4djtY6JnsjvPdUHVMg6xQt3B8fpTTWHI9A+ADjM9frzg==", + "dev": true, + "optional": true + }, + "node-api-version": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/node-api-version/-/node-api-version-0.1.4.tgz", + "integrity": "sha512-KGXihXdUChwJAOHO53bv9/vXcLmdUsZ6jIptbvYvkpKfth+r7jw44JkVxQFA3kX5nQjzjmGu1uAu/xNNLNlI5g==", + "dev": true, + "requires": { + "semver": "^7.3.5" + } + }, + "node-forge": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", + "integrity": "sha512-dPEtOeMvF9VMcYV/1Wb8CPoVAXtp6MKMlcbAt4ddqmGqUJ6fQZFXkNZNkNlfevtNkGtaSoXf/vNNNSvgrdXwtA==", + "dev": true + }, + "node-gyp-build": { + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/node-gyp-build/-/node-gyp-build-4.4.0.tgz", + "integrity": "sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==", + "dev": true + }, + "node-int64": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/node-int64/-/node-int64-0.4.0.tgz", + "integrity": "sha1-h6kGXNs1XTGC2PlM4RGIuCXGijs=", + "dev": true + }, + "node-mpv": { + "version": "git+ssh://git@github.com/jeffvli/Node-MPV.git#c7f84d7966b82e5916c3b4bb47cac667bb895c22", + "from": "node-mpv@github:jeffvli/Node-MPV" + }, + "node-releases": { + "version": "2.0.8", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.8.tgz", + "integrity": "sha512-dFSmB8fFHEH/s81Xi+Y/15DQY6VHW81nXRj86EMSL3lmuTmK1e+aT4wrFCkTbm+gSwkw4KpX+rT/pMM2c1mF+A==" + }, + "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" + } + }, + "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-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==", + "dev": true + }, + "normalize-selector": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/normalize-selector/-/normalize-selector-0.2.0.tgz", + "integrity": "sha512-dxvWdI8gw6eAvk9BlPffgEoGfM7AdijoCwOEJge3e3ulT2XLgmU7KvvxprOaCu05Q1uGRHmOhHe1r6emZoKyFw==", + "dev": true + }, + "normalize-url": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", + "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", + "dev": true + }, + "now-and-later": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/now-and-later/-/now-and-later-2.0.1.tgz", + "integrity": "sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==", + "dev": true, + "requires": { + "once": "^1.3.2" + } + }, + "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" + } + }, + "npmlog": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/npmlog/-/npmlog-6.0.1.tgz", + "integrity": "sha512-BTHDvY6nrRHuRfyjt1MAufLxYdVXZfd099H4+i1f0lPywNQyI4foeNXJRObB/uy+TYqUW0vAD9gbdSOXPst7Eg==", + "dev": true, + "requires": { + "are-we-there-yet": "^3.0.0", + "console-control-strings": "^1.1.0", + "gauge": "^4.0.0", + "set-blocking": "^2.0.0" + } + }, + "nth-check": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.0.1.tgz", + "integrity": "sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==", + "dev": true, + "requires": { + "boolbase": "^1.0.0" + } + }, + "num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==", + "dev": true + }, + "nwsapi": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/nwsapi/-/nwsapi-2.2.0.tgz", + "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=" + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-inspect": { + "version": "1.12.2", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz", + "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==", + "dev": true + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.4", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.4.tgz", + "integrity": "sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + } + }, + "object.entries": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.6.tgz", + "integrity": "sha512-leTPzo4Zvg3pmbQ3rDK69Rl8GQvIqMWubrkxONG9/ojtFE2rD9fjMKfSI5BxW3osRH1m6VdzmqK8oAY9aT4x5w==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "object.fromentries": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz", + "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "object.hasown": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object.hasown/-/object.hasown-1.1.2.tgz", + "integrity": "sha512-B5UIT3J1W+WuWIU55h0mjlwaqxiE5vYENJXIXZ4VFe05pNYrkKuK0U/6aFcb0pKywYJh7IhfoqUfKVmrJJHZHw==", + "dev": true, + "requires": { + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "object.values": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz", + "integrity": "sha512-FVVTkD1vENCsAcwNs9k6jea2uHC/X0+JcjG8YA60FN5CMaJmG95wT9jek/xX9nornqGRrBkKtzuAu2wuHpKqvw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": 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==", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "open": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/open/-/open-8.4.0.tgz", + "integrity": "sha512-XgFPPM+B28FtCCgSb9I+s9szOC1vZRSwgWsRUA5ylIxRTgKozqjOCrVOqGsYABPYK5qnfqClxZTFBa8PKt2v6Q==", + "dev": true, + "requires": { + "define-lazy-prop": "^2.0.0", + "is-docker": "^2.1.1", + "is-wsl": "^2.2.0" + } + }, + "opener": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", + "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", + "dev": true + }, + "optionator": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.1.tgz", + "integrity": "sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==", + "dev": true, + "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" + } + }, + "ora": { + "version": "5.4.1", + "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz", + "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==", + "dev": true, + "requires": { + "bl": "^4.1.0", + "chalk": "^4.1.0", + "cli-cursor": "^3.1.0", + "cli-spinners": "^2.5.0", + "is-interactive": "^1.0.0", + "is-unicode-supported": "^0.1.0", + "log-symbols": "^4.1.0", + "strip-ansi": "^6.0.0", + "wcwidth": "^1.0.1" + } + }, + "ordered-read-streams": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ordered-read-streams/-/ordered-read-streams-1.0.1.tgz", + "integrity": "sha1-d8DLN8QVJdZBZtmQ/61+xqDhNj4=", + "dev": true, + "requires": { + "readable-stream": "^2.0.1" + } + }, + "p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "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==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "p-map": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz", + "integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-retry": { + "version": "4.6.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-4.6.1.tgz", + "integrity": "sha512-e2xXGNhZOZ0lfgR9kL34iGlU8N/KO0xZnQxVEwdeOvpqNDQfdnxIYizvWtK8RglUa3bGqI8g0R/BdfzLMxRkiA==", + "dev": true, + "requires": { + "@types/retry": "^0.12.0", + "retry": "^0.13.1" + }, + "dependencies": { + "retry": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.13.1.tgz", + "integrity": "sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==", + "dev": true + } + } + }, + "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==" + }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "param-case": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-3.0.4.tgz", + "integrity": "sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==", + "dev": true, + "requires": { + "dot-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "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-entities": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", + "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==", + "dev": true, + "requires": { + "character-entities": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "character-reference-invalid": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-hexadecimal": "^1.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==", + "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": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==", + "dev": true + }, + "parse5-htmlparser2-tree-adapter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz", + "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==", + "dev": true, + "requires": { + "parse5": "^6.0.1" + } + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "pascal-case": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-3.1.2.tgz", + "integrity": "sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==", + "dev": true, + "requires": { + "no-case": "^3.0.4", + "tslib": "^2.0.3" + } + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "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==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "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==" + }, + "path-posix": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/path-posix/-/path-posix-1.0.0.tgz", + "integrity": "sha1-BrJhE/Vr6rBCVFojv6iAA8ysJg8=", + "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": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "path-type": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", + "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==" + }, + "pend": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", + "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==", + "dev": true + }, + "picocolors": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", + "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==" + }, + "picomatch": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", + "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==" + }, + "pidtree": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/pidtree/-/pidtree-0.5.0.tgz", + "integrity": "sha512-9nxspIM7OpZuhBxPg73Zvyq7j1QMPMPsGKTqRc2XOaFQauDvoNz9fM1Wdkjmeo7l9GXOZiRs97sPkuayl39wjA==", + "dev": true + }, + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": 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" + } + } + } + }, + "pkg-up": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-3.1.0.tgz", + "integrity": "sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==", + "requires": { + "find-up": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "requires": { + "p-limit": "^2.0.0" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==" + } + } + }, + "plist": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/plist/-/plist-3.0.6.tgz", + "integrity": "sha512-WiIVYyrp8TD4w8yCvyeIr+lkmrGRd5u0VbRnU+tP/aRLxP/YadJUYOMZJ/6hIa3oUyVCsycXvtNRgd5XBJIbiA==", + "dev": true, + "requires": { + "base64-js": "^1.5.1", + "xmlbuilder": "^15.1.1" + } + }, + "portfinder": { + "version": "1.0.28", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.28.tgz", + "integrity": "sha512-Se+2isanIcEqf2XMHjyUKskczxbPH7dQnlMjXX6+dybayyHvAf/TCgyMRlzf/B6QDhAEFOGes0pzRo3by4AbMA==", + "dev": true, + "requires": { + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.5" + }, + "dependencies": { + "async": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", + "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, + "debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==", + "dev": true + }, + "postcss": { + "version": "8.4.20", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.20.tgz", + "integrity": "sha512-6Q04AXR1212bXr5fh03u8aAwbLxAQNGQ/Q1LNa0VfOI06ZAlhPHtQvE4OIdpj4kLThXilalPnmDSOD65DcHt+g==", + "dev": true, + "requires": { + "nanoid": "^3.3.4", + "picocolors": "^1.0.0", + "source-map-js": "^1.0.2" + } + }, + "postcss-calc": { + "version": "8.2.4", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-8.2.4.tgz", + "integrity": "sha512-SmWMSJmB8MRnnULldx0lQIyhSNvuDl9HfrZkaqqE/WHAhToYsAvDq+yAsA/kIyINDszOp3Rh0GFoNuH5Ypsm3Q==", + "dev": true, + "requires": { + "postcss-selector-parser": "^6.0.9", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-colormin": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-5.3.0.tgz", + "integrity": "sha512-WdDO4gOFG2Z8n4P8TWBpshnL3JpmNmJwdnfP2gbk2qBA8PWwOYcmjmI/t3CmMeL72a7Hkd+x/Mg9O2/0rD54Pg==", + "dev": true, + "requires": { + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0", + "colord": "^2.9.1", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-convert-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-5.1.0.tgz", + "integrity": "sha512-GkyPbZEYJiWtQB0KZ0X6qusqFHUepguBCNFi9t5JJc7I2OTXG7C0twbTLvCfaKOLl3rSXmpAwV7W5txd91V84g==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-discard-comments": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-5.1.1.tgz", + "integrity": "sha512-5JscyFmvkUxz/5/+TB3QTTT9Gi9jHkcn8dcmmuN68JQcv3aQg4y88yEHHhwFB52l/NkaJ43O0dbksGMAo49nfQ==", + "dev": true, + "requires": {} + }, + "postcss-discard-duplicates": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-5.1.0.tgz", + "integrity": "sha512-zmX3IoSI2aoenxHV6C7plngHWWhUOV3sP1T8y2ifzxzbtnuhk1EdPwm0S1bIUNaJ2eNbWeGLEwzw8huPD67aQw==", + "dev": true, + "requires": {} + }, + "postcss-discard-empty": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-5.1.1.tgz", + "integrity": "sha512-zPz4WljiSuLWsI0ir4Mcnr4qQQ5e1Ukc3i7UfE2XcrwKK2LIPIqE5jxMRxO6GbI3cv//ztXDsXwEWT3BHOGh3A==", + "dev": true, + "requires": {} + }, + "postcss-discard-overridden": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-5.1.0.tgz", + "integrity": "sha512-21nOL7RqWR1kasIVdKs8HNqQJhFxLsyRfAnUDm4Fe4t4mCWL9OJiHvlHPjcd8zc5Myu89b/7wZDnOSjFgeWRtw==", + "dev": true, + "requires": {} + }, + "postcss-html": { + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/postcss-html/-/postcss-html-0.36.0.tgz", + "integrity": "sha512-HeiOxGcuwID0AFsNAL0ox3mW6MHH5cstWN1Z3Y+n6H+g12ih7LHdYxWwEA/QmrebctLjo79xz9ouK3MroHwOJw==", + "dev": true, + "requires": { + "htmlparser2": "^3.10.0" + }, + "dependencies": { + "dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + }, + "dependencies": { + "domelementtype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz", + "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==", + "dev": true + }, + "entities": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.2.0.tgz", + "integrity": "sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==", + "dev": true + } + } + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "domhandler": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", + "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "dev": true, + "requires": { + "domelementtype": "1" + } + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "entities": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", + "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==", + "dev": true + }, + "htmlparser2": { + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", + "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", + "dev": true, + "requires": { + "domelementtype": "^1.3.1", + "domhandler": "^2.3.0", + "domutils": "^1.5.1", + "entities": "^1.1.1", + "inherits": "^2.0.1", + "readable-stream": "^3.1.1" + } + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "postcss-jsx": { + "version": "0.36.4", + "resolved": "https://registry.npmjs.org/postcss-jsx/-/postcss-jsx-0.36.4.tgz", + "integrity": "sha512-jwO/7qWUvYuWYnpOb0+4bIIgJt7003pgU3P6nETBLaOyBXuTD55ho21xnals5nBrlpTIFodyd3/jBi6UO3dHvA==", + "dev": true, + "requires": { + "@babel/core": ">=7.2.2" + } + }, + "postcss-less": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/postcss-less/-/postcss-less-3.1.4.tgz", + "integrity": "sha512-7TvleQWNM2QLcHqvudt3VYjULVB49uiW6XzEUFmvwHzvsOEF5MwBrIXZDJQvJNFGjJQTzSzZnDoCJ8h/ljyGXA==", + "dev": true, + "requires": { + "postcss": "^7.0.14" + }, + "dependencies": { + "picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "requires": { + "picocolors": "^0.2.1", + "source-map": "^0.6.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 + } + } + }, + "postcss-markdown": { + "version": "0.36.0", + "resolved": "https://registry.npmjs.org/postcss-markdown/-/postcss-markdown-0.36.0.tgz", + "integrity": "sha512-rl7fs1r/LNSB2bWRhyZ+lM/0bwKv9fhl38/06gF6mKMo/NPnp55+K1dSTosSVjFZc0e1ppBlu+WT91ba0PMBfQ==", + "dev": true, + "requires": { + "remark": "^10.0.1", + "unist-util-find-all-after": "^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-merge-longhand": { + "version": "5.1.4", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-5.1.4.tgz", + "integrity": "sha512-hbqRRqYfmXoGpzYKeW0/NCZhvNyQIlQeWVSao5iKWdyx7skLvCfQFGIUsP9NUs3dSbPac2IC4Go85/zG+7MlmA==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0", + "stylehacks": "^5.1.0" + } + }, + "postcss-merge-rules": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-5.1.1.tgz", + "integrity": "sha512-8wv8q2cXjEuCcgpIB1Xx1pIy8/rhMPIQqYKNzEdyx37m6gpq83mQQdCxgIkFgliyEnKvdwJf/C61vN4tQDq4Ww==", + "dev": true, + "requires": { + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0", + "cssnano-utils": "^3.1.0", + "postcss-selector-parser": "^6.0.5" + } + }, + "postcss-minify-font-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-5.1.0.tgz", + "integrity": "sha512-el3mYTgx13ZAPPirSVsHqFzl+BBBDrXvbySvPGFnQcTI4iNslrPaFq4muTkLZmKlGk4gyFAYUBMH30+HurREyA==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-minify-gradients": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-5.1.1.tgz", + "integrity": "sha512-VGvXMTpCEo4qHTNSa9A0a3D+dxGFZCYwR6Jokk+/3oB6flu2/PnPXAh2x7x52EkY5xlIHLm+Le8tJxe/7TNhzw==", + "dev": true, + "requires": { + "colord": "^2.9.1", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-minify-params": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-5.1.2.tgz", + "integrity": "sha512-aEP+p71S/urY48HWaRHasyx4WHQJyOYaKpQ6eXl8k0kxg66Wt/30VR6/woh8THgcpRbonJD5IeD+CzNhPi1L8g==", + "dev": true, + "requires": { + "browserslist": "^4.16.6", + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-minify-selectors": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-5.2.0.tgz", + "integrity": "sha512-vYxvHkW+iULstA+ctVNx0VoRAR4THQQRkG77o0oa4/mBS0OzGvvzLIvHDv/nNEM0crzN2WIyFU5X7wZhaUK3RA==", + "dev": true, + "requires": { + "postcss-selector-parser": "^6.0.5" + } + }, + "postcss-modules-extract-imports": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz", + "integrity": "sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw==", + "dev": true, + "requires": {} + }, + "postcss-modules-local-by-default": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz", + "integrity": "sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ==", + "dev": true, + "requires": { + "icss-utils": "^5.0.0", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.1.0" + } + }, + "postcss-modules-scope": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz", + "integrity": "sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg==", + "dev": true, + "requires": { + "postcss-selector-parser": "^6.0.4" + } + }, + "postcss-modules-values": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz", + "integrity": "sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ==", + "dev": true, + "requires": { + "icss-utils": "^5.0.0" + } + }, + "postcss-normalize-charset": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-5.1.0.tgz", + "integrity": "sha512-mSgUJ+pd/ldRGVx26p2wz9dNZ7ji6Pn8VWBajMXFf8jk7vUoSrZ2lt/wZR7DtlZYKesmZI680qjr2CeFF2fbUg==", + "dev": true, + "requires": {} + }, + "postcss-normalize-display-values": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-5.1.0.tgz", + "integrity": "sha512-WP4KIM4o2dazQXWmFaqMmcvsKmhdINFblgSeRgn8BJ6vxaMyaJkwAzpPpuvSIoG/rmX3M+IrRZEz2H0glrQNEA==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-positions": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-5.1.0.tgz", + "integrity": "sha512-8gmItgA4H5xiUxgN/3TVvXRoJxkAWLW6f/KKhdsH03atg0cB8ilXnrB5PpSshwVu/dD2ZsRFQcR1OEmSBDAgcQ==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-repeat-style": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-5.1.0.tgz", + "integrity": "sha512-IR3uBjc+7mcWGL6CtniKNQ4Rr5fTxwkaDHwMBDGGs1x9IVRkYIT/M4NelZWkAOBdV6v3Z9S46zqaKGlyzHSchw==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-string": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-5.1.0.tgz", + "integrity": "sha512-oYiIJOf4T9T1N4i+abeIc7Vgm/xPCGih4bZz5Nm0/ARVJ7K6xrDlLwvwqOydvyL3RHNf8qZk6vo3aatiw/go3w==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-timing-functions": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-5.1.0.tgz", + "integrity": "sha512-DOEkzJ4SAXv5xkHl0Wa9cZLF3WCBhF3o1SKVxKQAa+0pYKlueTpCgvkFAHfk+Y64ezX9+nITGrDZeVGgITJXjg==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-unicode": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-5.1.0.tgz", + "integrity": "sha512-J6M3MizAAZ2dOdSjy2caayJLQT8E8K9XjLce8AUQMwOrCvjCHv24aLC/Lps1R1ylOfol5VIDMaM/Lo9NGlk1SQ==", + "dev": true, + "requires": { + "browserslist": "^4.16.6", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-url": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-5.1.0.tgz", + "integrity": "sha512-5upGeDO+PVthOxSmds43ZeMeZfKH+/DKgGRD7TElkkyS46JXAUhMzIKiCa7BabPeIy3AQcTkXwVVN7DbqsiCew==", + "dev": true, + "requires": { + "normalize-url": "^6.0.1", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-normalize-whitespace": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-5.1.1.tgz", + "integrity": "sha512-83ZJ4t3NUDETIHTa3uEg6asWjSBYL5EdkVB0sDncx9ERzOKBVJIUeDO9RyA9Zwtig8El1d79HBp0JEi8wvGQnA==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-ordered-values": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-5.1.1.tgz", + "integrity": "sha512-7lxgXF0NaoMIgyihL/2boNAEZKiW0+HkMhdKMTD93CjW8TdCy2hSdj8lsAo+uwm7EDG16Da2Jdmtqpedl0cMfw==", + "dev": true, + "requires": { + "cssnano-utils": "^3.1.0", + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-reduce-initial": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-5.1.0.tgz", + "integrity": "sha512-5OgTUviz0aeH6MtBjHfbr57tml13PuedK/Ecg8szzd4XRMbYxH4572JFG067z+FqBIf6Zp/d+0581glkvvWMFw==", + "dev": true, + "requires": { + "browserslist": "^4.16.6", + "caniuse-api": "^3.0.0" + } + }, + "postcss-reduce-transforms": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-5.1.0.tgz", + "integrity": "sha512-2fbdbmgir5AvpW9RLtdONx1QoYG2/EtqpNQbFASDlixBbAYuTcJ0dECwlqNqH7VbaUnEnh8SrxOe2sRIn24XyQ==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0" + } + }, + "postcss-reporter": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-6.0.1.tgz", + "integrity": "sha512-LpmQjfRWyabc+fRygxZjpRxfhRf9u/fdlKf4VHG4TSPbV2XNsuISzYW1KL+1aQzx53CAppa1bKG4APIB/DOXXw==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "lodash": "^4.17.11", + "log-symbols": "^2.2.0", + "postcss": "^7.0.7" + }, + "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 + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + } + }, + "picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "requires": { + "picocolors": "^0.2.1", + "source-map": "^0.6.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 + }, + "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" + } + } + } + }, + "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-sass": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/postcss-sass/-/postcss-sass-0.3.5.tgz", + "integrity": "sha512-B5z2Kob4xBxFjcufFnhQ2HqJQ2y/Zs/ic5EZbCywCkxKd756Q40cIQ/veRDwSrw1BF6+4wUgmpm0sBASqVi65A==", + "dev": true, + "requires": { + "gonzales-pe": "^4.2.3", + "postcss": "^7.0.1" + }, + "dependencies": { + "picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "requires": { + "picocolors": "^0.2.1", + "source-map": "^0.6.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 + } + } + }, + "postcss-scss": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-4.0.4.tgz", + "integrity": "sha512-aBBbVyzA8b3hUL0MGrpydxxXKXFZc5Eqva0Q3V9qsBOLEMsjb6w49WfpsoWzpEgcqJGW4t7Rio8WXVU9Gd8vWg==", + "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-sorting": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-7.0.1.tgz", + "integrity": "sha512-iLBFYz6VRYyLJEJsBJ8M3TCqNcckVzz4wFounSc5Oez35ogE/X+aoC5fFu103Ot7NyvjU3/xqIXn93Gp3kJk4g==", + "dev": true, + "requires": {} + }, + "postcss-svgo": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-5.1.0.tgz", + "integrity": "sha512-D75KsH1zm5ZrHyxPakAxJWtkyXew5qwS70v56exwvw542d9CRtTo78K0WeFxZB4G7JXKKMbEZtZayTGdIky/eA==", + "dev": true, + "requires": { + "postcss-value-parser": "^4.2.0", + "svgo": "^2.7.0" + } + }, + "postcss-syntax": { + "version": "0.36.2", + "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz", + "integrity": "sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==", + "dev": true, + "requires": {} + }, + "postcss-unique-selectors": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-5.1.1.tgz", + "integrity": "sha512-5JiODlELrz8L2HwxfPnhOWZYWDxVHWL83ufOv84NrcgipI7TaeRsatAhK4Tr2/ZiYldpK/wBvw5BD3qfaK96GA==", + "dev": true, + "requires": { + "postcss-selector-parser": "^6.0.5" + } + }, + "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==" + }, + "prelude-ls": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", + "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==", + "dev": true + }, + "prettier": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz", + "integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==", + "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-error": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-4.0.0.tgz", + "integrity": "sha512-AoJ5YMAcXKYxKhuJGdcvse+Voc6v1RgnsR3nWcYU7q4t6z0Q6T86sv5Zq8VIRbOWWFpvdGE83LtdSMNd+6Y0xw==", + "dev": true, + "requires": { + "lodash": "^4.17.20", + "renderkid": "^3.0.0" + } + }, + "pretty-format": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz", + "integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1", + "ansi-styles": "^5.0.0", + "react-is": "^17.0.1" + }, + "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 + } + } + }, + "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==", + "dev": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "promise-map-series": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/promise-map-series/-/promise-map-series-0.3.0.tgz", + "integrity": "sha512-3npG2NGhTc8BWBolLLf8l/92OxMGaRLbqvIh9wjCHhDXNvk4zsxaTaCpiCunW09qWPrN2zeNSNwRLVBrQQtutA==", + "dev": true + }, + "promise-retry": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/promise-retry/-/promise-retry-2.0.1.tgz", + "integrity": "sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==", + "dev": true, + "requires": { + "err-code": "^2.0.2", + "retry": "^0.12.0" + } + }, + "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" + } + }, + "prop-types": { + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.13.1" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } + } + }, + "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==", + "dev": true, + "requires": { + "forwarded": "0.2.0", + "ipaddr.js": "1.9.1" + }, + "dependencies": { + "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==", + "dev": true + } + } + }, + "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.8.0", + "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", + "integrity": "sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==", + "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==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": 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.10.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.10.3.tgz", + "integrity": "sha512-wr7M2E0OFRfIfJZjKGieI8lBKb7fRCH4Fv5KNPEs7gJ8jadvotdsS08PzOKR7opXhZ/Xkjtt3WF9g38drmyRqQ==", + "dev": true, + "requires": { + "side-channel": "^1.0.4" + } + }, + "queue-microtask": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", + "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==", + "dev": true + }, + "queue-tick": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/queue-tick/-/queue-tick-1.0.1.tgz", + "integrity": "sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==", + "dev": true + }, + "quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true + }, + "quick-temp": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/quick-temp/-/quick-temp-0.1.8.tgz", + "integrity": "sha1-urAqJCq4+w3XWKPJd2sy+aXZRAg=", + "dev": true, + "requires": { + "mktemp": "~0.4.0", + "rimraf": "^2.5.4", + "underscore.string": "~3.3.4" + }, + "dependencies": { + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + } + } + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "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==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "react": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", + "integrity": "sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==", + "requires": { + "loose-envify": "^1.1.0" + } + }, + "react-dom": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.2.0.tgz", + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "requires": { + "loose-envify": "^1.1.0", + "scheduler": "^0.23.0" + }, + "dependencies": { + "scheduler": { + "version": "0.23.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.0.tgz", + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "requires": { + "loose-envify": "^1.1.0" + } + } + } + }, + "react-error-boundary": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz", + "integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==", + "requires": { + "@babel/runtime": "^7.12.5" + } + }, + "react-fast-compare": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz", + "integrity": "sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==" + }, + "react-i18next": { + "version": "11.16.7", + "resolved": "https://registry.npmjs.org/react-i18next/-/react-i18next-11.16.7.tgz", + "integrity": "sha512-7yotILJLnKfvUfrl/nt9eK9vFpVFjZPLWAwBzWL6XppSZZEvlmlKk0GBGDCAPfLfs8oND7WAbry8wGzdoiW5Nw==", + "requires": { + "@babel/runtime": "^7.14.5", + "html-escaper": "^2.0.2", + "html-parse-stringify": "^3.0.1" + } + }, + "react-icons": { + "version": "4.8.0", + "resolved": "https://registry.npmjs.org/react-icons/-/react-icons-4.8.0.tgz", + "integrity": "sha512-N6+kOLcihDiAnj5Czu637waJqSnwlMNROzVZMhfX68V/9bu9qHaMIJC4UdozWoOk57gahFCNHwVvWzm0MTzRjg==", + "requires": {} + }, + "react-is": { + "version": "17.0.2", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", + "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" + }, + "react-player": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/react-player/-/react-player-2.11.0.tgz", + "integrity": "sha512-fIrwpuXOBXdEg1FiyV9isKevZOaaIsAAtZy5fcjkQK9Nhmk1I2NXzY/hkPos8V0zb/ZX416LFy8gv7l/1k3a5w==", + "requires": { + "deepmerge": "^4.0.0", + "load-script": "^1.0.0", + "memoize-one": "^5.1.1", + "prop-types": "^15.7.2", + "react-fast-compare": "^3.0.1" + }, + "dependencies": { + "memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" + } + } + }, + "react-refresh": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.12.0.tgz", + "integrity": "sha512-suLIhrU2IHKL5JEKR/fAwJv7bbeq4kJ+pJopf77jHwuR+HmJS/HbrPIGsTBUVfw7tXPOmYv7UJ7PCaN49e8x4A==", + "dev": true + }, + "react-refresh-typescript": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/react-refresh-typescript/-/react-refresh-typescript-2.0.4.tgz", + "integrity": "sha512-ySsBExEFik5Jjf7NoXtFbzUk2rYWM4gF5gg+wRTNmp9p7B2uMpAAa339FHWqmB8EAr0e6mzzskAXxc0Jd04fBw==", + "dev": true, + "requires": {} + }, + "react-remove-scroll": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.5.5.tgz", + "integrity": "sha512-ImKhrzJJsyXJfBZ4bzu8Bwpka14c/fQt0k+cyFp/PBhTfyDnU5hjOtM4AG/0AMyy8oKzOTR0lDgJIM7pYXI0kw==", + "requires": { + "react-remove-scroll-bar": "^2.3.3", + "react-style-singleton": "^2.2.1", + "tslib": "^2.1.0", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" + } + }, + "react-remove-scroll-bar": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/react-remove-scroll-bar/-/react-remove-scroll-bar-2.3.4.tgz", + "integrity": "sha512-63C4YQBUt0m6ALadE9XV56hV8BgJWDmmTPY758iIJjfQKt2nYwoUrPk0LXRXcB/yIj82T1/Ixfdpdk68LwIB0A==", + "requires": { + "react-style-singleton": "^2.2.1", + "tslib": "^2.0.0" + } + }, + "react-router": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.5.0.tgz", + "integrity": "sha512-fqqUSU0NC0tSX0sZbyuxzuAzvGqbjiZItBQnyicWlOUmzhAU8YuLgRbaCL2hf3sJdtRy4LP/WBrWtARkMvdGPQ==", + "requires": { + "@remix-run/router": "1.1.0" + } + }, + "react-router-dom": { + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.5.0.tgz", + "integrity": "sha512-/XzRc5fq80gW1ctiIGilyKFZC/j4kfe75uivMsTChFbkvrK4ZrF3P3cGIc1f/SSkQ4JiJozPrf+AwUHHWVehVg==", + "requires": { + "@remix-run/router": "1.1.0", + "react-router": "6.5.0" + } + }, + "react-shallow-renderer": { + "version": "16.15.0", + "resolved": "https://registry.npmjs.org/react-shallow-renderer/-/react-shallow-renderer-16.15.0.tgz", + "integrity": "sha512-oScf2FqQ9LFVQgA73vr86xl2NaOIX73rh+YFqcOp68CWj56tSfgtGKrEbyhCj0rSijyG9M1CYprTh39fBi5hzA==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "react-is": "^16.12.0 || ^17.0.0 || ^18.0.0" + } + }, + "react-simple-img": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/react-simple-img/-/react-simple-img-3.0.0.tgz", + "integrity": "sha512-I0sG/GgY9c+04BgWf1YRlipWBQxR3oG2s/bagU8EO7zals3/Vkfk1PJMeYh/wHfjxJtUmal+y7HWEBm4MzXVsQ==", + "requires": {} + }, + "react-style-singleton": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz", + "integrity": "sha512-ZWj0fHEMyWkHzKYUr2Bs/4zU6XLmq9HsgBURm7g5pAVfyn49DgUiNgY2d4lXRlYSiCif9YBGpQleewkcqddc7g==", + "requires": { + "get-nonce": "^1.0.0", + "invariant": "^2.2.4", + "tslib": "^2.0.0" + } + }, + "react-test-renderer": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/react-test-renderer/-/react-test-renderer-18.0.0.tgz", + "integrity": "sha512-SyZTP/FSkwfiKOZuTZiISzsrC8A80KNlQ8PyyoGoOq+VzMAab6Em1POK/CiX3+XyXG6oiJa1C53zYDbdrJu9fw==", + "dev": true, + "requires": { + "react-is": "^18.0.0", + "react-shallow-renderer": "^16.13.1", + "scheduler": "^0.21.0" + }, + "dependencies": { + "react-is": { + "version": "18.0.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.0.0.tgz", + "integrity": "sha512-yUcBYdBBbo3QiPsgYDcfQcIkGZHfxOaoE6HLSnr1sPzMhdyxusbfKOSUbSd/ocGi32dxcj366PsTj+5oggeKKw==", + "dev": true + } + } + }, + "react-textarea-autosize": { + "version": "8.3.4", + "resolved": "https://registry.npmjs.org/react-textarea-autosize/-/react-textarea-autosize-8.3.4.tgz", + "integrity": "sha512-CdtmP8Dc19xL8/R6sWvtknD/eCXkQr30dtvC4VmGInhRsfF8X/ihXCq6+9l9qbxmKRiq407/7z5fxE7cVWQNgQ==", + "requires": { + "@babel/runtime": "^7.10.2", + "use-composed-ref": "^1.3.0", + "use-latest": "^1.2.1" + } + }, + "react-transition-group": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.2.tgz", + "integrity": "sha512-/RNYfRAMlZwDSr6z4zNKV6xu53/e2BuaBbGhbyYIXTrmgu/bGHzmqOs7mJSJBHy9Ud+ApHx3QjrkKSp1pxvlFg==", + "requires": { + "@babel/runtime": "^7.5.5", + "dom-helpers": "^5.0.1", + "loose-envify": "^1.4.0", + "prop-types": "^15.6.2" + } + }, + "react-virtualized-auto-sizer": { + "version": "1.0.17", + "resolved": "https://registry.npmjs.org/react-virtualized-auto-sizer/-/react-virtualized-auto-sizer-1.0.17.tgz", + "integrity": "sha512-XtojyZHGo/iYmGkOEL8psTQsr5XI4fd+QxCD16ru00mnJhuvXFXcPLHXj5cKJh/xUttxPCglnpUI8d2u6gUgzw==", + "requires": {} + }, + "react-window": { + "version": "1.8.9", + "resolved": "https://registry.npmjs.org/react-window/-/react-window-1.8.9.tgz", + "integrity": "sha512-+Eqx/fj1Aa5WnhRfj9dJg4VYATGwIUP2ItwItiJ6zboKWA6EX3lYDAXfGF2hyNqplEprhbtjbipiADEcwQ823Q==", + "requires": { + "@babel/runtime": "^7.0.0", + "memoize-one": ">=3.1.1 <6" + }, + "dependencies": { + "memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" + } + } + }, + "react-window-infinite-loader": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/react-window-infinite-loader/-/react-window-infinite-loader-1.0.9.tgz", + "integrity": "sha512-5Hg89IdU4Vrp0RT8kZYKeTIxWZYhNkVXeI1HbKo01Vm/Z7qztDvXljwx16sMzsa9yapRJQW3ODZfMUw38SOWHw==", + "requires": {} + }, + "read-config-file": { + "version": "6.3.2", + "resolved": "https://registry.npmjs.org/read-config-file/-/read-config-file-6.3.2.tgz", + "integrity": "sha512-M80lpCjnE6Wt6zb98DoW8WHR09nzMSpu8XHtPkiTHrJ5Az9CybfeQhTJ8D7saeBHpGhLPIVyA8lcL6ZmdKwY6Q==", + "dev": true, + "requires": { + "config-file-ts": "^0.2.4", + "dotenv": "^9.0.2", + "dotenv-expand": "^5.1.0", + "js-yaml": "^4.1.0", + "json5": "^2.2.0", + "lazy-val": "^1.0.4" + } + }, + "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==", + "dev": 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" + } + }, + "readdirp": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", + "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "rechoir": { + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.1.tgz", + "integrity": "sha512-/njmZ8s1wVeR6pjTZ+0nCnv8SpZNRMT2D1RLOJQESlYFDBvwpTA4KWJpZ+sBJ4+vhjILRcK7JIFdGCdxEAAitg==", + "dev": true, + "requires": { + "resolve": "^1.9.0" + } + }, + "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" + } + }, + "regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==" + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexp.prototype.flags": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz", + "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.3", + "functions-have-names": "^1.2.2" + } + }, + "regexpp": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-3.2.0.tgz", + "integrity": "sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==", + "dev": true + }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", + "dev": true + }, + "remark": { + "version": "10.0.1", + "resolved": "https://registry.npmjs.org/remark/-/remark-10.0.1.tgz", + "integrity": "sha512-E6lMuoLIy2TyiokHprMjcWNJ5UxfGQjaMSMhV+f4idM625UjjK4j798+gPs5mfjzDE6vL0oFKVeZM6gZVSVrzQ==", + "dev": true, + "requires": { + "remark-parse": "^6.0.0", + "remark-stringify": "^6.0.0", + "unified": "^7.0.0" + } + }, + "remark-parse": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-6.0.3.tgz", + "integrity": "sha512-QbDXWN4HfKTUC0hHa4teU463KclLAnwpn/FBn87j9cKYJWWawbiLgMfP2Q4XwhxxuuuOxHlw+pSN0OKuJwyVvg==", + "dev": true, + "requires": { + "collapse-white-space": "^1.0.2", + "is-alphabetical": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "is-word-character": "^1.0.0", + "markdown-escapes": "^1.0.0", + "parse-entities": "^1.1.0", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "trim": "0.0.1", + "trim-trailing-lines": "^1.0.0", + "unherit": "^1.0.4", + "unist-util-remove-position": "^1.0.0", + "vfile-location": "^2.0.0", + "xtend": "^4.0.1" + } + }, + "remark-stringify": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-6.0.4.tgz", + "integrity": "sha512-eRWGdEPMVudijE/psbIDNcnJLRVx3xhfuEsTDGgH4GsFF91dVhw5nhmnBppafJ7+NWINW6C7ZwWbi30ImJzqWg==", + "dev": true, + "requires": { + "ccount": "^1.0.0", + "is-alphanumeric": "^1.0.0", + "is-decimal": "^1.0.0", + "is-whitespace-character": "^1.0.0", + "longest-streak": "^2.0.1", + "markdown-escapes": "^1.0.0", + "markdown-table": "^1.1.0", + "mdast-util-compact": "^1.0.0", + "parse-entities": "^1.0.2", + "repeat-string": "^1.5.4", + "state-toggle": "^1.0.0", + "stringify-entities": "^1.0.1", + "unherit": "^1.0.4", + "xtend": "^4.0.1" + } + }, + "remove-accents": { + "version": "0.4.2", + "resolved": "https://registry.npmjs.org/remove-accents/-/remove-accents-0.4.2.tgz", + "integrity": "sha512-7pXIJqJOq5tFgG1A2Zxti3Ht8jJF337m4sowbuHsW30ZnkQFnDzy9qBNhgzX8ZLW4+UBcXiiR7SwR6pokHsxiA==" + }, + "remove-bom-buffer": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz", + "integrity": "sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5", + "is-utf8": "^0.2.1" + } + }, + "remove-bom-stream": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/remove-bom-stream/-/remove-bom-stream-1.2.0.tgz", + "integrity": "sha1-BfGlk/FuQuH7kOv1nejlaVJflSM=", + "dev": true, + "requires": { + "remove-bom-buffer": "^3.0.0", + "safe-buffer": "^5.1.0", + "through2": "^2.0.3" + }, + "dependencies": { + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + } + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "renderkid": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/renderkid/-/renderkid-3.0.0.tgz", + "integrity": "sha512-q/7VIQA8lmM1hF+jn+sFSPWGlMkSAeNYcPLmDQx2zzuiDfaLrOmumR8iaUKlenFgh0XRPIUeSPlH3A+AW3Z5pg==", + "dev": true, + "requires": { + "css-select": "^4.1.3", + "dom-converter": "^0.2.0", + "htmlparser2": "^6.1.0", + "lodash": "^4.17.21", + "strip-ansi": "^6.0.1" + } + }, + "repeat-element": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.4.tgz", + "integrity": "sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "replace-ext": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", + "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "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==" + }, + "requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", + "dev": true + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true + }, + "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" + }, + "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-options": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/resolve-options/-/resolve-options-1.1.0.tgz", + "integrity": "sha1-MrueOcBtZzONyTeMDW1gdFZq0TE=", + "dev": true, + "requires": { + "value-or-function": "^3.0.0" + } + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "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": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "requires": { + "lowercase-keys": "^2.0.0" + } + }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dev": true, + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "dev": true + }, + "reusify": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", + "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==", + "dev": true + }, + "rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==", + "dev": true + }, + "rimraf": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz", + "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==", + "dev": true, + "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==", + "dev": true, + "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" + } + }, + "rsvp": { + "version": "4.8.5", + "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", + "integrity": "sha512-nfMOlASu9OnRJo1mbEk2cz0D56a1MBNrJ7orjRZQG10XDyuvwksKbuXNp6qa+kbn839HwjwhBzhFmdsaEAfauA==", + "dev": true + }, + "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==", + "dev": true, + "requires": { + "queue-microtask": "^1.2.2" + } + }, + "runtime-required": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/runtime-required/-/runtime-required-1.1.0.tgz", + "integrity": "sha512-yX97f5E0WfNpcQnfVjap6vzQcvErkYYCx6eTK4siqGEdC8lglwypUFgZVTX7ShvIlgfkC4XGFl9O1KTYcff0pw==", + "dev": true + }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } + } + }, + "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==" + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safe-regex-test": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz", + "integrity": "sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.3", + "is-regex": "^1.1.4" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sanitize-filename": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.3.tgz", + "integrity": "sha512-y/52Mcy7aw3gRm7IrcGDFx/bCk4AhRh2eI9luHOQM86nZsqwiRkkq2GekHXBBD+SmPidc8i2PqtYZl+pWJ8Oeg==", + "dev": true, + "requires": { + "truncate-utf8-bytes": "^1.0.0" + } + }, + "sass": { + "version": "1.50.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.50.0.tgz", + "integrity": "sha512-cLsD6MEZ5URXHStxApajEh7gW189kkjn4Rc8DQweMyF+o5HF5nfEz8QYLMlPsTOD88DknatTmBWkOcw5/LnJLQ==", + "dev": true, + "requires": { + "chokidar": ">=3.0.0 <4.0.0", + "immutable": "^4.0.0", + "source-map-js": ">=0.6.2 <2.0.0" + } + }, + "sass-loader": { + "version": "12.6.0", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-12.6.0.tgz", + "integrity": "sha512-oLTaH0YCtX4cfnJZxKSLAyglED0naiYfNG1iXfU5w1LNZ+ukoA5DtyDIN5zmKVZwYNJP4KRc5Y3hkWga+7tYfA==", + "dev": true, + "requires": { + "klona": "^2.0.4", + "neo-async": "^2.6.2" + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==" + }, + "saxes": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/saxes/-/saxes-5.0.1.tgz", + "integrity": "sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==", + "dev": true, + "requires": { + "xmlchars": "^2.2.0" + } + }, + "scheduler": { + "version": "0.21.0", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.21.0.tgz", + "integrity": "sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0" + } }, "schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - } - } - } - }, - "webpack-dev-server": { - "version": "4.8.1", - "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.8.1.tgz", - "integrity": "sha512-dwld70gkgNJa33czmcj/PlKY/nOy/BimbrgZRaR9vDATBQAYgLzggR0nxDtPLJiLrMgZwbE6RRfJ5vnBBasTyg==", - "dev": true, - "requires": { - "@types/bonjour": "^3.5.9", - "@types/connect-history-api-fallback": "^1.3.5", - "@types/express": "^4.17.13", - "@types/serve-index": "^1.9.1", - "@types/sockjs": "^0.3.33", - "@types/ws": "^8.5.1", - "ansi-html-community": "^0.0.8", - "bonjour-service": "^1.0.11", - "chokidar": "^3.5.3", - "colorette": "^2.0.10", - "compression": "^1.7.4", - "connect-history-api-fallback": "^1.6.0", - "default-gateway": "^6.0.3", - "express": "^4.17.3", - "graceful-fs": "^4.2.6", - "html-entities": "^2.3.2", - "http-proxy-middleware": "^2.0.3", - "ipaddr.js": "^2.0.1", - "open": "^8.0.9", - "p-retry": "^4.5.0", - "portfinder": "^1.0.28", - "rimraf": "^3.0.2", - "schema-utils": "^4.0.0", - "selfsigned": "^2.0.1", - "serve-index": "^1.9.1", - "sockjs": "^0.3.21", - "spdy": "^4.0.2", - "webpack-dev-middleware": "^5.3.1", - "ws": "^8.4.2" - }, - "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" - } + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.1.2.tgz", + "integrity": "sha512-pvjEHOgWc9OWA/f/DE3ohBWTD6EleVLf7iFUkoSwAxttdBhB9QUebQgxER2kWueOvRJXPHNnyrvvh9eZINB8Eg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.8", + "ajv": "^6.12.5", + "ajv-keywords": "^3.5.2" + } }, - "ajv-keywords": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", - "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", - "dev": true, - "requires": { - "fast-deep-equal": "^3.1.3" - } + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", + "dev": true }, - "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 + "selfsigned": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.0.1.tgz", + "integrity": "sha512-LmME957M1zOsUhG+67rAjKfiWFox3SBxE/yymatMZsAx+oMrJ0YQ8AToOnyCm7xbeg2ep37IHLxdu0o2MavQOQ==", + "dev": true, + "requires": { + "node-forge": "^1" + } }, - "schema-utils": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", - "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", - "dev": true, - "requires": { - "@types/json-schema": "^7.0.9", - "ajv": "^8.8.0", - "ajv-formats": "^2.1.1", - "ajv-keywords": "^5.0.0" - } + "semver": { + "version": "7.3.8", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", + "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "requires": { + "lru-cache": "^6.0.0" + } + }, + "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==", + "dev": true, + "optional": true + }, + "send": { + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/send/-/send-0.18.0.tgz", + "integrity": "sha512-qqWzuOjSFOuqPjFe4NOsMLafToQQwBSOEpS+FwEt3A2V3vKubTquT3vmLTQpFgMXp8AlFWFuP1qKaJZOtPpVXg==", + "dev": true, + "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" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "dev": true + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "statuses": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", + "integrity": "sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==", + "dev": true + } + } + }, + "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==", + "dev": true, + "optional": true, + "requires": { + "type-fest": "^0.13.1" + }, + "dependencies": { + "type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "dev": true, + "optional": true + } + } + }, + "serialize-javascript": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-6.0.1.tgz", + "integrity": "sha512-owoXEFjWRllis8/M1Q+Cw5k8ZH40e3zhp/ovX+Xr/vi1qj6QesbyXXViFbpNvWvPNAD62SutwEXavefrLJWj7w==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": 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==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.18.0" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-immediate-shim": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz", + "integrity": "sha1-SysbJ+uAip+NzEgaWOXlb1mfP2E=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true + } + } + }, + "setprototypeof": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", + "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", + "dev": true + }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "shallowequal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/shallowequal/-/shallowequal-1.1.0.tgz", + "integrity": "sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==" + }, + "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==", + "dev": true, + "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==", + "dev": true + }, + "side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "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 + }, + "simple-update-notifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/simple-update-notifier/-/simple-update-notifier-1.1.0.tgz", + "integrity": "sha512-VpsrsJSUcJEseSbMHkrsrAVSdvVS5I96Qo1QAQ4FxQ9wXFcB+pjj7FB7/us9+GcgfW4ziHtYMc1J0PLczb55mg==", + "dev": true, + "requires": { + "semver": "~7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true + } + } + }, + "sirv": { + "version": "1.0.19", + "resolved": "https://registry.npmjs.org/sirv/-/sirv-1.0.19.tgz", + "integrity": "sha512-JuLThK3TnZG1TAKDwNIqNq6QA2afLOCcm+iE8D1Kj3GA40pSPsxQjjJl0J8X3tsR7T+CP1GavpzLwYkgVLWrZQ==", + "dev": true, + "requires": { + "@polka/url": "^1.0.0-next.20", + "mrmime": "^1.0.0", + "totalist": "^1.0.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": "3.0.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-3.0.0.tgz", + "integrity": "sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + }, + "smart-buffer": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", + "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "sockjs": { + "version": "0.3.24", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.24.tgz", + "integrity": "sha512-GJgLTZ7vYb/JtPSSZ10hsOYIvEYsjbNU+zPdIHcUaWVNUEPivzxku31865sSSud0Da0W4lEeOPlmw93zLQchuQ==", + "dev": true, + "requires": { + "faye-websocket": "^0.11.3", + "uuid": "^8.3.2", + "websocket-driver": "^0.7.4" + } + }, + "socks": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/socks/-/socks-2.6.2.tgz", + "integrity": "sha512-zDZhHhZRY9PxRruRMR7kMhnf3I8hDs4S3f9RecfnGxvcBHQcKcIH/oUcEWffsfl1XxdYlA7nnlGbbTvPz9D8gA==", + "dev": true, + "requires": { + "ip": "^1.1.5", + "smart-buffer": "^4.2.0" + } + }, + "sort-keys": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-5.0.0.tgz", + "integrity": "sha512-Pdz01AvCAottHTPQGzndktFNdbRA75BgOfeT1hH+AMnJFv8lynkPi42rfeEhpx1saTEI3YNMWxfqu0sFD1G8pw==", + "dev": true, + "requires": { + "is-plain-obj": "^4.0.0" + }, + "dependencies": { + "is-plain-obj": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.0.0.tgz", + "integrity": "sha512-NXRbBtUdBioI73y/HmOhogw/U5msYPC9DAtGkJXeFcFWSFZw0mCUsPxk/snTuJHzNKA8kLBK4rH97RMB1BfCXw==", + "dev": true + } + } + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==", + "dev": true + }, + "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-resolve": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", + "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0" + } + }, + "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==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "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 + } + } + }, + "source-map-url": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.1.tgz", + "integrity": "sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==", + "dev": true + }, + "spawn-command": { + "version": "0.0.2-1", + "resolved": "https://registry.npmjs.org/spawn-command/-/spawn-command-0.0.2-1.tgz", + "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=", + "dev": true + }, + "spdx-correct": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.1.tgz", + "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "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==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.11", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz", + "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g==", + "dev": true + }, + "spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + } + }, + "spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "specificity": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/specificity/-/specificity-0.4.1.tgz", + "integrity": "sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", + "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==", + "dev": true + }, + "ssr-window": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/ssr-window/-/ssr-window-4.0.2.tgz", + "integrity": "sha512-ISv/Ch+ig7SOtw7G2+qkwfVASzazUnvlDTwypdLoPoySv+6MqlOV10VwPSE6EWkGjhW50lUmghPmpYZXMu/+AQ==" + }, + "stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "dev": 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==", + "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 + } + } + }, + "stackframe": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.3.4.tgz", + "integrity": "sha512-oeVtt7eWQS+Na6F//S4kJ2K2VbRlS9D43mAlMyVpVWovy9o+jfgH8O9agzANzaiLjclA0oYzUXEM4PurhSUChw==", + "dev": true + }, + "stat-mode": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/stat-mode/-/stat-mode-1.0.0.tgz", + "integrity": "sha512-jH9EhtKIjuXZ2cWxmXS8ZP80XyC3iasQxMDV8jzhNJpfDb7VbQLVW4Wvsxz9QZvzV+G4YoSfBUVKDOyxLzi/sg==", + "dev": true + }, + "state-toggle": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", + "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==", + "dev": true + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + } + }, + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, + "streamx": { + "version": "2.13.2", + "resolved": "https://registry.npmjs.org/streamx/-/streamx-2.13.2.tgz", + "integrity": "sha512-+TWqixPhGDXEG9L/XczSbhfkmwAtGs3BJX5QNU6cvno+pOLKeszByWcnaTu6dg8efsTYqR8ZZuXWHhZfgrxMvA==", + "dev": true, + "requires": { + "fast-fifo": "^1.1.0", + "queue-tick": "^1.0.1" + } + }, + "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==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "string-argv": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.1.tgz", + "integrity": "sha512-a1uQGz7IyVy9YwhqjZIZu1c8JO8dNIe20xBmSS6qu9kv++k3JGzCVmprbNN5Kn+BgzD5E7YYwg1CcjuJMRNsvg==", + "dev": true + }, + "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, + "requires": { + "char-regex": "^1.0.2", + "strip-ansi": "^6.0.0" + } + }, + "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": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "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 + } + } + }, + "string.prototype.matchall": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", + "integrity": "sha512-6zOCOcJ+RJAQshcTvXPHoxoQGONa3e/Lqx90wUA+wEzX78sg5Bo+1tQo4N0pohS0erG9qtCqJDjNCQBjeWVxyg==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4", + "get-intrinsic": "^1.1.3", + "has-symbols": "^1.0.3", + "internal-slot": "^1.0.3", + "regexp.prototype.flags": "^1.4.3", + "side-channel": "^1.0.4" + } + }, + "string.prototype.trimend": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz", + "integrity": "sha512-JySq+4mrPf9EsDBEDYMOb/lM7XQLulwg5R/m1r0PXEFqrV0qHvl58sdTilSXtKOflCsK2E8jxf+GKC0T07RWwQ==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "string.prototype.trimstart": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.6.tgz", + "integrity": "sha512-omqjMDaY92pbn5HOX7f9IccLA+U1tA9GvtU4JrodiXFfYB7jPzzHpRzpglLAjtUV6bB557zwClJezTqnAiYnQA==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "define-properties": "^1.1.4", + "es-abstract": "^1.20.4" + } + }, + "stringify-entities": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.2.tgz", + "integrity": "sha512-nrBAQClJAPN2p+uGCVJRPIPakKeKWZ9GtBCmormE7pWOSlHat7+x5A8gx85M7HM5Dt0BP3pP5RhVW77WdbJJ3A==", + "dev": true, + "requires": { + "character-entities-html4": "^1.0.0", + "character-entities-legacy": "^1.0.0", + "is-alphanumerical": "^1.0.0", + "is-hexadecimal": "^1.0.0" + } + }, + "strip-ansi": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "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" + } + }, + "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==", + "dev": true + }, + "style-loader": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-3.3.1.tgz", + "integrity": "sha512-GPcQ+LDJbrcxHORTRes6Jy2sfvK2kS6hpSfI/fXhPt+spVzxF6LJ1dHLN9zIGmVaaP044YKaIatFaufENRiDoQ==", + "dev": true, + "requires": {} + }, + "style-search": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/style-search/-/style-search-0.1.0.tgz", + "integrity": "sha1-eVjHk+R+MuB9K1yv5cC/jhLneQI=", + "dev": true + }, + "styled-components": { + "version": "5.3.11", + "resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.11.tgz", + "integrity": "sha512-uuzIIfnVkagcVHv9nE0VPlHPSCmXIUGKfJ42LNjxCCTDTL5sgnJ8Z7GZBq0EnLYGln77tPpEpExt2+qa+cZqSw==", + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/traverse": "^7.4.5", + "@emotion/is-prop-valid": "^1.1.0", + "@emotion/stylis": "^0.8.4", + "@emotion/unitless": "^0.7.4", + "babel-plugin-styled-components": ">= 1.12.0", + "css-to-react-native": "^3.0.0", + "hoist-non-react-statics": "^3.0.0", + "shallowequal": "^1.1.0", + "supports-color": "^5.5.0" + }, + "dependencies": { + "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==" + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "stylehacks": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-5.1.0.tgz", + "integrity": "sha512-SzLmvHQTrIWfSgljkQCw2++C9+Ne91d/6Sp92I8c5uHTcy/PgeHamwITIbBW9wnFTY/3ZfSXR9HIL6Ikqmcu6Q==", + "dev": true, + "requires": { + "browserslist": "^4.16.6", + "postcss-selector-parser": "^6.0.4" + } + }, + "stylelint": { + "version": "14.9.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-14.9.1.tgz", + "integrity": "sha512-RdAkJdPiLqHawCSnu21nE27MjNXaVd4WcOHA4vK5GtIGjScfhNnaOuWR2wWdfKFAvcWQPOYe311iveiVKSmwsA==", + "dev": true, + "requires": { + "@csstools/selector-specificity": "^2.0.1", + "balanced-match": "^2.0.0", + "colord": "^2.9.2", + "cosmiconfig": "^7.0.1", + "css-functions-list": "^3.1.0", + "debug": "^4.3.4", + "execall": "^2.0.0", + "fast-glob": "^3.2.11", + "fastest-levenshtein": "^1.0.12", + "file-entry-cache": "^6.0.1", + "get-stdin": "^8.0.0", + "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.14", + "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.2.0", + "svg-tags": "^1.0.0", + "table": "^6.8.0", + "v8-compile-cache": "^2.3.0", + "write-file-atomic": "^4.0.1" + }, + "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 + }, + "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 + }, + "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 + }, + "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 + }, + "write-file-atomic": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-4.0.1.tgz", + "integrity": "sha512-nSKUxgAbyioruk6hU87QzVbY279oYT6uiwgDoujth2ju4mJ+TZau7SQBhtbTmUyuNYTuXnSyRn66FV0+eCgcrQ==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "signal-exit": "^3.0.7" + } + } + } + }, + "stylelint-config-rational-order": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/stylelint-config-rational-order/-/stylelint-config-rational-order-0.1.2.tgz", + "integrity": "sha512-Qo7ZQaihCwTqijfZg4sbdQQHtugOX/B1/fYh018EiDZHW+lkqH9uHOnsDwDPGZrYJuB6CoyI7MZh2ecw2dOkew==", + "dev": true, + "requires": { + "stylelint": "^9.10.1", + "stylelint-order": "^2.2.1" + }, + "dependencies": { + "@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "dev": true + }, + "ansi-regex": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", + "integrity": "sha512-ILlv4k/3f6vfQ4OoP2AGvirOktlQ98ZEL1k9FaQjxa3L1abBgbuTDAdPOpvbGncC0BTVQrl+OM8xZGK6tWXt7g==", + "dev": true + }, + "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" + } + }, + "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" + } + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha512-Dxr6QJj/RdU/hCaBjOfxW+q6lyuVE6JFWIrAUpuOOhoJJoQ99cUn3igRaHVB5P9WrgFVN0FfArM3x0cueOU8ng==", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "camelcase": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", + "integrity": "sha512-FxAv7HpHrXbh3aPo4o2qxHay2lkLY3x5Mw3KeE4KQE8ysVfziWeRZDwcjauvwBSGEC/nXUPzZy8zeh4HokqOnw==", + "dev": true + }, + "camelcase-keys": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-4.2.0.tgz", + "integrity": "sha512-Ej37YKYbFUI8QiYlvj9YHb6/Z60dZyPJW0Cs8sFilMbd2lP0bw3ylAq9yJkK4lcTA2dID5fG8LjmJYbO7kWb7Q==", + "dev": true, + "requires": { + "camelcase": "^4.1.0", + "map-obj": "^2.0.0", + "quick-lru": "^1.0.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" + } + }, + "clone-regexp": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/clone-regexp/-/clone-regexp-1.0.1.tgz", + "integrity": "sha512-Fcij9IwRW27XedRIJnSOEupS7RVcXtObJXbcUOX93UCLqqOdRpkvzKywOOSizmEK/Is3S/RHX9dLdfo6R1Q1mw==", + "dev": true, + "requires": { + "is-regexp": "^1.0.0", + "is-supported-regexp-flag": "^1.0.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 + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + } + }, + "dir-glob": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.2.2.tgz", + "integrity": "sha512-f9LBi5QWzIW3I6e//uxZoLBlUt9kcp66qo0sSCxL6YZKc75R1c4MFCoe/LaZiBGmgujvQdxc5Bn3QhfyvK5Hsw==", + "dev": true, + "requires": { + "path-type": "^3.0.0" + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "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 + }, + "execall": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execall/-/execall-1.0.0.tgz", + "integrity": "sha512-/J0Q8CvOvlAdpvhfkD/WnTQ4H1eU0exze2nFGPj/RSC7jpQ0NkKe2r28T5eMkhEEs+fzepMZNy1kVRKNlC04nQ==", + "dev": true, + "requires": { + "clone-regexp": "^1.0.0" + } + }, + "fast-glob": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "dev": true, + "requires": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + } + }, + "file-entry-cache": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-4.0.0.tgz", + "integrity": "sha512-AVSwsnbV8vH/UVbvgEhf3saVQXORNv0ZzSkvkhQIaia5Tia+JhGTaa/ePUSVoPHQyGayQNmYfkzFi3WZV5zcpA==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.2.tgz", + "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==", + "dev": true + }, + "get-stdin": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", + "integrity": "sha512-jp4tHawyV7+fkkSKyvjuLZswblUtz+SQKzSWnBbii16BuZksJlU1wuBYXY75r+duh/llF1ur6oNwi+2ZzjKZ7g==", + "dev": true + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "globby": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-9.2.0.tgz", + "integrity": "sha512-ollPHROa5mcxDEkwg6bPt3QbEf4pDQSNtd6JPL1YvOvAo/7/0VAm9TccUeoTmarjPw4pfUthSCqcyfNB1I3ZSg==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "array-union": "^1.0.2", + "dir-glob": "^2.2.2", + "fast-glob": "^2.2.6", + "glob": "^7.1.3", + "ignore": "^4.0.3", + "pify": "^4.0.1", + "slash": "^2.0.0" + }, + "dependencies": { + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "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 + }, + "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 + }, + "html-tags": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/html-tags/-/html-tags-2.0.0.tgz", + "integrity": "sha512-+Il6N8cCo2wB/Vd3gqy/8TZhTD3QvcVeQLCnZiGkGCH3JP28IgGAY41giccp2W4R3jfyJPAP318FQTa1yU7K7g==", + "dev": true + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + }, + "dependencies": { + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + } + } + }, + "import-lazy": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/import-lazy/-/import-lazy-3.1.0.tgz", + "integrity": "sha512-8/gvXvX2JMn0F+CDlSC4l6kOmVaLOO3XLkksI7CI3Ud95KDYJuYur2b9P/PUt/i/pDAMd/DulQsNbbbmRRsDIQ==", + "dev": true + }, + "indent-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-3.2.0.tgz", + "integrity": "sha512-BYqTHXTGUIvg7t1r4sJNKcbDZkL92nkXA8YtRpbjFHRHGDL/NtUeiBJMeE60kIFN/Mg8ESaWQvftaYMGJzQZCQ==", + "dev": true + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==", + "dev": true + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "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-regexp": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-regexp/-/is-regexp-1.0.0.tgz", + "integrity": "sha512-7zjFAPO4/gwyQAAgRRmqeEeyIICSdmCqa3tsVHMdBzaXXRiqopZL4Cyghg/XulGWrtABTpbnYYzzIRffLkP4oA==", + "dev": true + }, + "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" + } + }, + "known-css-properties": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/known-css-properties/-/known-css-properties-0.11.0.tgz", + "integrity": "sha512-bEZlJzXo5V/ApNNa5z375mJC6Nrz4vG43UgcSCrg2OHC+yuB6j0iDSrY7RQ/+PRofFB03wNIIt9iXIVLr4wc7w==", + "dev": true + }, + "leven": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-2.1.0.tgz", + "integrity": "sha512-nvVPLpIHUxCUoRLrFqTgSxXJ614d8AgQoWl7zPe/2VadE8+1dpU3LBhowRuBAcuwruWtOdD8oYC9jDNJjXDPyA==", + "dev": true + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "log-symbols": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", + "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", + "dev": true, + "requires": { + "chalk": "^2.0.1" + } + }, + "map-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/map-obj/-/map-obj-2.0.0.tgz", + "integrity": "sha512-TzQSV2DiMYgoF5RycneKVUzIa9bQsj/B3tTgsE3dOGqlzHnGIDaC7XBE7grnA+8kZPnfqSGFe95VHc2oc0VFUQ==", + "dev": true + }, + "meow": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/meow/-/meow-5.0.0.tgz", + "integrity": "sha512-CbTqYU17ABaLefO8vCU153ZZlprKYWDljcndKKDCFcYQITzWCXZAVk4QMFZPgvzrnUQ3uItnIE/LoUOwrT15Ig==", + "dev": true, + "requires": { + "camelcase-keys": "^4.0.0", + "decamelize-keys": "^1.0.0", + "loud-rejection": "^1.0.0", + "minimist-options": "^3.0.1", + "normalize-package-data": "^2.3.4", + "read-pkg-up": "^3.0.0", + "redent": "^2.0.0", + "trim-newlines": "^2.0.0", + "yargs-parser": "^10.0.0" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "minimist-options": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/minimist-options/-/minimist-options-3.0.2.tgz", + "integrity": "sha512-FyBrT/d0d4+uiZRbqznPXqw3IpZZG3gl3wKWiX784FycUKVwBt0uLBFkQrtE4tZOrgo78nZp2jnKz3L65T5LdQ==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "is-plain-obj": "^1.1.0" + } + }, + "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" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==", + "dev": true + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==", + "dev": true + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true + } + } + }, + "picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "requires": { + "picocolors": "^0.2.1", + "source-map": "^0.6.1" + } + }, + "postcss-safe-parser": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-safe-parser/-/postcss-safe-parser-4.0.2.tgz", + "integrity": "sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g==", + "dev": true, + "requires": { + "postcss": "^7.0.26" + } + }, + "postcss-scss": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/postcss-scss/-/postcss-scss-2.1.1.tgz", + "integrity": "sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA==", + "dev": true, + "requires": { + "postcss": "^7.0.6" + } + }, + "postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + }, + "postcss-sorting": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-sorting/-/postcss-sorting-4.1.0.tgz", + "integrity": "sha512-r4T2oQd1giURJdHQ/RMb72dKZCuLOdWx2B/XhXN1Y1ZdnwXsKH896Qz6vD4tFy9xSjpKNYhlZoJmWyhH/7JUQw==", + "dev": true, + "requires": { + "lodash": "^4.17.4", + "postcss": "^7.0.0" + } + }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "quick-lru": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-1.1.0.tgz", + "integrity": "sha512-tRS7sTgyxMXtLum8L65daJnHUhfDUgboRdcWW2bR9vBfrj2+O5HSMbQOJfJJjIVSPFqbBCF37FpwWXGitDc5tA==", + "dev": true + }, + "read-pkg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", + "integrity": "sha1-nLxoaXj+5l0WwA4rGcI3/Pbjg4k=", + "dev": true, + "requires": { + "load-json-file": "^4.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^3.0.0" + } + }, + "read-pkg-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-3.0.0.tgz", + "integrity": "sha1-PtSWaF26D4/hGNBpHcUfSh/5bwc=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^3.0.0" + } + }, + "redent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-2.0.0.tgz", + "integrity": "sha1-wbIAe0LVfrE4kHmzyDM2OdXhzKo=", + "dev": true, + "requires": { + "indent-string": "^3.0.0", + "strip-indent": "^2.0.0" + } + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, + "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 + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "strip-indent": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-2.0.0.tgz", + "integrity": "sha1-XvjbKV0B5u1sv3qrlpmNeCJSe2g=", + "dev": true + }, + "stylelint": { + "version": "9.10.1", + "resolved": "https://registry.npmjs.org/stylelint/-/stylelint-9.10.1.tgz", + "integrity": "sha512-9UiHxZhOAHEgeQ7oLGwrwoDR8vclBKlSX7r4fH0iuu0SfPwFaLkb1c7Q2j1cqg9P7IDXeAV2TvQML/fRQzGBBQ==", + "dev": true, + "requires": { + "autoprefixer": "^9.0.0", + "balanced-match": "^1.0.0", + "chalk": "^2.4.1", + "cosmiconfig": "^5.0.0", + "debug": "^4.0.0", + "execall": "^1.0.0", + "file-entry-cache": "^4.0.0", + "get-stdin": "^6.0.0", + "global-modules": "^2.0.0", + "globby": "^9.0.0", + "globjoin": "^0.1.4", + "html-tags": "^2.0.0", + "ignore": "^5.0.4", + "import-lazy": "^3.1.0", + "imurmurhash": "^0.1.4", + "known-css-properties": "^0.11.0", + "leven": "^2.1.0", + "lodash": "^4.17.4", + "log-symbols": "^2.0.0", + "mathml-tag-names": "^2.0.1", + "meow": "^5.0.0", + "micromatch": "^3.1.10", + "normalize-selector": "^0.2.0", + "pify": "^4.0.0", + "postcss": "^7.0.13", + "postcss-html": "^0.36.0", + "postcss-jsx": "^0.36.0", + "postcss-less": "^3.1.0", + "postcss-markdown": "^0.36.0", + "postcss-media-query-parser": "^0.2.3", + "postcss-reporter": "^6.0.0", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-safe-parser": "^4.0.0", + "postcss-sass": "^0.3.5", + "postcss-scss": "^2.0.0", + "postcss-selector-parser": "^3.1.0", + "postcss-syntax": "^0.36.2", + "postcss-value-parser": "^3.3.0", + "resolve-from": "^4.0.0", + "signal-exit": "^3.0.2", + "slash": "^2.0.0", + "specificity": "^0.4.1", + "string-width": "^3.0.0", + "style-search": "^0.1.0", + "sugarss": "^2.0.0", + "svg-tags": "^1.0.0", + "table": "^5.0.0" + } + }, + "stylelint-order": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-2.2.1.tgz", + "integrity": "sha512-019KBV9j8qp1MfBjJuotse6MgaZqGVtXMc91GU9MsS9Feb+jYUvUU3Z8XiClqPdqJZQ0ryXQJGg3U3PcEjXwfg==", + "dev": true, + "requires": { + "lodash": "^4.17.10", + "postcss": "^7.0.2", + "postcss-sorting": "^4.1.0" + } + }, + "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" + } + }, + "table": { + "version": "5.4.6", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.6.tgz", + "integrity": "sha512-wmEc8m4fjnob4gt5riFRtTu/6+4rSe12TpAELNSqHMfF3IqnA+CH37USM6/YR3qRZv7e56kAEAtd6nKZaxe0Ug==", + "dev": true, + "requires": { + "ajv": "^6.10.2", + "lodash": "^4.17.14", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "trim-newlines": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/trim-newlines/-/trim-newlines-2.0.0.tgz", + "integrity": "sha512-MTBWv3jhVjTU7XR3IQHllbiJs8sc75a80OEhB6or/q7pLTWgQ0bMGQXXYQSrSuXe6WiKWDZ5txXY5P59a/coVA==", + "dev": true + }, + "yargs-parser": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-10.1.0.tgz", + "integrity": "sha512-VCIyR1wJoEBZUqk5PA+oOBF6ypbwh5aNB3I50guxAL/quggdfs4TtNHQrSazFA3fYZ+tEqfs0zIGlv0c/rgjbQ==", + "dev": true, + "requires": { + "camelcase": "^4.1.0" + } + } + } + }, + "stylelint-config-recommended": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-7.0.0.tgz", + "integrity": "sha512-yGn84Bf/q41J4luis1AZ95gj0EQwRX8lWmGmBwkwBNSkpGSpl66XcPTulxGa/Z91aPoNGuIGBmFkcM1MejMo9Q==", + "dev": true, + "requires": {} + }, + "stylelint-config-recommended-scss": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-recommended-scss/-/stylelint-config-recommended-scss-6.0.0.tgz", + "integrity": "sha512-6QOe2/OzXV2AP5FE12A7+qtKdZik7Saf42SMMl84ksVBBPpTdrV+9HaCbPYiRMiwELY9hXCVdH4wlJ+YJb5eig==", + "dev": true, + "requires": { + "postcss-scss": "^4.0.2", + "stylelint-config-recommended": "^7.0.0", + "stylelint-scss": "^4.0.0" + } + }, + "stylelint-config-standard": { + "version": "25.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard/-/stylelint-config-standard-25.0.0.tgz", + "integrity": "sha512-21HnP3VSpaT1wFjFvv9VjvOGDtAviv47uTp3uFmzcN+3Lt+RYRv6oAplLaV51Kf792JSxJ6svCJh/G18E9VnCA==", + "dev": true, + "requires": { + "stylelint-config-recommended": "^7.0.0" + } + }, + "stylelint-config-standard-scss": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/stylelint-config-standard-scss/-/stylelint-config-standard-scss-4.0.0.tgz", + "integrity": "sha512-xizu8PTEyB6zYXBiVg6VtvUYn9m57x+6ZtaOdaxsfpbe5eagLPGNlbYnKfm/CfN69ArUpnwR6LjgsTHzlGbtXQ==", + "dev": true, + "requires": { + "stylelint-config-recommended-scss": "^6.0.0", + "stylelint-config-standard": "^25.0.0" + } + }, + "stylelint-config-styled-components": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/stylelint-config-styled-components/-/stylelint-config-styled-components-0.1.1.tgz", + "integrity": "sha512-z5Xz/9GmvxO6e/DLzBMwkB85zHxEEjN6K7Cj80Bi+o/9vR9eS3GX3E9VuMnX9WLFYulqbqLtTapGGY28JBiy9Q==", + "dev": true + }, + "stylelint-order": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/stylelint-order/-/stylelint-order-5.0.0.tgz", + "integrity": "sha512-OWQ7pmicXufDw5BlRqzdz3fkGKJPgLyDwD1rFY3AIEfIH/LQY38Vu/85v8/up0I+VPiuGRwbc2Hg3zLAsJaiyw==", + "dev": true, + "requires": { + "postcss": "^8.3.11", + "postcss-sorting": "^7.0.1" + } + }, + "stylelint-processor-styled-components": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/stylelint-processor-styled-components/-/stylelint-processor-styled-components-1.10.0.tgz", + "integrity": "sha512-g4HpN9rm0JD0LoHuIOcd/FIjTZCJ0ErQ+dC3VTxp+dSvnkV+MklKCCmCQEdz5K5WxF4vPuzfVgdbSDuPYGZhoA==", + "dev": true, + "requires": { + "@babel/parser": "^7.8.3", + "@babel/traverse": "^7.8.3", + "micromatch": "^4.0.2", + "postcss": "^7.0.26" + }, + "dependencies": { + "picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "requires": { + "picocolors": "^0.2.1", + "source-map": "^0.6.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 + } + } + }, + "stylelint-scss": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/stylelint-scss/-/stylelint-scss-4.3.0.tgz", + "integrity": "sha512-GvSaKCA3tipzZHoz+nNO7S02ZqOsdBzMiCx9poSmLlb3tdJlGddEX/8QzCOD8O7GQan9bjsvLMsO5xiw6IhhIQ==", + "dev": true, + "requires": { + "lodash": "^4.17.21", + "postcss-media-query-parser": "^0.2.3", + "postcss-resolve-nested-selector": "^0.1.1", + "postcss-selector-parser": "^6.0.6", + "postcss-value-parser": "^4.1.0" + } + }, + "stylis": { + "version": "4.0.13", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.0.13.tgz", + "integrity": "sha512-xGPXiFVl4YED9Jh7Euv2V220mriG9u4B2TA6Ybjc1catrstKD2PpIdU3U0RKpkVBC2EhmL/F0sPCr9vrFTNRag==" + }, + "sugarss": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/sugarss/-/sugarss-2.0.0.tgz", + "integrity": "sha512-WfxjozUk0UVA4jm+U1d736AUpzSrNsQcIbyOkoE364GrtWmIrFdk5lksEupgWMD4VaT/0kVx1dobpiDumSgmJQ==", + "dev": true, + "requires": { + "postcss": "^7.0.2" + }, + "dependencies": { + "picocolors": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-0.2.1.tgz", + "integrity": "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==", + "dev": true + }, + "postcss": { + "version": "7.0.39", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.39.tgz", + "integrity": "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==", + "dev": true, + "requires": { + "picocolors": "^0.2.1", + "source-map": "^0.6.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 + } + } + }, + "sumchecker": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/sumchecker/-/sumchecker-3.0.1.tgz", + "integrity": "sha512-MvjXzkz/BOfyVDkG0oFOtBxHX2u3gKbMHIF/dXblZsgD3BWOFLmHovIpZY7BykJdAjcqRCBi1WYBNdEC9yI7vg==", + "dev": true, + "requires": { + "debug": "^4.1.0" + } + }, + "superjson": { + "version": "1.11.0", + "resolved": "https://registry.npmjs.org/superjson/-/superjson-1.11.0.tgz", + "integrity": "sha512-6PfAg1FKhqkwWvPb2uXhH4MkMttdc17eJ91+Aoz4s1XUEDZFmLfFx/xVA3wgkPxAGy5dpozgGdK6V/n20Wj9yg==", + "requires": { + "copy-anything": "^3.0.2" + } + }, + "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==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "supports-hyperlinks": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.2.0.tgz", + "integrity": "sha512-6sXEzV5+I5j8Bmq9/vUphGRM/RJNT9SCURJLjwfOg51heRtguGWDzcaBlgAzKhQa0EVNpPEKzQuBwZ8S8WaCeQ==", + "dev": true, + "requires": { + "has-flag": "^4.0.0", + "supports-color": "^7.0.0" + } + }, + "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==" + }, + "svg-tags": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/svg-tags/-/svg-tags-1.0.0.tgz", + "integrity": "sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q=", + "dev": true + }, + "svgo": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-2.8.0.tgz", + "integrity": "sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==", + "dev": true, + "requires": { + "@trysound/sax": "0.2.0", + "commander": "^7.2.0", + "css-select": "^4.1.3", + "css-tree": "^1.1.3", + "csso": "^4.2.0", + "picocolors": "^1.0.0", + "stable": "^0.1.8" + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + } + } + }, + "swiper": { + "version": "9.3.1", + "resolved": "https://registry.npmjs.org/swiper/-/swiper-9.3.1.tgz", + "integrity": "sha512-YBDf0DLBLO7O4rwYHfz+HltkY4sDwKSbRf1it56rngpkYHxiKg0NkPMXAFmw2nGvMNQJwV14Dse47hQIifJzzA==", + "requires": { + "ssr-window": "^4.0.2" + } + }, + "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 + }, + "symlink-or-copy": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/symlink-or-copy/-/symlink-or-copy-1.3.1.tgz", + "integrity": "sha512-0K91MEXFpBUaywiwSSkmKjnGcasG/rVBXFLJz5DrgGabpYD6N+3yZrfD6uUIfpuTu65DZLHi7N8CizHc07BPZA==", + "dev": true + }, + "tabbable": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.1.1.tgz", + "integrity": "sha512-4kl5w+nCB44EVRdO0g/UGoOp3vlwgycUVtkk/7DPyeLZUCuNFFKCFG6/t/DgHLrUPHjrZg6s5tNm+56Q2B0xyg==" + }, + "table": { + "version": "6.8.0", + "resolved": "https://registry.npmjs.org/table/-/table-6.8.0.tgz", + "integrity": "sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==", + "dev": true, + "requires": { + "ajv": "^8.0.1", + "lodash.truncate": "^4.4.2", + "slice-ansi": "^4.0.0", + "string-width": "^4.2.3", + "strip-ansi": "^6.0.1" + }, + "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 + }, + "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, + "requires": { + "ansi-styles": "^4.0.0", + "astral-regex": "^2.0.0", + "is-fullwidth-code-point": "^3.0.0" + } + } + } + }, + "tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true + }, + "tar": { + "version": "6.1.13", + "resolved": "https://registry.npmjs.org/tar/-/tar-6.1.13.tgz", + "integrity": "sha512-jdIBIN6LTIe2jqzay/2vtYLlBHa3JF42ot3h1dW8Q0PaAG4v8rm0cvpVePtau5C6OKXGGcgO9q2AMNSWxiLqKw==", + "dev": true, + "requires": { + "chownr": "^2.0.0", + "fs-minipass": "^2.0.0", + "minipass": "^4.0.0", + "minizlib": "^2.1.1", + "mkdirp": "^1.0.3", + "yallist": "^4.0.0" + }, + "dependencies": { + "minipass": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.5.tgz", + "integrity": "sha512-+yQl7SX3bIT83Lhb4BVorMAHVuqsskxRdlmO9kTpyukp8vsm2Sn/fUOV9xlnG8/a5JsypJzap21lz/y3FBMJ8Q==", + "dev": true + }, + "mkdirp": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", + "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", + "dev": true + } + } + }, + "teex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", + "integrity": "sha512-eYE6iEI62Ni1H8oIa7KlDU6uQBtqr4Eajni3wX7rpfXD8ysFx8z0+dri+KWEPWpBsxXfxu58x/0jvTVT1ekOSg==", + "dev": true, + "requires": { + "streamx": "^2.12.5" + } + }, + "temp-file": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/temp-file/-/temp-file-3.4.0.tgz", + "integrity": "sha512-C5tjlC/HCtVUOi3KWVokd4vHVViOmGjtLwIh4MuzPo/nMYTV/p1urt3RnMz2IWXDdKEGJH3k5+KPxtqRsUYGtg==", + "dev": true, + "requires": { + "async-exit-hook": "^2.0.1", + "fs-extra": "^10.0.0" + }, + "dependencies": { + "fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + }, + "jsonfile": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", + "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6", + "universalify": "^2.0.0" + } + }, + "universalify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz", + "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==", + "dev": true + } + } + }, + "terminal-link": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz", + "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==", + "dev": true, + "requires": { + "ansi-escapes": "^4.2.1", + "supports-hyperlinks": "^2.0.0" + } + }, + "terser": { + "version": "5.17.7", + "resolved": "https://registry.npmjs.org/terser/-/terser-5.17.7.tgz", + "integrity": "sha512-/bi0Zm2C6VAexlGgLlVxA0P2lru/sdLyfCVaRMfKVo9nWxbmz7f/sD8VPybPeSUJaJcwmCJis9pBIhcVcG1QcQ==", + "dev": true, + "requires": { + "@jridgewell/source-map": "^0.3.3", + "acorn": "^8.8.2", + "commander": "^2.20.0", + "source-map-support": "~0.5.20" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + } + } + }, + "terser-webpack-plugin": { + "version": "5.3.9", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-5.3.9.tgz", + "integrity": "sha512-ZuXsqE07EcggTWQjXUj+Aot/OMcD0bMKGgF63f7UxYcu5/AJF53aIpK1YoP5xR9l6s/Hy2b+t1AM0bLNPRuhwA==", + "dev": true, + "requires": { + "@jridgewell/trace-mapping": "^0.3.17", + "jest-worker": "^27.4.5", + "schema-utils": "^3.1.1", + "serialize-javascript": "^6.0.1", + "terser": "^5.16.8" + } + }, + "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": { + "@istanbuljs/schema": "^0.1.2", + "glob": "^7.1.4", + "minimatch": "^3.0.4" + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "throat": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.1.tgz", + "integrity": "sha512-8hmiGIJMDlwjg7dlJ4yKGLK8EsYqKgPWbG3b4wjJddKNwc7N7Dpn08Df4szr/sZdMVeOstrdYSsqzX6BYbcB+w==", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/through2/-/through2-4.0.2.tgz", + "integrity": "sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==", + "dev": true, + "requires": { + "readable-stream": "3" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "through2-filter": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/through2-filter/-/through2-filter-3.0.0.tgz", + "integrity": "sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==", + "dev": true, + "requires": { + "through2": "~2.0.0", + "xtend": "~4.0.0" + }, + "dependencies": { + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + } + } + }, + "thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "tmp": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz", + "integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==", + "dev": true, + "requires": { + "rimraf": "^3.0.0" + } + }, + "tmp-promise": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz", + "integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==", + "dev": true, + "requires": { + "tmp": "^0.2.0" + } + }, + "tmpl": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", + "dev": true + }, + "to-absolute-glob": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/to-absolute-glob/-/to-absolute-glob-2.0.2.tgz", + "integrity": "sha1-GGX0PZ50sIItufFFt4z/fQ98hJs=", + "dev": true, + "requires": { + "is-absolute": "^1.0.0", + "is-negated-glob": "^1.0.0" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=" + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "to-through": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-through/-/to-through-2.0.0.tgz", + "integrity": "sha1-/JKtq6ByZHvAtn1rA2ZKoZUJOvY=", + "dev": true, + "requires": { + "through2": "^2.0.3" + }, + "dependencies": { + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + } + } + }, + "toidentifier": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", + "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", + "dev": true + }, + "totalist": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/totalist/-/totalist-1.1.0.tgz", + "integrity": "sha512-gduQwd1rOdDMGxFG1gEvhV88Oirdo2p+KjoYFU7k2g+i7n6AFFbDQ5kMPUsW0pNbfQsB/cwXvT1i4Bue0s9g5g==", + "dev": true + }, + "tough-cookie": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.0.0.tgz", + "integrity": "sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==", + "dev": true, + "requires": { + "psl": "^1.1.33", + "punycode": "^2.1.1", + "universalify": "^0.1.2" + } + }, + "tr46": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-2.1.0.tgz", + "integrity": "sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==", + "dev": true, + "requires": { + "punycode": "^2.1.1" + } + }, + "tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true + }, + "trim": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", + "integrity": "sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ==", + "dev": true + }, + "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 + }, + "trim-trailing-lines": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz", + "integrity": "sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==", + "dev": true + }, + "trough": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", + "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", + "dev": true + }, + "truncate-utf8-bytes": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz", + "integrity": "sha512-95Pu1QXQvruGEhv62XCMO3Mm90GscOCClvrIUwCM0PYOXK3kaF3l3sIHxx71ThJfcbM2O5Au6SO3AWCSEfW4mQ==", + "dev": true, + "requires": { + "utf8-byte-length": "^1.0.1" + } + }, + "ts-jest": { + "version": "27.1.4", + "resolved": "https://registry.npmjs.org/ts-jest/-/ts-jest-27.1.4.tgz", + "integrity": "sha512-qjkZlVPWVctAezwsOD1OPzbZ+k7zA5z3oxII4dGdZo5ggX/PL7kvwTM0pXTr10fAtbiVpJaL3bWd502zAhpgSQ==", + "dev": true, + "requires": { + "bs-logger": "0.x", + "fast-json-stable-stringify": "2.x", + "jest-util": "^27.0.0", + "json5": "2.x", + "lodash.memoize": "4.x", + "make-error": "1.x", + "semver": "7.x", + "yargs-parser": "20.x" + } + }, + "ts-loader": { + "version": "9.2.8", + "resolved": "https://registry.npmjs.org/ts-loader/-/ts-loader-9.2.8.tgz", + "integrity": "sha512-gxSak7IHUuRtwKf3FIPSW1VpZcqF9+MBrHOvBp9cjHh+525SjtCIJKVGjRKIAfxBwDGDGCFF00rTfzB1quxdSw==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.0.0", + "micromatch": "^4.0.0", + "semver": "^7.3.4" + }, + "dependencies": { + "enhanced-resolve": { + "version": "5.9.2", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.9.2.tgz", + "integrity": "sha512-GIm3fQfwLJ8YZx2smuHpBKkXC1yOk+OBEmKckVyL0i/ea8mqDEykK3ld5dgH1QYPNyT/lIllxV2LULnxCHaHkA==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + } + } + }, + "ts-node": { + "version": "10.7.0", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", + "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", + "dev": true, + "requires": { + "@cspotcode/source-map-support": "0.7.0", + "@tsconfig/node10": "^1.0.7", + "@tsconfig/node12": "^1.0.7", + "@tsconfig/node14": "^1.0.0", + "@tsconfig/node16": "^1.0.2", + "acorn": "^8.4.1", + "acorn-walk": "^8.1.1", + "arg": "^4.1.0", + "create-require": "^1.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "v8-compile-cache-lib": "^3.0.0", + "yn": "3.1.1" + }, + "dependencies": { + "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 + } + } + }, + "tsconfig-paths": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz", + "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==", + "dev": true, + "requires": { + "@types/json5": "^0.0.29", + "json5": "^1.0.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + }, + "dependencies": { + "json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + } + } + }, + "tsconfig-paths-webpack-plugin": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths-webpack-plugin/-/tsconfig-paths-webpack-plugin-4.0.0.tgz", + "integrity": "sha512-fw/7265mIWukrSHd0i+wSwx64kYUSAKPfxRDksjKIYTxSAp9W9/xcZVBF4Kl0eqQd5eBpAQ/oQrc5RyM/0c1GQ==", + "dev": true, + "requires": { + "chalk": "^4.1.0", + "enhanced-resolve": "^5.7.0", + "tsconfig-paths": "^4.0.0" + }, + "dependencies": { + "enhanced-resolve": { + "version": "5.10.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.10.0.tgz", + "integrity": "sha512-T0yTFjdpldGY8PmuXXR0PyQ1ufZpEGiHVrp7zHKB7jdR4qlmZHhONVM5AQOAWXuF/w3dnHbEQVrNptJgt7F+cQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true + }, + "tsconfig-paths": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.1.0.tgz", + "integrity": "sha512-AHx4Euop/dXFC+Vx589alFba8QItjF+8hf8LtmuiCwHyI4rHXQtOOENaM8kvYf5fR0dRChy3wzWIZ9WbB7FWow==", + "dev": true, + "requires": { + "json5": "^2.2.1", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + } + } + }, + "tslib": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.4.1.tgz", + "integrity": "sha512-tGyy4dAjRIEwI7BzsB0lynWgOpfqjUdq91XXAlIWD2OwKBH7oCl/GZG/HT4BOHrTlPMOASlMQ7veyTqpmRcrNA==" + }, + "tsutils": { + "version": "3.21.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", + "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + }, + "dependencies": { + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + } + } + }, + "type-check": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", + "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==", + "dev": true, + "requires": { + "prelude-ls": "^1.2.1" + } + }, + "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 + }, + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "typedarray-to-buffer": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/typedarray-to-buffer/-/typedarray-to-buffer-3.1.5.tgz", + "integrity": "sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==", + "dev": true, + "requires": { + "is-typedarray": "^1.0.0" + } + }, + "typescript": { + "version": "4.8.4", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.8.4.tgz", + "integrity": "sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==", + "dev": true + }, + "typescript-plugin-styled-components": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/typescript-plugin-styled-components/-/typescript-plugin-styled-components-2.0.0.tgz", + "integrity": "sha512-Wu7F96dwuphgiACHfu63vTbRRg6tkPwLnpFJwdxM70Y0PLfeKLRnvs2Yo5MAySMwE120ODMKk9W4TtJgY1ZumA==", + "dev": true, + "requires": {} + }, + "unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "requires": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + } + }, + "unc-path-regex": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/unc-path-regex/-/unc-path-regex-0.1.2.tgz", + "integrity": "sha1-5z3T17DXxe2G+6xrCufYxqadUPo=", + "dev": true + }, + "underscore.string": { + "version": "3.3.6", + "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz", + "integrity": "sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ==", + "dev": true, + "requires": { + "sprintf-js": "^1.1.1", + "util-deprecate": "^1.0.2" + } + }, + "unherit": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", + "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", + "dev": true, + "requires": { + "inherits": "^2.0.0", + "xtend": "^4.0.0" + } + }, + "unified": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/unified/-/unified-7.1.0.tgz", + "integrity": "sha512-lbk82UOIGuCEsZhPj8rNAkXSDXd6p0QLzIuSsCdxrqnqU56St4eyOB+AlXsVgVeRmetPTYydIuvFfpDIed8mqw==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "@types/vfile": "^3.0.0", + "bail": "^1.0.0", + "extend": "^3.0.0", + "is-plain-obj": "^1.1.0", + "trough": "^1.0.0", + "vfile": "^3.0.0", + "x-is-string": "^0.1.0" + }, + "dependencies": { + "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 + } + } + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==", + "dev": true + } + } + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "unique-stream": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/unique-stream/-/unique-stream-2.3.1.tgz", + "integrity": "sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==", + "dev": true, + "requires": { + "json-stable-stringify-without-jsonify": "^1.0.1", + "through2-filter": "^3.0.0" + } + }, + "unist-util-find-all-after": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/unist-util-find-all-after/-/unist-util-find-all-after-1.0.5.tgz", + "integrity": "sha512-lWgIc3rrTMTlK1Y0hEuL+k+ApzFk78h+lsaa2gHf63Gp5Ww+mt11huDniuaoq1H+XMK2lIIjjPkncxXcDp3QDw==", + "dev": true, + "requires": { + "unist-util-is": "^3.0.0" + } + }, + "unist-util-is": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", + "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==", + "dev": true + }, + "unist-util-remove-position": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz", + "integrity": "sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==", + "dev": true, + "requires": { + "unist-util-visit": "^1.1.0" + } + }, + "unist-util-stringify-position": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", + "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==", + "dev": true + }, + "unist-util-visit": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", + "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "dev": true, + "requires": { + "unist-util-visit-parents": "^2.0.0" + } + }, + "unist-util-visit-parents": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", + "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "dev": true, + "requires": { + "unist-util-is": "^3.0.0" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unixify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unixify/-/unixify-1.0.0.tgz", + "integrity": "sha1-OmQcjC/7zk2mg6XHDwOkYpQMIJA=", + "dev": true, + "requires": { + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==", + "dev": true + } + } + }, + "unzip-crx-3": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/unzip-crx-3/-/unzip-crx-3-0.2.0.tgz", + "integrity": "sha512-0+JiUq/z7faJ6oifVB5nSwt589v1KCduqIJupNVDoWSXZtWDmjDGO3RAEOvwJ07w90aoXoP4enKsR7ecMrJtWQ==", + "dev": true, + "requires": { + "jszip": "^3.1.0", + "mkdirp": "^0.5.1", + "yaku": "^0.16.6" + } + }, + "update-browserslist-db": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz", + "integrity": "sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==", + "requires": { + "escalade": "^3.1.1", + "picocolors": "^1.0.0" + } + }, + "uri-js": { + "version": "4.4.1", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", + "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url-loader": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/url-loader/-/url-loader-4.1.1.tgz", + "integrity": "sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA==", + "dev": true, + "requires": { + "loader-utils": "^2.0.0", + "mime-types": "^2.1.27", + "schema-utils": "^3.0.0" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "use-callback-ref": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.0.tgz", + "integrity": "sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==", + "requires": { + "tslib": "^2.0.0" + } + }, + "use-composed-ref": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-composed-ref/-/use-composed-ref-1.3.0.tgz", + "integrity": "sha512-GLMG0Jc/jiKov/3Ulid1wbv3r54K9HlMW29IWcDFPEqFkSO2nS0MuefWgMJpeHQ9YJeXDL3ZUF+P3jdXlZX/cQ==", + "requires": {} + }, + "use-isomorphic-layout-effect": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.1.2.tgz", + "integrity": "sha512-49L8yCO3iGT/ZF9QttjwLF/ZD9Iwto5LnH5LmEdk/6cFmXddqi2ulF0edxTwjj+7mqvpVVGQWvbXZdn32wRSHA==", + "requires": {} + }, + "use-latest": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/use-latest/-/use-latest-1.2.1.tgz", + "integrity": "sha512-xA+AVm/Wlg3e2P/JiItTziwS7FK92LWrDB0p+hgXloIMuVCeJJ8v6f0eeHyPZaJrM+usM1FkFfbNCrJGs8A/zw==", + "requires": { + "use-isomorphic-layout-effect": "^1.1.1" + } + }, + "use-sidecar": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", + "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", + "requires": { + "detect-node-es": "^1.1.0", + "tslib": "^2.0.0" + } + }, + "use-sync-external-store": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz", + "integrity": "sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==", + "requires": {} + }, + "utf8-byte-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz", + "integrity": "sha512-4+wkEYLBbWxqTahEsWrhxepcoVOJ+1z5PGIjPZxRkytcdSUaNjIjBM7Xn8E+pdSuV7SzvWovBFA54FO0JSoqhA==", + "dev": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "utila": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/utila/-/utila-0.4.0.tgz", + "integrity": "sha1-ihagXURWV6Oupe7MWxKk+lN5dyw=", + "dev": true + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true + }, + "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 + }, + "v8-compile-cache-lib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", + "integrity": "sha512-wa7YjyUGfNZngI/vtK0UHAN+lgDCxBPCylVXGp0zu59Fz5aiGtNXaq3DhIov063MorB+VfufLh3JlF2KdTK3xg==", + "dev": true + }, + "v8-to-istanbul": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/v8-to-istanbul/-/v8-to-istanbul-8.1.1.tgz", + "integrity": "sha512-FGtKtv3xIpR6BYhvgH8MI/y78oT7d8Au3ww4QIxymrCtZEh5b8gCw2siywE+puhEmuWKDtmfrvF5UlB298ut3w==", + "dev": true, + "requires": { + "@types/istanbul-lib-coverage": "^2.0.1", + "convert-source-map": "^1.6.0", + "source-map": "^0.7.3" + } + }, + "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": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "value-or-function": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/value-or-function/-/value-or-function-3.0.0.tgz", + "integrity": "sha1-HCQ6ULWVwb5Up1S/7OhWO5/42BM=", + "dev": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, + "verror": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.1.tgz", + "integrity": "sha512-veufcmxri4e3XSrT0xwfUR7kguIkaxBeosDg00yDWhk49wdwkSUrvvsm7nc75e1PUyvIeZj6nS8VQRYz2/S4Xg==", + "dev": true, + "optional": true, + "requires": { + "assert-plus": "^1.0.0", + "core-util-is": "1.0.2", + "extsprintf": "^1.2.0" + }, + "dependencies": { + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true, + "optional": true + } + } + }, + "vfile": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-3.0.1.tgz", + "integrity": "sha512-y7Y3gH9BsUSdD4KzHsuMaCzRjglXN0W2EcMf0gpvu6+SbsGhMje7xDc8AEoeXy6mIwCKMI6BkjMsRjzQbhMEjQ==", + "dev": true, + "requires": { + "is-buffer": "^2.0.0", + "replace-ext": "1.0.0", + "unist-util-stringify-position": "^1.0.0", + "vfile-message": "^1.0.0" + }, + "dependencies": { + "is-buffer": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.5.tgz", + "integrity": "sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==", + "dev": true + }, + "replace-ext": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", + "integrity": "sha1-3mMSg3P8v3w8z6TeWkgMRaZ5WOs=", + "dev": true + }, + "vfile-message": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz", + "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==", + "dev": true, + "requires": { + "unist-util-stringify-position": "^1.1.1" + } + } + } + }, + "vfile-location": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.6.tgz", + "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==", + "dev": true + }, + "vfile-message": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.2.tgz", + "integrity": "sha512-QjSNP6Yxzyycd4SVOtmKKyTsSvClqBPJcd00Z0zuPj3hOIjg0rUPG6DbFGPvUKRgYyaIWLPKpuEclcuvb3H8qA==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0", + "unist-util-stringify-position": "^3.0.0" + }, + "dependencies": { + "unist-util-stringify-position": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.2.tgz", + "integrity": "sha512-7A6eiDCs9UtjcwZOcCpM4aPII3bAAGv13E96IkawkOAW0OhH+yRxtY0lzo8KiHpzEMfH7Q+FizUmwp8Iqy5EWg==", + "dev": true, + "requires": { + "@types/unist": "^2.0.0" + } + } + } + }, + "vinyl": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/vinyl/-/vinyl-2.2.1.tgz", + "integrity": "sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==", + "dev": true, + "requires": { + "clone": "^2.1.1", + "clone-buffer": "^1.0.0", + "clone-stats": "^1.0.0", + "cloneable-readable": "^1.0.0", + "remove-trailing-separator": "^1.0.1", + "replace-ext": "^1.0.0" + }, + "dependencies": { + "clone": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/clone/-/clone-2.1.2.tgz", + "integrity": "sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=", + "dev": true + } + } + }, + "vinyl-fs": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/vinyl-fs/-/vinyl-fs-3.0.3.tgz", + "integrity": "sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==", + "dev": true, + "requires": { + "fs-mkdirp-stream": "^1.0.0", + "glob-stream": "^6.1.0", + "graceful-fs": "^4.0.0", + "is-valid-glob": "^1.0.0", + "lazystream": "^1.0.0", + "lead": "^1.0.0", + "object.assign": "^4.0.4", + "pumpify": "^1.3.5", + "readable-stream": "^2.3.3", + "remove-bom-buffer": "^3.0.0", + "remove-bom-stream": "^1.2.0", + "resolve-options": "^1.1.0", + "through2": "^2.0.0", + "to-through": "^2.0.0", + "value-or-function": "^3.0.0", + "vinyl": "^2.0.0", + "vinyl-sourcemap": "^1.1.0" + }, + "dependencies": { + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + } + } + }, + "vinyl-sourcemap": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/vinyl-sourcemap/-/vinyl-sourcemap-1.1.0.tgz", + "integrity": "sha1-kqgAWTo4cDqM2xHYswCtS+Y7PhY=", + "dev": true, + "requires": { + "append-buffer": "^1.0.2", + "convert-source-map": "^1.5.0", + "graceful-fs": "^4.1.6", + "normalize-path": "^2.1.1", + "now-and-later": "^2.0.0", + "remove-bom-buffer": "^3.0.0", + "vinyl": "^2.0.0" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "void-elements": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/void-elements/-/void-elements-3.1.0.tgz", + "integrity": "sha1-YU9/v42AHwu18GYfWy9XhXUOTwk=" + }, + "vue-template-compiler": { + "version": "2.6.14", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.14.tgz", + "integrity": "sha512-ODQS1SyMbjKoO1JBJZojSw6FE4qnh9rIpUZn2EUT86FKizx9uH5z6uXiIrm4/Nb/gwxTi/o17ZDEGWAXHvtC7g==", + "dev": true, + "requires": { + "de-indent": "^1.0.2", + "he": "^1.1.0" + } + }, + "w3c-hr-time": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/w3c-hr-time/-/w3c-hr-time-1.0.2.tgz", + "integrity": "sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==", + "dev": true, + "requires": { + "browser-process-hrtime": "^1.0.0" + } + }, + "w3c-xmlserializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/w3c-xmlserializer/-/w3c-xmlserializer-2.0.0.tgz", + "integrity": "sha512-4tzD0mF8iSiMiNs30BiLO3EpfGLZUT2MSX/G+o7ZywDzliWQ3OPtTZ0PTC3B3ca1UAf4cJMHB+2Bf56EriJuRA==", + "dev": true, + "requires": { + "xml-name-validator": "^3.0.0" + } + }, + "walk-sync": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/walk-sync/-/walk-sync-2.2.0.tgz", + "integrity": "sha512-IC8sL7aB4/ZgFcGI2T1LczZeFWZ06b3zoHH7jBPyHxOtIIz1jppWHjjEXkOFvFojBVAK9pV7g47xOZ4LW3QLfg==", + "dev": true, + "requires": { + "@types/minimatch": "^3.0.3", + "ensure-posix-path": "^1.1.0", + "matcher-collection": "^2.0.0", + "minimatch": "^3.0.4" + } + }, + "walker": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", + "dev": true, + "requires": { + "makeerror": "1.0.12" + } + }, + "watchboy": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/watchboy/-/watchboy-0.4.3.tgz", + "integrity": "sha512-GHs1HxwvxSMBsqd/WfTOZhj5gBdMqf5HQpfgtKxDfZRxrlYPDdVLRB61LCeRzJaWANmvSIMlfmRVDwVmJFgAKA==", + "dev": true, + "requires": { + "lodash.difference": "^4.5.0", + "micromatch": "^4.0.2", + "pify": "^4.0.1", + "unixify": "^1.0.0" + }, + "dependencies": { + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + } + } + }, + "watchpack": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.0.tgz", + "integrity": "sha512-Lcvm7MGST/4fup+ifyKi2hjyIAwcdI4HRgtvTpIUxBRhB+RFtUh8XtDOxUfctVCnhVi+QQj49i91OyvzkJl6cg==", + "dev": true, + "requires": { + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.1.2" + } + }, + "wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "requires": { + "minimalistic-assert": "^1.0.0" + } + }, + "wcwidth": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", + "integrity": "sha1-8LDc+RW8X/FSivrbLA4XtTLaL+g=", + "dev": true, + "requires": { + "defaults": "^1.0.3" + } + }, + "webidl-conversions": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-6.1.0.tgz", + "integrity": "sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==", + "dev": true + }, + "webpack": { + "version": "5.85.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-5.85.0.tgz", + "integrity": "sha512-7gazTiYqwo5OSqwH1tigLDL2r3qDeP2dOKYgd+LlXpsUMqDTklg6tOghexqky0/+6QY38kb/R/uRPUleuL43zg==", + "dev": true, + "requires": { + "@types/eslint-scope": "^3.7.3", + "@types/estree": "^1.0.0", + "@webassemblyjs/ast": "^1.11.5", + "@webassemblyjs/wasm-edit": "^1.11.5", + "@webassemblyjs/wasm-parser": "^1.11.5", + "acorn": "^8.7.1", + "acorn-import-assertions": "^1.9.0", + "browserslist": "^4.14.5", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^5.14.1", + "es-module-lexer": "^1.2.1", + "eslint-scope": "5.1.1", + "events": "^3.2.0", + "glob-to-regexp": "^0.4.1", + "graceful-fs": "^4.2.9", + "json-parse-even-better-errors": "^2.3.1", + "loader-runner": "^4.2.0", + "mime-types": "^2.1.27", + "neo-async": "^2.6.2", + "schema-utils": "^3.1.2", + "tapable": "^2.1.1", + "terser-webpack-plugin": "^5.3.7", + "watchpack": "^2.4.0", + "webpack-sources": "^3.2.3" + }, + "dependencies": { + "enhanced-resolve": { + "version": "5.14.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.14.1.tgz", + "integrity": "sha512-Vklwq2vDKtl0y/vtwjSesgJ5MYS7Etuk5txS8VdKL4AOS1aUlD96zqIfsOSLQsdv3xgMRbtkWM8eG9XDfKUPow==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + } + } + } + }, + "webpack-bundle-analyzer": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-4.5.0.tgz", + "integrity": "sha512-GUMZlM3SKwS8Z+CKeIFx7CVoHn3dXFcUAjT/dcZQQmfSZGvitPfMob2ipjai7ovFFqPvTqkEZ/leL4O0YOdAYQ==", + "dev": true, + "requires": { + "acorn": "^8.0.4", + "acorn-walk": "^8.0.0", + "chalk": "^4.1.0", + "commander": "^7.2.0", + "gzip-size": "^6.0.0", + "lodash": "^4.17.20", + "opener": "^1.5.2", + "sirv": "^1.0.7", + "ws": "^7.3.1" + }, + "dependencies": { + "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 + }, + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + } + } + }, + "webpack-cli": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.9.2.tgz", + "integrity": "sha512-m3/AACnBBzK/kMTcxWHcZFPrw/eQuY4Df1TxvIWfWM2x7mRqBQCqKEd96oCUa9jkapLBaFfRce33eGDb4Pr7YQ==", + "dev": true, + "requires": { + "@discoveryjs/json-ext": "^0.5.0", + "@webpack-cli/configtest": "^1.1.1", + "@webpack-cli/info": "^1.4.1", + "@webpack-cli/serve": "^1.6.1", + "colorette": "^2.0.14", + "commander": "^7.0.0", + "execa": "^5.0.0", + "fastest-levenshtein": "^1.0.12", + "import-local": "^3.0.2", + "interpret": "^2.2.0", + "rechoir": "^0.7.0", + "webpack-merge": "^5.7.3" + }, + "dependencies": { + "commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true + }, + "interpret": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", + "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==", + "dev": true + } + } + }, + "webpack-dev-middleware": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-5.3.1.tgz", + "integrity": "sha512-81EujCKkyles2wphtdrnPg/QqegC/AtqNH//mQkBYSMqwFVCQrxM6ktB2O/SPlZy7LqeEfTbV3cZARGQz6umhg==", + "dev": true, + "requires": { + "colorette": "^2.0.10", + "memfs": "^3.4.1", + "mime-types": "^2.1.31", + "range-parser": "^1.2.1", + "schema-utils": "^4.0.0" + }, + "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" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "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 + }, + "schema-utils": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" + } + } + } + }, + "webpack-dev-server": { + "version": "4.8.1", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-4.8.1.tgz", + "integrity": "sha512-dwld70gkgNJa33czmcj/PlKY/nOy/BimbrgZRaR9vDATBQAYgLzggR0nxDtPLJiLrMgZwbE6RRfJ5vnBBasTyg==", + "dev": true, + "requires": { + "@types/bonjour": "^3.5.9", + "@types/connect-history-api-fallback": "^1.3.5", + "@types/express": "^4.17.13", + "@types/serve-index": "^1.9.1", + "@types/sockjs": "^0.3.33", + "@types/ws": "^8.5.1", + "ansi-html-community": "^0.0.8", + "bonjour-service": "^1.0.11", + "chokidar": "^3.5.3", + "colorette": "^2.0.10", + "compression": "^1.7.4", + "connect-history-api-fallback": "^1.6.0", + "default-gateway": "^6.0.3", + "express": "^4.17.3", + "graceful-fs": "^4.2.6", + "html-entities": "^2.3.2", + "http-proxy-middleware": "^2.0.3", + "ipaddr.js": "^2.0.1", + "open": "^8.0.9", + "p-retry": "^4.5.0", + "portfinder": "^1.0.28", + "rimraf": "^3.0.2", + "schema-utils": "^4.0.0", + "selfsigned": "^2.0.1", + "serve-index": "^1.9.1", + "sockjs": "^0.3.21", + "spdy": "^4.0.2", + "webpack-dev-middleware": "^5.3.1", + "ws": "^8.4.2" + }, + "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" + } + }, + "ajv-keywords": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", + "integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.3" + } + }, + "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 + }, + "schema-utils": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.0.0.tgz", + "integrity": "sha512-1edyXKgh6XnJsJSQ8mKWXnN/BVaIbFMLpouRUrXgVq7WYne5kw3MW7UPhO44uRXQSIpTSXoJbmrR2X0w9kUTyg==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.9", + "ajv": "^8.8.0", + "ajv-formats": "^2.1.1", + "ajv-keywords": "^5.0.0" + } + }, + "ws": { + "version": "8.5.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", + "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", + "dev": true, + "requires": {} + } + } + }, + "webpack-merge": { + "version": "5.8.0", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", + "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "wildcard": "^2.0.0" + } + }, + "webpack-sources": { + "version": "3.2.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", + "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", + "dev": true + }, + "websocket-driver": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", + "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", + "dev": true, + "requires": { + "http-parser-js": ">=0.5.1", + "safe-buffer": ">=5.1.0", + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true + }, + "whatwg-encoding": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", + "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", + "dev": true, + "requires": { + "iconv-lite": "0.4.24" + }, + "dependencies": { + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + } + } + }, + "whatwg-mimetype": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", + "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", + "dev": true + }, + "whatwg-url": { + "version": "8.7.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", + "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", + "dev": true, + "requires": { + "lodash": "^4.7.0", + "tr46": "^2.1.0", + "webidl-conversions": "^6.1.0" + } + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "requires": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + } + }, + "wide-align": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", + "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2 || 3 || 4" + } + }, + "wildcard": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", + "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", + "dev": true + }, + "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==", + "dev": true + }, + "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, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + }, + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } }, "ws": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.5.0.tgz", - "integrity": "sha512-BWX0SWVgLPzYwF8lTzEy1egjhS4S4OEAHfsO8o65WOVsrnSRGaSiUaa9e0ggGlkMTtBlmOpEXiie9RUcBO86qg==", - "dev": true, - "requires": {} + "version": "7.5.7", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", + "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", + "dev": true, + "requires": {} + }, + "x-is-string": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", + "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=", + "dev": true + }, + "xml-name-validator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", + "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", + "dev": true + }, + "xmlbuilder": { + "version": "15.1.1", + "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", + "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", + "dev": true + }, + "xmlchars": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", + "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", + "dev": true + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yaku": { + "version": "0.16.7", + "resolved": "https://registry.npmjs.org/yaku/-/yaku-0.16.7.tgz", + "integrity": "sha1-HRlceKqbW/hHnIlblQT9TwhHmE4=", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, + "yaml": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", + "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + } + }, + "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 + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + }, + "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==", + "dev": true + }, + "zod": { + "version": "3.21.4", + "resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz", + "integrity": "sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==" + }, + "zustand": { + "version": "4.3.8", + "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.3.8.tgz", + "integrity": "sha512-4h28KCkHg5ii/wcFFJ5Fp+k1J3gJoasaIbppdgZFO4BPJnsNxL0mQXBSFgOgAdCdBj35aDTPvdAJReTMntFPGg==", + "requires": { + "use-sync-external-store": "1.2.0" + } } - } - }, - "webpack-merge": { - "version": "5.8.0", - "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.8.0.tgz", - "integrity": "sha512-/SaI7xY0831XwP6kzuwhKWVKDP9t1QY1h65lAFLbZqMPIuYcD9QAW4u9STIbU9kaJbPBB/geU/gLr1wDjOhQ+Q==", - "dev": true, - "requires": { - "clone-deep": "^4.0.1", - "wildcard": "^2.0.0" - } - }, - "webpack-sources": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.2.3.tgz", - "integrity": "sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==", - "dev": true - }, - "websocket-driver": { - "version": "0.7.4", - "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.7.4.tgz", - "integrity": "sha512-b17KeDIQVjvb0ssuSDF2cYXSg2iztliJ4B9WdsuB6J952qCPKmnVq4DyW5motImXHDC1cBT/1UezrJVsKw5zjg==", - "dev": true, - "requires": { - "http-parser-js": ">=0.5.1", - "safe-buffer": ">=5.1.0", - "websocket-extensions": ">=0.1.1" - } - }, - "websocket-extensions": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", - "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", - "dev": true - }, - "whatwg-encoding": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-1.0.5.tgz", - "integrity": "sha512-b5lim54JOPN9HtzvK9HFXvBma/rnfFeqsic0hSpjtDbVxR3dJKLc+KB4V6GgiGOvl7CY/KNh8rxSo9DKQrnUEw==", - "dev": true, - "requires": { - "iconv-lite": "0.4.24" - }, - "dependencies": { - "iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", - "dev": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - } - } - }, - "whatwg-mimetype": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-2.3.0.tgz", - "integrity": "sha512-M4yMwr6mAnQz76TbJm914+gPpB/nCwvZbJU28cUD6dR004SAxDLOOSUaB1JDRqLtaOV/vi0IC5lEAGFgrjGv/g==", - "dev": true - }, - "whatwg-url": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-8.7.0.tgz", - "integrity": "sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==", - "dev": true, - "requires": { - "lodash": "^4.7.0", - "tr46": "^2.1.0", - "webidl-conversions": "^6.1.0" - } - }, - "which": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", - "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-boxed-primitive": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", - "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", - "dev": true, - "requires": { - "is-bigint": "^1.0.1", - "is-boolean-object": "^1.1.0", - "is-number-object": "^1.0.4", - "is-string": "^1.0.5", - "is-symbol": "^1.0.3" - } - }, - "wide-align": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.5.tgz", - "integrity": "sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2 || 3 || 4" - } - }, - "wildcard": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/wildcard/-/wildcard-2.0.0.tgz", - "integrity": "sha512-JcKqAHLPxcdb9KM49dufGXn2x3ssnfjbcaQdLlfZsL9rH9wgDQjUtDxbo8NE0F6SFvydeu1VhZe7hZuHsB2/pw==", - "dev": true - }, - "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==", - "dev": true - }, - "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, - "requires": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "write": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", - "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", - "dev": true, - "requires": { - "mkdirp": "^0.5.1" - } - }, - "write-file-atomic": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", - "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4", - "is-typedarray": "^1.0.0", - "signal-exit": "^3.0.2", - "typedarray-to-buffer": "^3.1.5" - } - }, - "ws": { - "version": "7.5.7", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.7.tgz", - "integrity": "sha512-KMvVuFzpKBuiIXW3E4u3mySRO2/mCHSyZDJQM5NQ9Q9KHWHWh0NHgfbRMLLrceUK5qAL4ytALJbpRMjixFZh8A==", - "dev": true, - "requires": {} - }, - "x-is-string": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", - "integrity": "sha1-R0tQhlrzpJqcRlfwWs0UVFj3fYI=", - "dev": true - }, - "xml-name-validator": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/xml-name-validator/-/xml-name-validator-3.0.0.tgz", - "integrity": "sha512-A5CUptxDsvxKJEU3yO6DuWBSJz/qizqzJKOMIfUJHETbBw/sFaDxgd6fxm1ewUaM0jZ444Fc5vC5ROYurg/4Pw==", - "dev": true - }, - "xmlbuilder": { - "version": "15.1.1", - "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-15.1.1.tgz", - "integrity": "sha512-yMqGBqtXyeN1e3TGYvgNgDVZ3j84W4cwkOXQswghol6APgZWaff9lnbvN7MHYJOiXsvGPXtjTYJEiC9J2wv9Eg==", - "dev": true - }, - "xmlchars": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/xmlchars/-/xmlchars-2.2.0.tgz", - "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "5.0.8", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", - "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", - "dev": true - }, - "yaku": { - "version": "0.16.7", - "resolved": "https://registry.npmjs.org/yaku/-/yaku-0.16.7.tgz", - "integrity": "sha1-HRlceKqbW/hHnIlblQT9TwhHmE4=", - "dev": true - }, - "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, - "yaml": { - "version": "1.10.2", - "resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz", - "integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==" - }, - "yargs": { - "version": "16.2.0", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", - "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", - "dev": true, - "requires": { - "cliui": "^7.0.2", - "escalade": "^3.1.1", - "get-caller-file": "^2.0.5", - "require-directory": "^2.1.1", - "string-width": "^4.2.0", - "y18n": "^5.0.5", - "yargs-parser": "^20.2.2" - } - }, - "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 - }, - "yauzl": { - "version": "2.10.0", - "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", - "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==", - "dev": true, - "requires": { - "buffer-crc32": "~0.2.3", - "fd-slicer": "~1.1.0" - } - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true - }, - "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==", - "dev": true - }, - "zod": { - "version": "3.21.4", - "resolved": "https://registry.npmjs.org/zod/-/zod-3.21.4.tgz", - "integrity": "sha512-m46AKbrzKVzOzs/DZgVnG5H55N1sv1M8qZU3A8RIKbs3mrACDNeIOeilDymVb2HdmP8uwshOCF4uJ8uM9rCqJw==" - }, - "zustand": { - "version": "4.3.8", - "resolved": "https://registry.npmjs.org/zustand/-/zustand-4.3.8.tgz", - "integrity": "sha512-4h28KCkHg5ii/wcFFJ5Fp+k1J3gJoasaIbppdgZFO4BPJnsNxL0mQXBSFgOgAdCdBj35aDTPvdAJReTMntFPGg==", - "requires": { - "use-sync-external-store": "1.2.0" - } } - } } diff --git a/package.json b/package.json index 3dea6bf8..4f7c6ffa 100644 --- a/package.json +++ b/package.json @@ -1,321 +1,321 @@ { - "name": "feishin", - "productName": "Feishin", - "description": "Feishin music server", - "version": "0.2.0", - "scripts": { - "build": "concurrently \"npm run build:main\" \"npm run build:renderer\"", - "build:main": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.main.prod.ts", - "build:renderer": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.prod.ts", - "rebuild": "electron-rebuild --parallel --types prod,dev,optional --module-dir release/app", - "lint": "cross-env NODE_ENV=development eslint . --ext .js,.jsx,.ts,.tsx", - "lint:fix": "cross-env NODE_ENV=development eslint . --ext .js,.jsx,.ts,.tsx --fix", - "lint:styles": "npx stylelint **/*.tsx", - "package": "ts-node ./.erb/scripts/clean.js dist && npm run build && electron-builder build --publish never", - "package:pr": "ts-node ./.erb/scripts/clean.js dist && npm run build && electron-builder build --publish never --win --mac --linux", - "package:dev": "ts-node ./.erb/scripts/clean.js dist && npm run build && electron-builder build --publish never --dir", - "postinstall": "ts-node .erb/scripts/check-native-dep.js && electron-builder install-app-deps && cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.dev.dll.ts", - "start": "ts-node ./.erb/scripts/check-port-in-use.js && npm run start:renderer", - "start:main": "cross-env NODE_ENV=development electron -r ts-node/register/transpile-only ./src/main/main.ts", - "start:preload": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.preload.dev.ts", - "start:renderer": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack serve --config ./.erb/configs/webpack.config.renderer.dev.ts", - "start:web": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack serve --config ./.erb/configs/webpack.config.renderer.web.ts", - "test": "jest", - "prepare": "husky install", - "i18next": "i18next -c src/renderer/i18n/i18next-parser.config.js", - "prod:buildserver": "pwsh -c \"./scripts/server-build.ps1\"", - "prod:publishserver": "pwsh -c \"./scripts/server-publish.ps1\"" - }, - "lint-staged": { - "*.{js,jsx,ts,tsx}": [ - "cross-env NODE_ENV=development eslint --cache" - ], - "*.json,.{eslintrc,prettierrc}": [ - "prettier --ignore-path .eslintignore --parser json --write" - ], - "*.{css,scss}": [ - "prettier --ignore-path .eslintignore --single-quote --write" - ], - "*.{html,md,yml}": [ - "prettier --ignore-path .eslintignore --single-quote --write" - ] - }, - "build": { + "name": "feishin", "productName": "Feishin", - "appId": "org.jeffvli.feishin", - "artifactName": "${productName}-${version}-${os}-${arch}.${ext}", - "asar": true, - "asarUnpack": "**\\*.{node,dll}", - "files": [ - "dist", - "node_modules", - "package.json" - ], - "afterSign": ".erb/scripts/notarize.js", - "electronVersion": "22.3.1", - "mac": { - "target": { - "target": "default", - "arch": [ - "arm64", - "x64" + "description": "Feishin music server", + "version": "0.2.0", + "scripts": { + "build": "concurrently \"npm run build:main\" \"npm run build:renderer\"", + "build:main": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.main.prod.ts", + "build:renderer": "cross-env NODE_ENV=production TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.prod.ts", + "rebuild": "electron-rebuild --parallel --types prod,dev,optional --module-dir release/app", + "lint": "cross-env NODE_ENV=development eslint . --ext .js,.jsx,.ts,.tsx", + "lint:fix": "cross-env NODE_ENV=development eslint . --ext .js,.jsx,.ts,.tsx --fix", + "lint:styles": "npx stylelint **/*.tsx", + "package": "ts-node ./.erb/scripts/clean.js dist && npm run build && electron-builder build --publish never", + "package:pr": "ts-node ./.erb/scripts/clean.js dist && npm run build && electron-builder build --publish never --win --mac --linux", + "package:dev": "ts-node ./.erb/scripts/clean.js dist && npm run build && electron-builder build --publish never --dir", + "postinstall": "ts-node .erb/scripts/check-native-dep.js && electron-builder install-app-deps && cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.renderer.dev.dll.ts", + "start": "ts-node ./.erb/scripts/check-port-in-use.js && npm run start:renderer", + "start:main": "cross-env NODE_ENV=development electron -r ts-node/register/transpile-only ./src/main/main.ts", + "start:preload": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack --config ./.erb/configs/webpack.config.preload.dev.ts", + "start:renderer": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack serve --config ./.erb/configs/webpack.config.renderer.dev.ts", + "start:web": "cross-env NODE_ENV=development TS_NODE_TRANSPILE_ONLY=true webpack serve --config ./.erb/configs/webpack.config.renderer.web.ts", + "test": "jest", + "prepare": "husky install", + "i18next": "i18next -c src/renderer/i18n/i18next-parser.config.js", + "prod:buildserver": "pwsh -c \"./scripts/server-build.ps1\"", + "prod:publishserver": "pwsh -c \"./scripts/server-publish.ps1\"" + }, + "lint-staged": { + "*.{js,jsx,ts,tsx}": [ + "cross-env NODE_ENV=development eslint --cache" + ], + "*.json,.{eslintrc,prettierrc}": [ + "prettier --ignore-path .eslintignore --parser json --write" + ], + "*.{css,scss}": [ + "prettier --ignore-path .eslintignore --single-quote --write" + ], + "*.{html,md,yml}": [ + "prettier --ignore-path .eslintignore --single-quote --write" ] - }, - "type": "distribution", - "hardenedRuntime": true, - "entitlements": "assets/entitlements.mac.plist", - "entitlementsInherit": "assets/entitlements.mac.plist", - "gatekeeperAssess": false }, - "dmg": { - "contents": [ - { - "x": 130, - "y": 220 + "build": { + "productName": "Feishin", + "appId": "org.jeffvli.feishin", + "artifactName": "${productName}-${version}-${os}-${arch}.${ext}", + "asar": true, + "asarUnpack": "**\\*.{node,dll}", + "files": [ + "dist", + "node_modules", + "package.json" + ], + "afterSign": ".erb/scripts/notarize.js", + "electronVersion": "22.3.1", + "mac": { + "target": { + "target": "default", + "arch": [ + "arm64", + "x64" + ] + }, + "type": "distribution", + "hardenedRuntime": true, + "entitlements": "assets/entitlements.mac.plist", + "entitlementsInherit": "assets/entitlements.mac.plist", + "gatekeeperAssess": false }, - { - "x": 410, - "y": 220, - "type": "link", - "path": "/Applications" + "dmg": { + "contents": [ + { + "x": 130, + "y": 220 + }, + { + "x": 410, + "y": 220, + "type": "link", + "path": "/Applications" + } + ] + }, + "win": { + "target": [ + "nsis", + "zip" + ] + }, + "linux": { + "target": [ + "AppImage", + "tar.xz" + ], + "icon": "assets/icons/placeholder.png", + "category": "Development" + }, + "directories": { + "app": "release/app", + "buildResources": "assets", + "output": "release/build" + }, + "extraResources": [ + "./assets/**" + ], + "publish": { + "provider": "github", + "owner": "jeffvli", + "repo": "feishin" } - ] }, - "win": { - "target": [ - "nsis", - "zip" - ] + "repository": { + "type": "git", + "url": "git+https://github.com/jeffvli/feishin.git" }, - "linux": { - "target": [ - "AppImage", - "tar.xz" - ], - "icon": "assets/icons/placeholder.png", - "category": "Development" + "author": { + "name": "jeffvli", + "url": "https://github.com/jeffvli/" }, - "directories": { - "app": "release/app", - "buildResources": "assets", - "output": "release/build" + "contributors": [], + "license": "GPL-3.0", + "bugs": { + "url": "https://github.com/jeffvli/feishin/issues" }, - "extraResources": [ - "./assets/**" + "keywords": [ + "subsonic", + "navidrome", + "airsonic", + "jellyfin", + "react", + "electron" ], - "publish": { - "provider": "github", - "owner": "jeffvli", - "repo": "feishin" + "homepage": "https://github.com/jeffvli/feishin", + "jest": { + "testURL": "http://localhost/", + "testEnvironment": "jsdom", + "transform": { + "\\.(ts|tsx|js|jsx)$": "ts-jest" + }, + "moduleNameMapper": { + "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "/.erb/mocks/fileMock.js", + "\\.(css|less|sass|scss)$": "identity-obj-proxy" + }, + "moduleFileExtensions": [ + "js", + "jsx", + "ts", + "tsx", + "json" + ], + "moduleDirectories": [ + "node_modules", + "release/app/node_modules" + ], + "testPathIgnorePatterns": [ + "release/app/dist" + ], + "setupFiles": [ + "./.erb/scripts/check-build-exists.ts" + ] + }, + "devDependencies": { + "@electron/rebuild": "^3.2.10", + "@pmmmwh/react-refresh-webpack-plugin": "0.5.5", + "@stylelint/postcss-css-in-js": "^0.38.0", + "@teamsupercell/typings-for-css-modules-loader": "^2.5.1", + "@testing-library/jest-dom": "^5.16.4", + "@testing-library/react": "^13.0.0", + "@types/electron-localshortcut": "^3.1.0", + "@types/jest": "^27.4.1", + "@types/lodash": "^4.14.188", + "@types/md5": "^2.3.2", + "@types/node": "^17.0.23", + "@types/react": "^18.0.25", + "@types/react-dom": "^18.0.8", + "@types/react-test-renderer": "^17.0.1", + "@types/react-virtualized-auto-sizer": "^1.0.1", + "@types/react-window": "^1.8.5", + "@types/react-window-infinite-loader": "^1.0.6", + "@types/styled-components": "^5.1.26", + "@types/terser-webpack-plugin": "^5.0.4", + "@types/webpack-bundle-analyzer": "^4.4.1", + "@types/webpack-env": "^1.16.3", + "@typescript-eslint/eslint-plugin": "^5.47.0", + "@typescript-eslint/parser": "^5.47.0", + "browserslist-config-erb": "^0.0.3", + "chalk": "^4.1.2", + "concurrently": "^7.1.0", + "core-js": "^3.21.1", + "cross-env": "^7.0.3", + "css-loader": "^6.7.1", + "css-minimizer-webpack-plugin": "^3.4.1", + "detect-port": "^1.3.0", + "electron": "^22.3.1", + "electron-builder": "^24.0.0-alpha.13", + "electron-devtools-installer": "^3.2.0", + "electron-notarize": "^1.2.1", + "electronmon": "^2.0.2", + "eslint": "^8.30.0", + "eslint-config-airbnb-base": "^15.0.0", + "eslint-config-erb": "^4.0.3", + "eslint-import-resolver-typescript": "^2.7.1", + "eslint-import-resolver-webpack": "^0.13.2", + "eslint-plugin-compat": "^4.0.2", + "eslint-plugin-import": "^2.26.0", + "eslint-plugin-jest": "^26.1.3", + "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-promise": "^6.0.0", + "eslint-plugin-react": "^7.29.4", + "eslint-plugin-react-hooks": "^4.4.0", + "eslint-plugin-sort-keys-fix": "^1.1.2", + "eslint-plugin-typescript-sort-keys": "^2.1.0", + "file-loader": "^6.2.0", + "html-webpack-plugin": "^5.5.0", + "husky": "^7.0.4", + "i18next-parser": "^6.3.0", + "identity-obj-proxy": "^3.0.0", + "jest": "^27.5.1", + "lint-staged": "^12.3.7", + "mini-css-extract-plugin": "^2.6.0", + "postcss-scss": "^4.0.4", + "postcss-syntax": "^0.36.2", + "prettier": "^2.6.2", + "react-refresh": "^0.12.0", + "react-refresh-typescript": "^2.0.4", + "react-test-renderer": "^18.0.0", + "rimraf": "^3.0.2", + "sass": "^1.49.11", + "sass-loader": "^12.6.0", + "style-loader": "^3.3.1", + "stylelint": "^14.9.1", + "stylelint-config-rational-order": "^0.1.2", + "stylelint-config-standard-scss": "^4.0.0", + "stylelint-config-styled-components": "^0.1.1", + "stylelint-order": "^5.0.0", + "stylelint-processor-styled-components": "^1.10.0", + "terser-webpack-plugin": "^5.3.1", + "ts-jest": "^27.1.4", + "ts-loader": "^9.2.8", + "ts-node": "^10.7.0", + "tsconfig-paths-webpack-plugin": "^4.0.0", + "typescript": "^4.8.4", + "typescript-plugin-styled-components": "^2.0.0", + "url-loader": "^4.1.1", + "webpack": "^5.71.0", + "webpack-bundle-analyzer": "^4.5.0", + "webpack-cli": "^4.9.2", + "webpack-dev-server": "^4.8.0", + "webpack-merge": "^5.8.0" + }, + "dependencies": { + "@ag-grid-community/client-side-row-model": "^28.2.1", + "@ag-grid-community/core": "^28.2.1", + "@ag-grid-community/infinite-row-model": "^28.2.1", + "@ag-grid-community/react": "^28.2.1", + "@ag-grid-community/styles": "^28.2.1", + "@emotion/react": "^11.10.4", + "@mantine/core": "^6.0.13", + "@mantine/dates": "^6.0.13", + "@mantine/form": "^6.0.13", + "@mantine/hooks": "^6.0.13", + "@mantine/modals": "^6.0.13", + "@mantine/notifications": "^6.0.13", + "@mantine/utils": "^6.0.13", + "@tanstack/react-query": "^4.29.5", + "@tanstack/react-query-devtools": "^4.29.6", + "@ts-rest/core": "^3.23.0", + "axios": "^1.4.0", + "cmdk": "^0.2.0", + "dayjs": "^1.11.6", + "electron-debug": "^3.2.0", + "electron-localshortcut": "^3.2.1", + "electron-log": "^4.4.6", + "electron-store": "^8.1.0", + "electron-updater": "^4.6.5", + "fast-average-color": "^9.3.0", + "format-duration": "^2.0.0", + "framer-motion": "^9.1.7", + "fuse.js": "^6.6.2", + "history": "^5.3.0", + "i18next": "^21.6.16", + "immer": "^9.0.21", + "is-electron": "^2.2.2", + "lodash": "^4.17.21", + "md5": "^2.3.0", + "memoize-one": "^6.0.0", + "nanoid": "^3.3.3", + "net": "^1.0.2", + "node-mpv": "github:jeffvli/Node-MPV", + "react": "^18.2.0", + "react-dom": "^18.2.0", + "react-error-boundary": "^3.1.4", + "react-i18next": "^11.16.7", + "react-icons": "^4.8.0", + "react-player": "^2.11.0", + "react-router": "^6.5.0", + "react-router-dom": "^6.5.0", + "react-simple-img": "^3.0.0", + "react-virtualized-auto-sizer": "^1.0.17", + "react-window": "^1.8.9", + "react-window-infinite-loader": "^1.0.9", + "styled-components": "^5.3.11", + "swiper": "^9.3.1", + "zod": "^3.21.4", + "zustand": "^4.3.8" + }, + "resolutions": { + "styled-components": "^5" + }, + "devEngines": { + "node": ">=14.x", + "npm": ">=7.x" + }, + "browserslist": [], + "electronmon": { + "patterns": [ + "!server", + "!src/renderer" + ] } - }, - "repository": { - "type": "git", - "url": "git+https://github.com/jeffvli/feishin.git" - }, - "author": { - "name": "jeffvli", - "url": "https://github.com/jeffvli/" - }, - "contributors": [], - "license": "GPL-3.0", - "bugs": { - "url": "https://github.com/jeffvli/feishin/issues" - }, - "keywords": [ - "subsonic", - "navidrome", - "airsonic", - "jellyfin", - "react", - "electron" - ], - "homepage": "https://github.com/jeffvli/feishin", - "jest": { - "testURL": "http://localhost/", - "testEnvironment": "jsdom", - "transform": { - "\\.(ts|tsx|js|jsx)$": "ts-jest" - }, - "moduleNameMapper": { - "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "/.erb/mocks/fileMock.js", - "\\.(css|less|sass|scss)$": "identity-obj-proxy" - }, - "moduleFileExtensions": [ - "js", - "jsx", - "ts", - "tsx", - "json" - ], - "moduleDirectories": [ - "node_modules", - "release/app/node_modules" - ], - "testPathIgnorePatterns": [ - "release/app/dist" - ], - "setupFiles": [ - "./.erb/scripts/check-build-exists.ts" - ] - }, - "devDependencies": { - "@electron/rebuild": "^3.2.10", - "@pmmmwh/react-refresh-webpack-plugin": "0.5.5", - "@stylelint/postcss-css-in-js": "^0.38.0", - "@teamsupercell/typings-for-css-modules-loader": "^2.5.1", - "@testing-library/jest-dom": "^5.16.4", - "@testing-library/react": "^13.0.0", - "@types/electron-localshortcut": "^3.1.0", - "@types/jest": "^27.4.1", - "@types/lodash": "^4.14.188", - "@types/md5": "^2.3.2", - "@types/node": "^17.0.23", - "@types/react": "^18.0.25", - "@types/react-dom": "^18.0.8", - "@types/react-test-renderer": "^17.0.1", - "@types/react-virtualized-auto-sizer": "^1.0.1", - "@types/react-window": "^1.8.5", - "@types/react-window-infinite-loader": "^1.0.6", - "@types/styled-components": "^5.1.26", - "@types/terser-webpack-plugin": "^5.0.4", - "@types/webpack-bundle-analyzer": "^4.4.1", - "@types/webpack-env": "^1.16.3", - "@typescript-eslint/eslint-plugin": "^5.47.0", - "@typescript-eslint/parser": "^5.47.0", - "browserslist-config-erb": "^0.0.3", - "chalk": "^4.1.2", - "concurrently": "^7.1.0", - "core-js": "^3.21.1", - "cross-env": "^7.0.3", - "css-loader": "^6.7.1", - "css-minimizer-webpack-plugin": "^3.4.1", - "detect-port": "^1.3.0", - "electron": "^22.3.1", - "electron-builder": "^24.0.0-alpha.13", - "electron-devtools-installer": "^3.2.0", - "electron-notarize": "^1.2.1", - "electronmon": "^2.0.2", - "eslint": "^8.30.0", - "eslint-config-airbnb-base": "^15.0.0", - "eslint-config-erb": "^4.0.3", - "eslint-import-resolver-typescript": "^2.7.1", - "eslint-import-resolver-webpack": "^0.13.2", - "eslint-plugin-compat": "^4.0.2", - "eslint-plugin-import": "^2.26.0", - "eslint-plugin-jest": "^26.1.3", - "eslint-plugin-jsx-a11y": "^6.5.1", - "eslint-plugin-promise": "^6.0.0", - "eslint-plugin-react": "^7.29.4", - "eslint-plugin-react-hooks": "^4.4.0", - "eslint-plugin-sort-keys-fix": "^1.1.2", - "eslint-plugin-typescript-sort-keys": "^2.1.0", - "file-loader": "^6.2.0", - "html-webpack-plugin": "^5.5.0", - "husky": "^7.0.4", - "i18next-parser": "^6.3.0", - "identity-obj-proxy": "^3.0.0", - "jest": "^27.5.1", - "lint-staged": "^12.3.7", - "mini-css-extract-plugin": "^2.6.0", - "postcss-scss": "^4.0.4", - "postcss-syntax": "^0.36.2", - "prettier": "^2.6.2", - "react-refresh": "^0.12.0", - "react-refresh-typescript": "^2.0.4", - "react-test-renderer": "^18.0.0", - "rimraf": "^3.0.2", - "sass": "^1.49.11", - "sass-loader": "^12.6.0", - "style-loader": "^3.3.1", - "stylelint": "^14.9.1", - "stylelint-config-rational-order": "^0.1.2", - "stylelint-config-standard-scss": "^4.0.0", - "stylelint-config-styled-components": "^0.1.1", - "stylelint-order": "^5.0.0", - "stylelint-processor-styled-components": "^1.10.0", - "terser-webpack-plugin": "^5.3.1", - "ts-jest": "^27.1.4", - "ts-loader": "^9.2.8", - "ts-node": "^10.7.0", - "tsconfig-paths-webpack-plugin": "^4.0.0", - "typescript": "^4.8.4", - "typescript-plugin-styled-components": "^2.0.0", - "url-loader": "^4.1.1", - "webpack": "^5.71.0", - "webpack-bundle-analyzer": "^4.5.0", - "webpack-cli": "^4.9.2", - "webpack-dev-server": "^4.8.0", - "webpack-merge": "^5.8.0" - }, - "dependencies": { - "@ag-grid-community/client-side-row-model": "^28.2.1", - "@ag-grid-community/core": "^28.2.1", - "@ag-grid-community/infinite-row-model": "^28.2.1", - "@ag-grid-community/react": "^28.2.1", - "@ag-grid-community/styles": "^28.2.1", - "@emotion/react": "^11.10.4", - "@mantine/core": "^6.0.13", - "@mantine/dates": "^6.0.13", - "@mantine/form": "^6.0.13", - "@mantine/hooks": "^6.0.13", - "@mantine/modals": "^6.0.13", - "@mantine/notifications": "^6.0.13", - "@mantine/utils": "^6.0.13", - "@tanstack/react-query": "^4.29.5", - "@tanstack/react-query-devtools": "^4.29.6", - "@ts-rest/core": "^3.23.0", - "axios": "^1.4.0", - "cmdk": "^0.2.0", - "dayjs": "^1.11.6", - "electron-debug": "^3.2.0", - "electron-localshortcut": "^3.2.1", - "electron-log": "^4.4.6", - "electron-store": "^8.1.0", - "electron-updater": "^4.6.5", - "fast-average-color": "^9.3.0", - "format-duration": "^2.0.0", - "framer-motion": "^9.1.7", - "fuse.js": "^6.6.2", - "history": "^5.3.0", - "i18next": "^21.6.16", - "immer": "^9.0.21", - "is-electron": "^2.2.2", - "lodash": "^4.17.21", - "md5": "^2.3.0", - "memoize-one": "^6.0.0", - "nanoid": "^3.3.3", - "net": "^1.0.2", - "node-mpv": "github:jeffvli/Node-MPV", - "react": "^18.2.0", - "react-dom": "^18.2.0", - "react-error-boundary": "^3.1.4", - "react-i18next": "^11.16.7", - "react-icons": "^4.8.0", - "react-player": "^2.11.0", - "react-router": "^6.5.0", - "react-router-dom": "^6.5.0", - "react-simple-img": "^3.0.0", - "react-virtualized-auto-sizer": "^1.0.17", - "react-window": "^1.8.9", - "react-window-infinite-loader": "^1.0.9", - "styled-components": "^5.3.11", - "swiper": "^9.3.1", - "zod": "^3.21.4", - "zustand": "^4.3.8" - }, - "resolutions": { - "styled-components": "^5" - }, - "devEngines": { - "node": ">=14.x", - "npm": ">=7.x" - }, - "browserslist": [], - "electronmon": { - "patterns": [ - "!server", - "!src/renderer" - ] - } } diff --git a/src/__tests__/App.test.tsx b/src/__tests__/App.test.tsx index aa1b21ae..b2f4b7d1 100644 --- a/src/__tests__/App.test.tsx +++ b/src/__tests__/App.test.tsx @@ -3,7 +3,7 @@ import { render } from '@testing-library/react'; import { App } from '../renderer/app'; describe('App', () => { - it('should render', () => { - expect(render()).toBeTruthy(); - }); + it('should render', () => { + expect(render()).toBeTruthy(); + }); }); diff --git a/src/main/features/core/lyrics/genius.ts b/src/main/features/core/lyrics/genius.ts index 7ed0f38e..cf4aef86 100644 --- a/src/main/features/core/lyrics/genius.ts +++ b/src/main/features/core/lyrics/genius.ts @@ -1,10 +1,10 @@ import axios, { AxiosResponse } from 'axios'; import { load } from 'cheerio'; import { - LyricSource, - InternetProviderLyricResponse, - InternetProviderLyricSearchResponse, - LyricSearchQuery, + LyricSource, + InternetProviderLyricResponse, + InternetProviderLyricSearchResponse, + LyricSearchQuery, } from '../../../../renderer/api/types'; import { orderSearchResults } from './shared'; @@ -13,197 +13,197 @@ const SEARCH_URL = 'https://genius.com/api/search/song'; // Adapted from https://github.com/NyaomiDEV/Sunamu/blob/master/src/main/lyricproviders/genius.ts export interface GeniusResponse { - meta: Meta; - response: Response; + meta: Meta; + response: Response; } export interface Meta { - status: number; + status: number; } export interface Response { - next_page: number; - sections: Section[]; + next_page: number; + sections: Section[]; } export interface Section { - hits: Hit[]; - type: string; + hits: Hit[]; + type: string; } export interface Hit { - highlights: any[]; - index: string; - result: Result; - type: string; + highlights: any[]; + index: string; + result: Result; + type: string; } export interface Result { - _type: string; - annotation_count: number; - api_path: string; - artist_names: string; - featured_artists: any[]; - full_title: string; - header_image_thumbnail_url: string; - header_image_url: string; - id: number; - instrumental: boolean; - language: string; - lyrics_owner_id: number; - lyrics_state: string; - lyrics_updated_at: number; - path: string; - primary_artist: PrimaryArtist; - pyongs_count: null; - relationships_index_url: string; - release_date_components: ReleaseDateComponents; - release_date_for_display: string; - release_date_with_abbreviated_month_for_display: string; - song_art_image_thumbnail_url: string; - song_art_image_url: string; - stats: Stats; - title: string; - title_with_featured: string; - updated_by_human_at: number; - url: string; + _type: string; + annotation_count: number; + api_path: string; + artist_names: string; + featured_artists: any[]; + full_title: string; + header_image_thumbnail_url: string; + header_image_url: string; + id: number; + instrumental: boolean; + language: string; + lyrics_owner_id: number; + lyrics_state: string; + lyrics_updated_at: number; + path: string; + primary_artist: PrimaryArtist; + pyongs_count: null; + relationships_index_url: string; + release_date_components: ReleaseDateComponents; + release_date_for_display: string; + release_date_with_abbreviated_month_for_display: string; + song_art_image_thumbnail_url: string; + song_art_image_url: string; + stats: Stats; + title: string; + title_with_featured: string; + updated_by_human_at: number; + url: string; } export interface PrimaryArtist { - _type: string; - api_path: string; - header_image_url: string; - id: number; - image_url: string; - index_character: string; - is_meme_verified: boolean; - is_verified: boolean; - name: string; - slug: string; - url: string; + _type: string; + api_path: string; + header_image_url: string; + id: number; + image_url: string; + index_character: string; + is_meme_verified: boolean; + is_verified: boolean; + name: string; + slug: string; + url: string; } export interface ReleaseDateComponents { - day: number; - month: number; - year: number; + day: number; + month: number; + year: number; } export interface Stats { - hot: boolean; - unreviewed_annotations: number; + hot: boolean; + unreviewed_annotations: number; } export async function getSearchResults( - params: LyricSearchQuery, + params: LyricSearchQuery, ): Promise { - let result: AxiosResponse; + let result: AxiosResponse; - const searchQuery = [params.artist, params.name].join(' '); + const searchQuery = [params.artist, params.name].join(' '); - if (!searchQuery) { - return null; - } + if (!searchQuery) { + return null; + } - try { - result = await axios.get(SEARCH_URL, { - params: { - per_page: '5', - q: searchQuery, - }, + try { + result = await axios.get(SEARCH_URL, { + params: { + per_page: '5', + q: searchQuery, + }, + }); + } catch (e) { + console.error('Genius search request got an error!', e); + return null; + } + + const rawSongsResult = result.data.response?.sections?.[0]?.hits?.map((hit) => hit.result); + + if (!rawSongsResult) return null; + + const songResults: InternetProviderLyricSearchResponse[] = rawSongsResult.map((song) => { + return { + artist: song.artist_names, + id: song.url, + name: song.full_title, + source: LyricSource.GENIUS, + }; }); - } catch (e) { - console.error('Genius search request got an error!', e); - return null; - } - const rawSongsResult = result.data.response?.sections?.[0]?.hits?.map((hit) => hit.result); - - if (!rawSongsResult) return null; - - const songResults: InternetProviderLyricSearchResponse[] = rawSongsResult.map((song) => { - return { - artist: song.artist_names, - id: song.url, - name: song.full_title, - source: LyricSource.GENIUS, - }; - }); - - return orderSearchResults({ params, results: songResults }); + return orderSearchResults({ params, results: songResults }); } async function getSongId( - params: LyricSearchQuery, + params: LyricSearchQuery, ): Promise | null> { - let result: AxiosResponse; - try { - result = await axios.get(SEARCH_URL, { - params: { - per_page: '1', - q: `${params.artist} ${params.name}`, - }, - }); - } catch (e) { - console.error('Genius search request got an error!', e); - return null; - } + let result: AxiosResponse; + try { + result = await axios.get(SEARCH_URL, { + params: { + per_page: '1', + q: `${params.artist} ${params.name}`, + }, + }); + } catch (e) { + console.error('Genius search request got an error!', e); + return null; + } - const hit = result.data.response?.sections?.[0]?.hits?.[0]?.result; + const hit = result.data.response?.sections?.[0]?.hits?.[0]?.result; - if (!hit) { - return null; - } + if (!hit) { + return null; + } - return { - artist: hit.artist_names, - id: hit.url, - name: hit.full_title, - source: LyricSource.GENIUS, - }; + return { + artist: hit.artist_names, + id: hit.url, + name: hit.full_title, + source: LyricSource.GENIUS, + }; } export async function getLyricsBySongId(url: string): Promise { - let result: AxiosResponse; - try { - result = await axios.get(url, { responseType: 'text' }); - } catch (e) { - console.error('Genius lyrics request got an error!', e); - return null; - } + let result: AxiosResponse; + try { + result = await axios.get(url, { responseType: 'text' }); + } catch (e) { + console.error('Genius lyrics request got an error!', e); + return null; + } - const $ = load(result.data.split('
').join('\n')); - const lyricsDiv = $('div.lyrics'); + const $ = load(result.data.split('
').join('\n')); + const lyricsDiv = $('div.lyrics'); - if (lyricsDiv.length > 0) return lyricsDiv.text().trim(); + if (lyricsDiv.length > 0) return lyricsDiv.text().trim(); - const lyricSections = $('div[class^=Lyrics__Container]') - .map((_, e) => $(e).text()) - .toArray() - .join('\n'); - return lyricSections; + const lyricSections = $('div[class^=Lyrics__Container]') + .map((_, e) => $(e).text()) + .toArray() + .join('\n'); + return lyricSections; } export async function query( - params: LyricSearchQuery, + params: LyricSearchQuery, ): Promise { - const response = await getSongId(params); - if (!response) { - console.error('Could not find the song on Genius!'); - return null; - } + const response = await getSongId(params); + if (!response) { + console.error('Could not find the song on Genius!'); + return null; + } - const lyrics = await getLyricsBySongId(response.id); - if (!lyrics) { - console.error('Could not get lyrics on Genius!'); - return null; - } + const lyrics = await getLyricsBySongId(response.id); + if (!lyrics) { + console.error('Could not get lyrics on Genius!'); + return null; + } - return { - artist: response.artist, - id: response.id, - lyrics, - name: response.name, - source: LyricSource.GENIUS, - }; + return { + artist: response.artist, + id: response.id, + lyrics, + name: response.name, + source: LyricSource.GENIUS, + }; } diff --git a/src/main/features/core/lyrics/index.ts b/src/main/features/core/lyrics/index.ts index c1fb710e..49345a1b 100644 --- a/src/main/features/core/lyrics/index.ts +++ b/src/main/features/core/lyrics/index.ts @@ -1,53 +1,53 @@ import { ipcMain } from 'electron'; import { - InternetProviderLyricResponse, - InternetProviderLyricSearchResponse, - LyricSearchQuery, - QueueSong, - LyricGetQuery, - LyricSource, + InternetProviderLyricResponse, + InternetProviderLyricSearchResponse, + LyricSearchQuery, + QueueSong, + LyricGetQuery, + LyricSource, } from '../../../../renderer/api/types'; import { store } from '../settings/index'; import { - query as queryGenius, - getSearchResults as searchGenius, - getLyricsBySongId as getGenius, + query as queryGenius, + getSearchResults as searchGenius, + getLyricsBySongId as getGenius, } from './genius'; import { - query as queryLrclib, - getSearchResults as searchLrcLib, - getLyricsBySongId as getLrcLib, + query as queryLrclib, + getSearchResults as searchLrcLib, + getLyricsBySongId as getLrcLib, } from './lrclib'; import { - query as queryNetease, - getSearchResults as searchNetease, - getLyricsBySongId as getNetease, + query as queryNetease, + getSearchResults as searchNetease, + getLyricsBySongId as getNetease, } from './netease'; type SongFetcher = (params: LyricSearchQuery) => Promise; type SearchFetcher = ( - params: LyricSearchQuery, + params: LyricSearchQuery, ) => Promise; type GetFetcher = (id: string) => Promise; type CachedLyrics = Record; const FETCHERS: Record = { - [LyricSource.GENIUS]: queryGenius, - [LyricSource.LRCLIB]: queryLrclib, - [LyricSource.NETEASE]: queryNetease, + [LyricSource.GENIUS]: queryGenius, + [LyricSource.LRCLIB]: queryLrclib, + [LyricSource.NETEASE]: queryNetease, }; const SEARCH_FETCHERS: Record = { - [LyricSource.GENIUS]: searchGenius, - [LyricSource.LRCLIB]: searchLrcLib, - [LyricSource.NETEASE]: searchNetease, + [LyricSource.GENIUS]: searchGenius, + [LyricSource.LRCLIB]: searchLrcLib, + [LyricSource.NETEASE]: searchNetease, }; const GET_FETCHERS: Record = { - [LyricSource.GENIUS]: getGenius, - [LyricSource.LRCLIB]: getLrcLib, - [LyricSource.NETEASE]: getNetease, + [LyricSource.GENIUS]: getGenius, + [LyricSource.LRCLIB]: getLrcLib, + [LyricSource.NETEASE]: getNetease, }; const MAX_CACHED_ITEMS = 10; @@ -55,95 +55,95 @@ const MAX_CACHED_ITEMS = 10; const lyricCache = new Map(); const getRemoteLyrics = async (song: QueueSong) => { - const sources = store.get('lyrics', []) as LyricSource[]; + const sources = store.get('lyrics', []) as LyricSource[]; - const cached = lyricCache.get(song.id); + const cached = lyricCache.get(song.id); + + if (cached) { + for (const source of sources) { + const data = cached[source]; + if (data) return data; + } + } + + let lyricsFromSource = null; - if (cached) { for (const source of sources) { - const data = cached[source]; - if (data) return data; + const params = { + album: song.album || song.name, + artist: song.artistName, + duration: song.duration, + name: song.name, + }; + const response = await FETCHERS[source](params); + + if (response) { + const newResult = cached + ? { + ...cached, + [source]: response, + } + : ({ [source]: response } as CachedLyrics); + + if (lyricCache.size === MAX_CACHED_ITEMS && cached === undefined) { + const toRemove = lyricCache.keys().next().value; + lyricCache.delete(toRemove); + } + + lyricCache.set(song.id, newResult); + + lyricsFromSource = response; + break; + } } - } - let lyricsFromSource = null; - - for (const source of sources) { - const params = { - album: song.album || song.name, - artist: song.artistName, - duration: song.duration, - name: song.name, - }; - const response = await FETCHERS[source](params); - - if (response) { - const newResult = cached - ? { - ...cached, - [source]: response, - } - : ({ [source]: response } as CachedLyrics); - - if (lyricCache.size === MAX_CACHED_ITEMS && cached === undefined) { - const toRemove = lyricCache.keys().next().value; - lyricCache.delete(toRemove); - } - - lyricCache.set(song.id, newResult); - - lyricsFromSource = response; - break; - } - } - - return lyricsFromSource; + return lyricsFromSource; }; const searchRemoteLyrics = async (params: LyricSearchQuery) => { - const sources = store.get('lyrics', []) as LyricSource[]; + const sources = store.get('lyrics', []) as LyricSource[]; - const results: Record = { - [LyricSource.GENIUS]: [], - [LyricSource.LRCLIB]: [], - [LyricSource.NETEASE]: [], - }; + const results: Record = { + [LyricSource.GENIUS]: [], + [LyricSource.LRCLIB]: [], + [LyricSource.NETEASE]: [], + }; - for (const source of sources) { - const response = await SEARCH_FETCHERS[source](params); + for (const source of sources) { + const response = await SEARCH_FETCHERS[source](params); - if (response) { - response.forEach((result) => { - results[source].push(result); - }); + if (response) { + response.forEach((result) => { + results[source].push(result); + }); + } } - } - return results; + return results; }; const getRemoteLyricsById = async (params: LyricGetQuery): Promise => { - const { remoteSongId, remoteSource } = params; - const response = await GET_FETCHERS[remoteSource](remoteSongId); + const { remoteSongId, remoteSource } = params; + const response = await GET_FETCHERS[remoteSource](remoteSongId); - if (!response) { - return null; - } + if (!response) { + return null; + } - return response; + return response; }; ipcMain.handle('lyric-by-song', async (_event, song: QueueSong) => { - const lyric = await getRemoteLyrics(song); - return lyric; + const lyric = await getRemoteLyrics(song); + return lyric; }); ipcMain.handle('lyric-search', async (_event, params: LyricSearchQuery) => { - const lyricResults = await searchRemoteLyrics(params); - return lyricResults; + const lyricResults = await searchRemoteLyrics(params); + return lyricResults; }); ipcMain.handle('lyric-by-remote-id', async (_event, params: LyricGetQuery) => { - const lyricResults = await getRemoteLyricsById(params); - return lyricResults; + const lyricResults = await getRemoteLyricsById(params); + return lyricResults; }); diff --git a/src/main/features/core/lyrics/lrclib.ts b/src/main/features/core/lyrics/lrclib.ts index 157a3231..26a98b7e 100644 --- a/src/main/features/core/lyrics/lrclib.ts +++ b/src/main/features/core/lyrics/lrclib.ts @@ -1,10 +1,10 @@ // Credits to https://github.com/tranxuanthang/lrcget for API implementation import axios, { AxiosResponse } from 'axios'; import { - InternetProviderLyricResponse, - InternetProviderLyricSearchResponse, - LyricSearchQuery, - LyricSource, + InternetProviderLyricResponse, + InternetProviderLyricSearchResponse, + LyricSearchQuery, + LyricSource, } from '../../../../renderer/api/types'; import { orderSearchResults } from './shared'; @@ -14,106 +14,106 @@ const SEEARCH_URL = 'https://lrclib.net/api/search'; const TIMEOUT_MS = 5000; export interface LrcLibSearchResponse { - albumName: string; - artistName: string; - id: number; - name: string; + albumName: string; + artistName: string; + id: number; + name: string; } export interface LrcLibTrackResponse { - albumName: string; - artistName: string; - duration: number; - id: number; - instrumental: boolean; - isrc: string; - lang: string; - name: string; - plainLyrics: string | null; - releaseDate: string; - spotifyId: string; - syncedLyrics: string | null; + albumName: string; + artistName: string; + duration: number; + id: number; + instrumental: boolean; + isrc: string; + lang: string; + name: string; + plainLyrics: string | null; + releaseDate: string; + spotifyId: string; + syncedLyrics: string | null; } export async function getSearchResults( - params: LyricSearchQuery, + params: LyricSearchQuery, ): Promise { - let result: AxiosResponse; + let result: AxiosResponse; - if (!params.name) { - return null; - } + if (!params.name) { + return null; + } - try { - result = await axios.get(SEEARCH_URL, { - params: { - q: params.name, - }, + try { + result = await axios.get(SEEARCH_URL, { + params: { + q: params.name, + }, + }); + } catch (e) { + console.error('LrcLib search request got an error!', e); + return null; + } + + if (!result.data) return null; + + const songResults: InternetProviderLyricSearchResponse[] = result.data.map((song) => { + return { + artist: song.artistName, + id: String(song.id), + name: song.name, + source: LyricSource.LRCLIB, + }; }); - } catch (e) { - console.error('LrcLib search request got an error!', e); - return null; - } - if (!result.data) return null; - - const songResults: InternetProviderLyricSearchResponse[] = result.data.map((song) => { - return { - artist: song.artistName, - id: String(song.id), - name: song.name, - source: LyricSource.LRCLIB, - }; - }); - - return orderSearchResults({ params, results: songResults }); + return orderSearchResults({ params, results: songResults }); } export async function getLyricsBySongId(songId: string): Promise { - let result: AxiosResponse; + let result: AxiosResponse; - try { - result = await axios.get(`${FETCH_URL}/${songId}`); - } catch (e) { - console.error('LrcLib lyrics request got an error!', e); - return null; - } + try { + result = await axios.get(`${FETCH_URL}/${songId}`); + } catch (e) { + console.error('LrcLib lyrics request got an error!', e); + return null; + } - return result.data.syncedLyrics || result.data.plainLyrics || null; + return result.data.syncedLyrics || result.data.plainLyrics || null; } export async function query( - params: LyricSearchQuery, + params: LyricSearchQuery, ): Promise { - let result: AxiosResponse; + let result: AxiosResponse; - try { - result = await axios.get(FETCH_URL, { - params: { - album_name: params.album, - artist_name: params.artist, - duration: params.duration, - track_name: params.name, - }, - timeout: TIMEOUT_MS, - }); - } catch (e) { - console.error('LrcLib search request got an error!', e); - return null; - } + try { + result = await axios.get(FETCH_URL, { + params: { + album_name: params.album, + artist_name: params.artist, + duration: params.duration, + track_name: params.name, + }, + timeout: TIMEOUT_MS, + }); + } catch (e) { + console.error('LrcLib search request got an error!', e); + return null; + } - const lyrics = result.data.syncedLyrics || result.data.plainLyrics || null; + const lyrics = result.data.syncedLyrics || result.data.plainLyrics || null; - if (!lyrics) { - console.error(`Could not get lyrics on LrcLib!`); - return null; - } + if (!lyrics) { + console.error(`Could not get lyrics on LrcLib!`); + return null; + } - return { - artist: result.data.artistName, - id: String(result.data.id), - lyrics, - name: result.data.name, - source: LyricSource.LRCLIB, - }; + return { + artist: result.data.artistName, + id: String(result.data.id), + lyrics, + name: result.data.name, + source: LyricSource.LRCLIB, + }; } diff --git a/src/main/features/core/lyrics/netease.ts b/src/main/features/core/lyrics/netease.ts index 8ebfde8e..b97ca3f8 100644 --- a/src/main/features/core/lyrics/netease.ts +++ b/src/main/features/core/lyrics/netease.ts @@ -2,9 +2,9 @@ import axios, { AxiosResponse } from 'axios'; import { LyricSource } from '../../../../renderer/api/types'; import { orderSearchResults } from './shared'; import type { - InternetProviderLyricResponse, - InternetProviderLyricSearchResponse, - LyricSearchQuery, + InternetProviderLyricResponse, + InternetProviderLyricSearchResponse, + LyricSearchQuery, } from '/@/renderer/api/types'; const SEARCH_URL = 'https://music.163.com/api/search/get'; @@ -13,155 +13,155 @@ const LYRICS_URL = 'https://music.163.com/api/song/lyric'; // Adapted from https://github.com/NyaomiDEV/Sunamu/blob/master/src/main/lyricproviders/netease.ts export interface NetEaseResponse { - code: number; - result: Result; + code: number; + result: Result; } export interface Result { - hasMore: boolean; - songCount: number; - songs: Song[]; + hasMore: boolean; + songCount: number; + songs: Song[]; } export interface Song { - album: Album; - alias: string[]; - artists: Artist[]; - copyrightId: number; - duration: number; - fee: number; - ftype: number; - id: number; - mark: number; - mvid: number; - name: string; - rUrl: null; - rtype: number; - status: number; - transNames?: string[]; + album: Album; + alias: string[]; + artists: Artist[]; + copyrightId: number; + duration: number; + fee: number; + ftype: number; + id: number; + mark: number; + mvid: number; + name: string; + rUrl: null; + rtype: number; + status: number; + transNames?: string[]; } export interface Album { - artist: Artist; - copyrightId: number; - id: number; - mark: number; - name: string; - picId: number; - publishTime: number; - size: number; - status: number; - transNames?: string[]; + artist: Artist; + copyrightId: number; + id: number; + mark: number; + name: string; + picId: number; + publishTime: number; + size: number; + status: number; + transNames?: string[]; } export interface Artist { - albumSize: number; - alias: any[]; - fansGroup: null; - id: number; - img1v1: number; - img1v1Url: string; - name: string; - picId: number; - picUrl: null; - trans: null; + albumSize: number; + alias: any[]; + fansGroup: null; + id: number; + img1v1: number; + img1v1Url: string; + name: string; + picId: number; + picUrl: null; + trans: null; } export async function getSearchResults( - params: LyricSearchQuery, + params: LyricSearchQuery, ): Promise { - let result: AxiosResponse; + let result: AxiosResponse; - const searchQuery = [params.artist, params.name].join(' '); + const searchQuery = [params.artist, params.name].join(' '); - if (!searchQuery) { - return null; - } + if (!searchQuery) { + return null; + } - try { - result = await axios.get(SEARCH_URL, { - params: { - limit: 5, - offset: 0, - s: searchQuery, - type: '1', - }, + try { + result = await axios.get(SEARCH_URL, { + params: { + limit: 5, + offset: 0, + s: searchQuery, + type: '1', + }, + }); + } catch (e) { + console.error('NetEase search request got an error!', e); + return null; + } + + const rawSongsResult = result?.data.result?.songs; + + if (!rawSongsResult) return null; + + const songResults: InternetProviderLyricSearchResponse[] = rawSongsResult.map((song) => { + const artist = song.artists ? song.artists.map((artist) => artist.name).join(', ') : ''; + + return { + artist, + id: String(song.id), + name: song.name, + source: LyricSource.NETEASE, + }; }); - } catch (e) { - console.error('NetEase search request got an error!', e); - return null; - } - const rawSongsResult = result?.data.result?.songs; - - if (!rawSongsResult) return null; - - const songResults: InternetProviderLyricSearchResponse[] = rawSongsResult.map((song) => { - const artist = song.artists ? song.artists.map((artist) => artist.name).join(', ') : ''; - - return { - artist, - id: String(song.id), - name: song.name, - source: LyricSource.NETEASE, - }; - }); - - return orderSearchResults({ params, results: songResults }); + return orderSearchResults({ params, results: songResults }); } async function getMatchedLyrics( - params: LyricSearchQuery, + params: LyricSearchQuery, ): Promise | null> { - const results = await getSearchResults(params); + const results = await getSearchResults(params); - const firstMatch = results?.[0]; + const firstMatch = results?.[0]; - if (!firstMatch || (firstMatch?.score && firstMatch.score > 0.5)) { - return null; - } + if (!firstMatch || (firstMatch?.score && firstMatch.score > 0.5)) { + return null; + } - return firstMatch; + return firstMatch; } export async function getLyricsBySongId(songId: string): Promise { - let result: AxiosResponse; - try { - result = await axios.get(LYRICS_URL, { - params: { - id: songId, - kv: '-1', - lv: '-1', - }, - }); - } catch (e) { - console.error('NetEase lyrics request got an error!', e); - return null; - } + let result: AxiosResponse; + try { + result = await axios.get(LYRICS_URL, { + params: { + id: songId, + kv: '-1', + lv: '-1', + }, + }); + } catch (e) { + console.error('NetEase lyrics request got an error!', e); + return null; + } - return result.data.klyric?.lyric || result.data.lrc?.lyric; + return result.data.klyric?.lyric || result.data.lrc?.lyric; } export async function query( - params: LyricSearchQuery, + params: LyricSearchQuery, ): Promise { - const lyricsMatch = await getMatchedLyrics(params); - if (!lyricsMatch) { - console.error('Could not find the song on NetEase!'); - return null; - } + const lyricsMatch = await getMatchedLyrics(params); + if (!lyricsMatch) { + console.error('Could not find the song on NetEase!'); + return null; + } - const lyrics = await getLyricsBySongId(lyricsMatch.id); - if (!lyrics) { - console.error('Could not get lyrics on NetEase!'); - return null; - } + const lyrics = await getLyricsBySongId(lyricsMatch.id); + if (!lyrics) { + console.error('Could not get lyrics on NetEase!'); + return null; + } - return { - artist: lyricsMatch.artist, - id: lyricsMatch.id, - lyrics, - name: lyricsMatch.name, - source: LyricSource.NETEASE, - }; + return { + artist: lyricsMatch.artist, + id: lyricsMatch.id, + lyrics, + name: lyricsMatch.name, + source: LyricSource.NETEASE, + }; } diff --git a/src/main/features/core/lyrics/shared.ts b/src/main/features/core/lyrics/shared.ts index 3bf5e4d5..bb926f28 100644 --- a/src/main/features/core/lyrics/shared.ts +++ b/src/main/features/core/lyrics/shared.ts @@ -1,34 +1,34 @@ import Fuse from 'fuse.js'; import { - InternetProviderLyricSearchResponse, - LyricSearchQuery, + InternetProviderLyricSearchResponse, + LyricSearchQuery, } from '../../../../renderer/api/types'; export const orderSearchResults = (args: { - params: LyricSearchQuery; - results: InternetProviderLyricSearchResponse[]; + params: LyricSearchQuery; + results: InternetProviderLyricSearchResponse[]; }) => { - const { params, results } = args; + const { params, results } = args; - const options: Fuse.IFuseOptions = { - fieldNormWeight: 1, - includeScore: true, - keys: [ - { getFn: (song) => song.name, name: 'name', weight: 3 }, - { getFn: (song) => song.artist, name: 'artist' }, - ], - threshold: 1.0, - }; + const options: Fuse.IFuseOptions = { + fieldNormWeight: 1, + includeScore: true, + keys: [ + { getFn: (song) => song.name, name: 'name', weight: 3 }, + { getFn: (song) => song.artist, name: 'artist' }, + ], + threshold: 1.0, + }; - const fuse = new Fuse(results, options); + const fuse = new Fuse(results, options); - const searchResults = fuse.search({ - ...(params.artist && { artist: params.artist }), - ...(params.name && { name: params.name }), - }); + const searchResults = fuse.search({ + ...(params.artist && { artist: params.artist }), + ...(params.name && { name: params.name }), + }); - return searchResults.map((result) => ({ - ...result.item, - score: result.score, - })); + return searchResults.map((result) => ({ + ...result.item, + score: result.score, + })); }; diff --git a/src/main/features/core/player/index.ts b/src/main/features/core/player/index.ts index 5d9018cb..04ca268e 100644 --- a/src/main/features/core/player/index.ts +++ b/src/main/features/core/player/index.ts @@ -6,215 +6,215 @@ import { PlayerData } from '/@/renderer/store'; declare module 'node-mpv'; function wait(timeout: number) { - return new Promise((resolve) => { - setTimeout(() => { - resolve('resolved'); - }, timeout); - }); + return new Promise((resolve) => { + setTimeout(() => { + resolve('resolved'); + }, timeout); + }); } ipcMain.handle('player-is-running', async () => { - return getMpvInstance()?.isRunning(); + return getMpvInstance()?.isRunning(); }); ipcMain.handle('player-clean-up', async () => { - getMpvInstance()?.stop(); - getMpvInstance()?.clearPlaylist(); + getMpvInstance()?.stop(); + getMpvInstance()?.clearPlaylist(); }); ipcMain.on('player-start', async () => { - await getMpvInstance() - ?.play() - .catch((err) => { - console.log('MPV failed to play', err); - }); + await getMpvInstance() + ?.play() + .catch((err) => { + console.log('MPV failed to play', err); + }); }); // Starts the player ipcMain.on('player-play', async () => { - await getMpvInstance() - ?.play() - .catch((err) => { - console.log('MPV failed to play', err); - }); + await getMpvInstance() + ?.play() + .catch((err) => { + console.log('MPV failed to play', err); + }); }); // Pauses the player ipcMain.on('player-pause', async () => { - await getMpvInstance() - ?.pause() - .catch((err) => { - console.log('MPV failed to pause', err); - }); + await getMpvInstance() + ?.pause() + .catch((err) => { + console.log('MPV failed to pause', err); + }); }); // Stops the player ipcMain.on('player-stop', async () => { - await getMpvInstance() - ?.stop() - .catch((err) => { - console.log('MPV failed to stop', err); - }); + await getMpvInstance() + ?.stop() + .catch((err) => { + console.log('MPV failed to stop', err); + }); }); // Goes to the next track in the playlist ipcMain.on('player-next', async () => { - await getMpvInstance() - ?.next() - .catch((err) => { - console.log('MPV failed to go to next', err); - }); + await getMpvInstance() + ?.next() + .catch((err) => { + console.log('MPV failed to go to next', err); + }); }); // Goes to the previous track in the playlist ipcMain.on('player-previous', async () => { - await getMpvInstance() - ?.prev() - .catch((err) => { - console.log('MPV failed to go to previous', err); - }); + await getMpvInstance() + ?.prev() + .catch((err) => { + console.log('MPV failed to go to previous', err); + }); }); // Seeks forward or backward by the given amount of seconds ipcMain.on('player-seek', async (_event, time: number) => { - await getMpvInstance() - ?.seek(time) - .catch((err) => { - console.log('MPV failed to seek', err); - }); + await getMpvInstance() + ?.seek(time) + .catch((err) => { + console.log('MPV failed to seek', err); + }); }); // Seeks to the given time in seconds ipcMain.on('player-seek-to', async (_event, time: number) => { - await getMpvInstance() - ?.goToPosition(time) - .catch((err) => { - console.log(`MPV failed to seek to ${time}`, err); - }); + await getMpvInstance() + ?.goToPosition(time) + .catch((err) => { + console.log(`MPV failed to seek to ${time}`, err); + }); }); // Sets the queue in position 0 and 1 to the given data. Used when manually starting a song or using the next/prev buttons ipcMain.on('player-set-queue', async (_event, data: PlayerData, pause?: boolean) => { - if (!data.queue.current && !data.queue.next) { - await getMpvInstance() - ?.clearPlaylist() - .catch((err) => { - console.log('MPV failed to clear playlist', err); - }); - await getMpvInstance() - ?.pause() - .catch((err) => { - console.log('MPV failed to pause', err); - }); - return; - } - - let complete = false; - let tryAttempts = 0; - - while (!complete) { - if (tryAttempts > 3) { - getMainWindow()?.webContents.send('renderer-player-error', 'Failed to load song'); - complete = true; - } else { - try { - if (data.queue.current) { - await getMpvInstance() - ?.load(data.queue.current.streamUrl, 'replace') + if (!data.queue.current && !data.queue.next) { + await getMpvInstance() + ?.clearPlaylist() .catch((err) => { - console.log('MPV failed to load song', err); + console.log('MPV failed to clear playlist', err); }); - } - - if (data.queue.next) { - await getMpvInstance() - ?.load(data.queue.next.streamUrl, 'append') + await getMpvInstance() + ?.pause() .catch((err) => { - console.log('MPV failed to load next song', err); + console.log('MPV failed to pause', err); }); - } - - complete = true; - } catch (err) { - console.error(err); - tryAttempts += 1; - await wait(500); - } + return; } - } - if (pause) { - await getMpvInstance()?.pause(); - } + let complete = false; + let tryAttempts = 0; + + while (!complete) { + if (tryAttempts > 3) { + getMainWindow()?.webContents.send('renderer-player-error', 'Failed to load song'); + complete = true; + } else { + try { + if (data.queue.current) { + await getMpvInstance() + ?.load(data.queue.current.streamUrl, 'replace') + .catch((err) => { + console.log('MPV failed to load song', err); + }); + } + + if (data.queue.next) { + await getMpvInstance() + ?.load(data.queue.next.streamUrl, 'append') + .catch((err) => { + console.log('MPV failed to load next song', err); + }); + } + + complete = true; + } catch (err) { + console.error(err); + tryAttempts += 1; + await wait(500); + } + } + } + + if (pause) { + await getMpvInstance()?.pause(); + } }); // Replaces the queue in position 1 to the given data ipcMain.on('player-set-queue-next', async (_event, data: PlayerData) => { - const size = await getMpvInstance() - ?.getPlaylistSize() - .catch((err) => { - console.log('MPV failed to get playlist size', err); - }); + const size = await getMpvInstance() + ?.getPlaylistSize() + .catch((err) => { + console.log('MPV failed to get playlist size', err); + }); - if (!size) { - return; - } + if (!size) { + return; + } - if (size > 1) { - await getMpvInstance() - ?.playlistRemove(1) - .catch((err) => { - console.log('MPV failed to remove song from playlist', err); - }); - } + if (size > 1) { + await getMpvInstance() + ?.playlistRemove(1) + .catch((err) => { + console.log('MPV failed to remove song from playlist', err); + }); + } - if (data.queue.next) { - await getMpvInstance() - ?.load(data.queue.next.streamUrl, 'append') - .catch((err) => { - console.log('MPV failed to load next song', err); - }); - } + if (data.queue.next) { + await getMpvInstance() + ?.load(data.queue.next.streamUrl, 'append') + .catch((err) => { + console.log('MPV failed to load next song', err); + }); + } }); // Sets the next song in the queue when reaching the end of the queue ipcMain.on('player-auto-next', async (_event, data: PlayerData) => { - // Always keep the current song as position 0 in the mpv queue - // This allows us to easily set update the next song in the queue without - // disturbing the currently playing song - await getMpvInstance() - ?.playlistRemove(0) - .catch((err) => { - console.log('MPV failed to remove song from playlist', err); - }); - - if (data.queue.next) { + // Always keep the current song as position 0 in the mpv queue + // This allows us to easily set update the next song in the queue without + // disturbing the currently playing song await getMpvInstance() - ?.load(data.queue.next.streamUrl, 'append') - .catch((err) => { - console.log('MPV failed to load next song', err); - }); - } + ?.playlistRemove(0) + .catch((err) => { + console.log('MPV failed to remove song from playlist', err); + }); + + if (data.queue.next) { + await getMpvInstance() + ?.load(data.queue.next.streamUrl, 'append') + .catch((err) => { + console.log('MPV failed to load next song', err); + }); + } }); // Sets the volume to the given value (0-100) ipcMain.on('player-volume', async (_event, value: number) => { - await getMpvInstance() - ?.volume(value) - .catch((err) => { - console.log('MPV failed to set volume', err); - }); + await getMpvInstance() + ?.volume(value) + .catch((err) => { + console.log('MPV failed to set volume', err); + }); }); // Toggles the mute status ipcMain.on('player-mute', async () => { - await getMpvInstance() - ?.mute() - .catch((err) => { - console.log('MPV failed to toggle mute', err); - }); + await getMpvInstance() + ?.mute() + .catch((err) => { + console.log('MPV failed to toggle mute', err); + }); }); ipcMain.handle('player-get-time', async (): Promise => { - return getMpvInstance()?.getTimePosition(); + return getMpvInstance()?.getTimePosition(); }); diff --git a/src/main/features/core/player/media-keys.ts b/src/main/features/core/player/media-keys.ts index 3a34be8b..2aefd7fd 100644 --- a/src/main/features/core/player/media-keys.ts +++ b/src/main/features/core/player/media-keys.ts @@ -2,26 +2,26 @@ import { BrowserWindow, globalShortcut } from 'electron'; export const enableMediaKeys = (window: BrowserWindow | null) => { - globalShortcut.register('MediaStop', () => { - window?.webContents.send('renderer-player-stop'); - }); + globalShortcut.register('MediaStop', () => { + window?.webContents.send('renderer-player-stop'); + }); - globalShortcut.register('MediaPlayPause', () => { - window?.webContents.send('renderer-player-play-pause'); - }); + globalShortcut.register('MediaPlayPause', () => { + window?.webContents.send('renderer-player-play-pause'); + }); - globalShortcut.register('MediaNextTrack', () => { - window?.webContents.send('renderer-player-next'); - }); + globalShortcut.register('MediaNextTrack', () => { + window?.webContents.send('renderer-player-next'); + }); - globalShortcut.register('MediaPreviousTrack', () => { - window?.webContents.send('renderer-player-previous'); - }); + globalShortcut.register('MediaPreviousTrack', () => { + window?.webContents.send('renderer-player-previous'); + }); }; export const disableMediaKeys = () => { - globalShortcut.unregister('MediaStop'); - globalShortcut.unregister('MediaPlayPause'); - globalShortcut.unregister('MediaNextTrack'); - globalShortcut.unregister('MediaPreviousTrack'); + globalShortcut.unregister('MediaStop'); + globalShortcut.unregister('MediaPlayPause'); + globalShortcut.unregister('MediaNextTrack'); + globalShortcut.unregister('MediaPreviousTrack'); }; diff --git a/src/main/features/core/settings/index.ts b/src/main/features/core/settings/index.ts index 47e6264b..f45addea 100644 --- a/src/main/features/core/settings/index.ts +++ b/src/main/features/core/settings/index.ts @@ -4,47 +4,47 @@ import Store from 'electron-store'; export const store = new Store(); ipcMain.handle('settings-get', (_event, data: { property: string }) => { - return store.get(`${data.property}`); + return store.get(`${data.property}`); }); ipcMain.on('settings-set', (__event, data: { property: string; value: any }) => { - store.set(`${data.property}`, data.value); + store.set(`${data.property}`, data.value); }); ipcMain.handle('password-get', (_event, server: string): string | null => { - if (safeStorage.isEncryptionAvailable()) { - const servers = store.get('server') as Record | undefined; + if (safeStorage.isEncryptionAvailable()) { + const servers = store.get('server') as Record | undefined; - if (!servers) { - return null; + if (!servers) { + return null; + } + + const encrypted = servers[server]; + if (!encrypted) return null; + + const decrypted = safeStorage.decryptString(Buffer.from(encrypted, 'hex')); + return decrypted; } - const encrypted = servers[server]; - if (!encrypted) return null; - - const decrypted = safeStorage.decryptString(Buffer.from(encrypted, 'hex')); - return decrypted; - } - - return null; + return null; }); ipcMain.on('password-remove', (_event, server: string) => { - const passwords = store.get('server', {}) as Record; - if (server in passwords) { - delete passwords[server]; - } - store.set({ server: passwords }); + const passwords = store.get('server', {}) as Record; + if (server in passwords) { + delete passwords[server]; + } + store.set({ server: passwords }); }); ipcMain.handle('password-set', (_event, password: string, server: string) => { - if (safeStorage.isEncryptionAvailable()) { - const encrypted = safeStorage.encryptString(password); - const passwords = store.get('server', {}) as Record; - passwords[server] = encrypted.toString('hex'); - store.set({ server: passwords }); + if (safeStorage.isEncryptionAvailable()) { + const encrypted = safeStorage.encryptString(password); + const passwords = store.get('server', {}) as Record; + passwords[server] = encrypted.toString('hex'); + store.set({ server: passwords }); - return true; - } - return false; + return true; + } + return false; }); diff --git a/src/main/features/linux/mpris.ts b/src/main/features/linux/mpris.ts index d027c8b9..3b005ac0 100644 --- a/src/main/features/linux/mpris.ts +++ b/src/main/features/linux/mpris.ts @@ -5,164 +5,166 @@ import { getMainWindow } from '../../main'; import { PlayerRepeat, PlayerShuffle, PlayerStatus } from '/@/renderer/types'; const mprisPlayer = Player({ - identity: 'Feishin', - maximumRate: 1.0, - minimumRate: 1.0, - name: 'Feishin', - rate: 1.0, - supportedInterfaces: ['player'], - supportedMimeTypes: ['audio/mpeg', 'application/ogg'], - supportedUriSchemes: ['file'], + identity: 'Feishin', + maximumRate: 1.0, + minimumRate: 1.0, + name: 'Feishin', + rate: 1.0, + supportedInterfaces: ['player'], + supportedMimeTypes: ['audio/mpeg', 'application/ogg'], + supportedUriSchemes: ['file'], }); mprisPlayer.on('quit', () => { - process.exit(); + process.exit(); }); mprisPlayer.on('stop', () => { - getMainWindow()?.webContents.send('renderer-player-stop'); - mprisPlayer.playbackStatus = 'Paused'; + getMainWindow()?.webContents.send('renderer-player-stop'); + mprisPlayer.playbackStatus = 'Paused'; }); mprisPlayer.on('pause', () => { - getMainWindow()?.webContents.send('renderer-player-pause'); - mprisPlayer.playbackStatus = 'Paused'; + getMainWindow()?.webContents.send('renderer-player-pause'); + mprisPlayer.playbackStatus = 'Paused'; }); mprisPlayer.on('play', () => { - getMainWindow()?.webContents.send('renderer-player-play'); - mprisPlayer.playbackStatus = 'Playing'; + getMainWindow()?.webContents.send('renderer-player-play'); + mprisPlayer.playbackStatus = 'Playing'; }); mprisPlayer.on('playpause', () => { - getMainWindow()?.webContents.send('renderer-player-play-pause'); - if (mprisPlayer.playbackStatus !== 'Playing') { - mprisPlayer.playbackStatus = 'Playing'; - } else { - mprisPlayer.playbackStatus = 'Paused'; - } + getMainWindow()?.webContents.send('renderer-player-play-pause'); + if (mprisPlayer.playbackStatus !== 'Playing') { + mprisPlayer.playbackStatus = 'Playing'; + } else { + mprisPlayer.playbackStatus = 'Paused'; + } }); mprisPlayer.on('next', () => { - getMainWindow()?.webContents.send('renderer-player-next'); + getMainWindow()?.webContents.send('renderer-player-next'); - if (mprisPlayer.playbackStatus !== 'Playing') { - mprisPlayer.playbackStatus = 'Playing'; - } + if (mprisPlayer.playbackStatus !== 'Playing') { + mprisPlayer.playbackStatus = 'Playing'; + } }); mprisPlayer.on('previous', () => { - getMainWindow()?.webContents.send('renderer-player-previous'); + getMainWindow()?.webContents.send('renderer-player-previous'); - if (mprisPlayer.playbackStatus !== 'Playing') { - mprisPlayer.playbackStatus = Player.PLAYBACK_STATUS_PLAYING; - } + if (mprisPlayer.playbackStatus !== 'Playing') { + mprisPlayer.playbackStatus = Player.PLAYBACK_STATUS_PLAYING; + } }); mprisPlayer.on('volume', (event: any) => { - getMainWindow()?.webContents.send('mpris-request-volume', { - volume: event, - }); + getMainWindow()?.webContents.send('mpris-request-volume', { + volume: event, + }); }); mprisPlayer.on('shuffle', (event: boolean) => { - getMainWindow()?.webContents.send('mpris-request-toggle-shuffle', { shuffle: event }); - mprisPlayer.shuffle = event; + getMainWindow()?.webContents.send('mpris-request-toggle-shuffle', { shuffle: event }); + mprisPlayer.shuffle = event; }); mprisPlayer.on('loopStatus', (event: string) => { - getMainWindow()?.webContents.send('mpris-request-toggle-repeat', { repeat: event }); - mprisPlayer.loopStatus = event; + getMainWindow()?.webContents.send('mpris-request-toggle-repeat', { repeat: event }); + mprisPlayer.loopStatus = event; }); mprisPlayer.on('position', (event: any) => { - getMainWindow()?.webContents.send('mpris-request-position', { - position: event.position / 1e6, - }); + getMainWindow()?.webContents.send('mpris-request-position', { + position: event.position / 1e6, + }); }); mprisPlayer.on('seek', (event: number) => { - getMainWindow()?.webContents.send('mpris-request-seek', { - offset: event / 1e6, - }); + getMainWindow()?.webContents.send('mpris-request-seek', { + offset: event / 1e6, + }); }); ipcMain.on('mpris-update-position', (_event, arg) => { - mprisPlayer.getPosition = () => arg * 1e6; + mprisPlayer.getPosition = () => arg * 1e6; }); ipcMain.on('mpris-update-seek', (_event, arg) => { - mprisPlayer.seeked(arg * 1e6); + mprisPlayer.seeked(arg * 1e6); }); ipcMain.on('mpris-update-volume', (_event, arg) => { - mprisPlayer.volume = Number(arg); + mprisPlayer.volume = Number(arg); }); ipcMain.on('mpris-update-repeat', (_event, arg) => { - mprisPlayer.loopStatus = arg; + mprisPlayer.loopStatus = arg; }); ipcMain.on('mpris-update-shuffle', (_event, arg) => { - mprisPlayer.shuffle = arg; + mprisPlayer.shuffle = arg; }); ipcMain.on( - 'mpris-update-song', - ( - _event, - args: { - currentTime: number; - repeat: PlayerRepeat; - shuffle: PlayerShuffle; - song: QueueSong; - status: PlayerStatus; + 'mpris-update-song', + ( + _event, + args: { + currentTime: number; + repeat: PlayerRepeat; + shuffle: PlayerShuffle; + song: QueueSong; + status: PlayerStatus; + }, + ) => { + const { song, status, repeat, shuffle } = args || {}; + + try { + mprisPlayer.playbackStatus = status; + + if (repeat) { + mprisPlayer.loopStatus = + repeat === 'all' ? 'Playlist' : repeat === 'one' ? 'Track' : 'None'; + } + + if (shuffle) { + mprisPlayer.shuffle = shuffle !== 'none'; + } + + if (!song) return; + + const upsizedImageUrl = song.imageUrl + ? song.imageUrl + ?.replace(/&size=\d+/, '&size=300') + .replace(/\?width=\d+/, '?width=300') + .replace(/&height=\d+/, '&height=300') + : null; + + mprisPlayer.metadata = { + 'mpris:artUrl': upsizedImageUrl, + 'mpris:length': song.duration ? Math.round((song.duration || 0) * 1e6) : null, + 'mpris:trackid': song?.id + ? mprisPlayer.objectPath(`track/${song.id?.replace('-', '')}`) + : '', + 'xesam:album': song.album || null, + 'xesam:albumArtist': song.albumArtists?.length ? song.albumArtists[0].name : null, + 'xesam:artist': + song.artists?.length !== 0 + ? song.artists?.map((artist: RelatedArtist) => artist.name) + : null, + 'xesam:discNumber': song.discNumber ? song.discNumber : null, + 'xesam:genre': song.genres?.length + ? song.genres.map((genre: any) => genre.name) + : null, + 'xesam:title': song.name || null, + 'xesam:trackNumber': song.trackNumber ? song.trackNumber : null, + 'xesam:useCount': + song.playCount !== null && song.playCount !== undefined ? song.playCount : null, + }; + } catch (err) { + console.log(err); + } }, - ) => { - const { song, status, repeat, shuffle } = args || {}; - - try { - mprisPlayer.playbackStatus = status; - - if (repeat) { - mprisPlayer.loopStatus = - repeat === 'all' ? 'Playlist' : repeat === 'one' ? 'Track' : 'None'; - } - - if (shuffle) { - mprisPlayer.shuffle = shuffle !== 'none'; - } - - if (!song) return; - - const upsizedImageUrl = song.imageUrl - ? song.imageUrl - ?.replace(/&size=\d+/, '&size=300') - .replace(/\?width=\d+/, '?width=300') - .replace(/&height=\d+/, '&height=300') - : null; - - mprisPlayer.metadata = { - 'mpris:artUrl': upsizedImageUrl, - 'mpris:length': song.duration ? Math.round((song.duration || 0) * 1e6) : null, - 'mpris:trackid': song?.id - ? mprisPlayer.objectPath(`track/${song.id?.replace('-', '')}`) - : '', - 'xesam:album': song.album || null, - 'xesam:albumArtist': song.albumArtists?.length ? song.albumArtists[0].name : null, - 'xesam:artist': - song.artists?.length !== 0 - ? song.artists?.map((artist: RelatedArtist) => artist.name) - : null, - 'xesam:discNumber': song.discNumber ? song.discNumber : null, - 'xesam:genre': song.genres?.length ? song.genres.map((genre: any) => genre.name) : null, - 'xesam:title': song.name || null, - 'xesam:trackNumber': song.trackNumber ? song.trackNumber : null, - 'xesam:useCount': - song.playCount !== null && song.playCount !== undefined ? song.playCount : null, - }; - } catch (err) { - console.log(err); - } - }, ); diff --git a/src/main/main.ts b/src/main/main.ts index c894d445..b32cb71b 100644 --- a/src/main/main.ts +++ b/src/main/main.ts @@ -12,15 +12,15 @@ import { access, constants, readFile, writeFile } from 'fs'; import path, { join } from 'path'; import { deflate, inflate } from 'zlib'; import { - app, - BrowserWindow, - shell, - ipcMain, - globalShortcut, - Tray, - Menu, - nativeImage, - BrowserWindowConstructorOptions, + app, + BrowserWindow, + shell, + ipcMain, + globalShortcut, + Tray, + Menu, + nativeImage, + BrowserWindowConstructorOptions, } from 'electron'; import electronLocalShortcut from 'electron-localshortcut'; import log from 'electron-log'; @@ -36,19 +36,19 @@ import './features'; declare module 'node-mpv'; export default class AppUpdater { - constructor() { - log.transports.file.level = 'info'; - autoUpdater.logger = log; - autoUpdater.checkForUpdatesAndNotify(); - } + constructor() { + log.transports.file.level = 'info'; + autoUpdater.logger = log; + autoUpdater.checkForUpdatesAndNotify(); + } } process.on('uncaughtException', (error: any) => { - console.log('Error in main process', error); + console.log('Error in main process', error); }); if (store.get('ignore_ssl')) { - app.commandLine.appendSwitch('ignore-certificate-errors'); + app.commandLine.appendSwitch('ignore-certificate-errors'); } let mainWindow: BrowserWindow | null = null; @@ -57,362 +57,362 @@ let exitFromTray = false; let forceQuit = false; if (process.env.NODE_ENV === 'production') { - const sourceMapSupport = require('source-map-support'); - sourceMapSupport.install(); + const sourceMapSupport = require('source-map-support'); + sourceMapSupport.install(); } const isDevelopment = process.env.NODE_ENV === 'development' || process.env.DEBUG_PROD === 'true'; if (isDevelopment) { - require('electron-debug')(); + require('electron-debug')(); } const installExtensions = async () => { - const installer = require('electron-devtools-installer'); - const forceDownload = !!process.env.UPGRADE_EXTENSIONS; - const extensions = ['REACT_DEVELOPER_TOOLS', 'REDUX_DEVTOOLS']; + const installer = require('electron-devtools-installer'); + const forceDownload = !!process.env.UPGRADE_EXTENSIONS; + const extensions = ['REACT_DEVELOPER_TOOLS', 'REDUX_DEVTOOLS']; - return installer - .default( - extensions.map((name) => installer[name]), - forceDownload, - ) - .catch(console.log); + return installer + .default( + extensions.map((name) => installer[name]), + forceDownload, + ) + .catch(console.log); }; const singleInstance = app.requestSingleInstanceLock(); if (!singleInstance) { - app.quit(); + app.quit(); } else { - app.on('second-instance', (_event, _argv, _workingDirectory) => { - mainWindow?.show(); - }); + app.on('second-instance', () => { + mainWindow?.show(); + }); } const RESOURCES_PATH = app.isPackaged - ? path.join(process.resourcesPath, 'assets') - : path.join(__dirname, '../../assets'); + ? path.join(process.resourcesPath, 'assets') + : path.join(__dirname, '../../assets'); const getAssetPath = (...paths: string[]): string => { - return path.join(RESOURCES_PATH, ...paths); + return path.join(RESOURCES_PATH, ...paths); }; export const getMainWindow = () => { - return mainWindow; + return mainWindow; }; const createWinThumbarButtons = () => { - if (isWindows()) { - getMainWindow()?.setThumbarButtons([ - { - click: () => getMainWindow()?.webContents.send('renderer-player-previous'), - icon: nativeImage.createFromPath(getAssetPath('skip-previous.png')), - tooltip: 'Previous Track', - }, - { - click: () => getMainWindow()?.webContents.send('renderer-player-play-pause'), - icon: nativeImage.createFromPath(getAssetPath('play-circle.png')), - tooltip: 'Play/Pause', - }, - { - click: () => getMainWindow()?.webContents.send('renderer-player-next'), - icon: nativeImage.createFromPath(getAssetPath('skip-next.png')), - tooltip: 'Next Track', - }, - ]); - } + if (isWindows()) { + getMainWindow()?.setThumbarButtons([ + { + click: () => getMainWindow()?.webContents.send('renderer-player-previous'), + icon: nativeImage.createFromPath(getAssetPath('skip-previous.png')), + tooltip: 'Previous Track', + }, + { + click: () => getMainWindow()?.webContents.send('renderer-player-play-pause'), + icon: nativeImage.createFromPath(getAssetPath('play-circle.png')), + tooltip: 'Play/Pause', + }, + { + click: () => getMainWindow()?.webContents.send('renderer-player-next'), + icon: nativeImage.createFromPath(getAssetPath('skip-next.png')), + tooltip: 'Next Track', + }, + ]); + } }; const createTray = () => { - if (isMacOS()) { - return; - } + if (isMacOS()) { + return; + } - tray = isLinux() ? new Tray(getAssetPath('icon.png')) : new Tray(getAssetPath('icon.ico')); - const contextMenu = Menu.buildFromTemplate([ - { - click: () => { - getMainWindow()?.webContents.send('renderer-player-play-pause'); - }, - label: 'Play/Pause', - }, - { - click: () => { - getMainWindow()?.webContents.send('renderer-player-next'); - }, - label: 'Next Track', - }, - { - click: () => { - getMainWindow()?.webContents.send('renderer-player-previous'); - }, - label: 'Previous Track', - }, - { - click: () => { - getMainWindow()?.webContents.send('renderer-player-stop'); - }, - label: 'Stop', - }, - { - type: 'separator', - }, - { - click: () => { + tray = isLinux() ? new Tray(getAssetPath('icon.png')) : new Tray(getAssetPath('icon.ico')); + const contextMenu = Menu.buildFromTemplate([ + { + click: () => { + getMainWindow()?.webContents.send('renderer-player-play-pause'); + }, + label: 'Play/Pause', + }, + { + click: () => { + getMainWindow()?.webContents.send('renderer-player-next'); + }, + label: 'Next Track', + }, + { + click: () => { + getMainWindow()?.webContents.send('renderer-player-previous'); + }, + label: 'Previous Track', + }, + { + click: () => { + getMainWindow()?.webContents.send('renderer-player-stop'); + }, + label: 'Stop', + }, + { + type: 'separator', + }, + { + click: () => { + mainWindow?.show(); + createWinThumbarButtons(); + }, + label: 'Open main window', + }, + { + click: () => { + exitFromTray = true; + app.quit(); + }, + label: 'Quit', + }, + ]); + + tray.on('double-click', () => { mainWindow?.show(); createWinThumbarButtons(); - }, - label: 'Open main window', - }, - { - click: () => { - exitFromTray = true; - app.quit(); - }, - label: 'Quit', - }, - ]); + }); - tray.on('double-click', () => { - mainWindow?.show(); - createWinThumbarButtons(); - }); - - tray.setToolTip('Feishin'); - tray.setContextMenu(contextMenu); + tray.setToolTip('Feishin'); + tray.setContextMenu(contextMenu); }; const createWindow = async () => { - if (isDevelopment) { - await installExtensions(); - } - - const nativeFrame = store.get('window_window_bar_style') === 'linux'; - store.set('window_has_frame', nativeFrame); - - const nativeFrameConfig: Record = { - linux: { - autoHideMenuBar: true, - frame: true, - }, - macOS: { - autoHideMenuBar: true, - frame: false, - titleBarStyle: 'hidden', - trafficLightPosition: { x: 10, y: 10 }, - }, - windows: { - autoHideMenuBar: true, - frame: true, - }, - }; - - mainWindow = new BrowserWindow({ - autoHideMenuBar: true, - frame: false, - height: 900, - icon: getAssetPath('icon.png'), - minHeight: 640, - minWidth: 480, - show: false, - webPreferences: { - allowRunningInsecureContent: !!store.get('ignore_ssl'), - backgroundThrottling: false, - contextIsolation: true, - devTools: true, - nodeIntegration: true, - preload: app.isPackaged - ? path.join(__dirname, 'preload.js') - : path.join(__dirname, '../../.erb/dll/preload.js'), - webSecurity: !store.get('ignore_cors'), - }, - width: 1440, - ...(nativeFrame && isLinux() && nativeFrameConfig.linux), - ...(nativeFrame && isMacOS() && nativeFrameConfig.macOS), - ...(nativeFrame && isWindows() && nativeFrameConfig.windows), - }); - - electronLocalShortcut.register(mainWindow, 'Ctrl+Shift+I', () => { - mainWindow?.webContents.openDevTools(); - }); - - ipcMain.on('window-dev-tools', () => { - mainWindow?.webContents.openDevTools(); - }); - - ipcMain.on('window-maximize', () => { - mainWindow?.maximize(); - }); - - ipcMain.on('window-unmaximize', () => { - mainWindow?.unmaximize(); - }); - - ipcMain.on('window-minimize', () => { - mainWindow?.minimize(); - }); - - ipcMain.on('window-close', () => { - mainWindow?.close(); - }); - - ipcMain.on('app-restart', () => { - // Fix for .AppImage - if (process.env.APPIMAGE) { - app.exit(); - app.relaunch({ - args: process.argv.slice(1).concat(['--appimage-extract-and-run']), - execPath: process.env.APPIMAGE, - }); - app.exit(0); - } else { - app.relaunch(); - app.exit(0); - } - }); - - ipcMain.on('global-media-keys-enable', () => { - enableMediaKeys(mainWindow); - }); - - ipcMain.on('global-media-keys-disable', () => { - disableMediaKeys(); - }); - - ipcMain.on('player-restore-queue', () => { - if (store.get('resume')) { - const queueLocation = join(app.getPath('userData'), 'queue'); - - access(queueLocation, constants.F_OK, (accessError) => { - if (accessError) { - console.error('unable to access saved queue: ', accessError); - return; - } - - readFile(queueLocation, (readError, buffer) => { - if (readError) { - console.error('failed to read saved queue: ', readError); - return; - } - - inflate(buffer, (decompressError, data) => { - if (decompressError) { - console.error('failed to decompress queue: ', decompressError); - return; - } - - const queue = JSON.parse(data.toString()); - getMainWindow()?.webContents.send('renderer-player-restore-queue', queue); - }); - }); - }); - } - }); - - const globalMediaKeysEnabled = store.get('global_media_hotkeys') as boolean; - - if (globalMediaKeysEnabled !== false) { - enableMediaKeys(mainWindow); - } - - mainWindow.loadURL(resolveHtmlPath('index.html')); - - mainWindow.on('ready-to-show', () => { - if (!mainWindow) { - throw new Error('"mainWindow" is not defined'); - } - if (process.env.START_MINIMIZED) { - mainWindow.minimize(); - } else { - mainWindow.show(); - createWinThumbarButtons(); - } - }); - - mainWindow.on('closed', () => { - mainWindow = null; - }); - - let saved = false; - - mainWindow.on('close', (event) => { - if (!exitFromTray && store.get('window_exit_to_tray')) { - if (isMacOS() && !forceQuit) { - exitFromTray = true; - } - event.preventDefault(); - mainWindow?.hide(); + if (isDevelopment) { + await installExtensions(); } - if (!saved && store.get('resume')) { - event.preventDefault(); - saved = true; + const nativeFrame = store.get('window_window_bar_style') === 'linux'; + store.set('window_has_frame', nativeFrame); - getMainWindow()?.webContents.send('renderer-player-save-queue'); + const nativeFrameConfig: Record = { + linux: { + autoHideMenuBar: true, + frame: true, + }, + macOS: { + autoHideMenuBar: true, + frame: false, + titleBarStyle: 'hidden', + trafficLightPosition: { x: 10, y: 10 }, + }, + windows: { + autoHideMenuBar: true, + frame: true, + }, + }; - ipcMain.once('player-save-queue', async (_event, data: Record) => { - const queueLocation = join(app.getPath('userData'), 'queue'); - const serialized = JSON.stringify(data); - - try { - await new Promise((resolve, reject) => { - deflate(serialized, { level: 1 }, (error, deflated) => { - if (error) { - reject(error); - } else { - writeFile(queueLocation, deflated, (writeError) => { - if (writeError) { - reject(writeError); - } else { - resolve(); - } - }); - } - }); - }); - } catch (error) { - console.error('error saving queue state: ', error); - } finally { - mainWindow?.close(); - if (forceQuit) { - app.exit(); - } - } - }); - } - }); - - mainWindow.on('minimize', (event: any) => { - if (store.get('window_minimize_to_tray') === true) { - event.preventDefault(); - mainWindow?.hide(); - } - }); - - if (isWindows()) { - app.setAppUserModelId(process.execPath); - } - - if (isMacOS()) { - app.on('before-quit', () => { - forceQuit = true; + mainWindow = new BrowserWindow({ + autoHideMenuBar: true, + frame: false, + height: 900, + icon: getAssetPath('icon.png'), + minHeight: 640, + minWidth: 480, + show: false, + webPreferences: { + allowRunningInsecureContent: !!store.get('ignore_ssl'), + backgroundThrottling: false, + contextIsolation: true, + devTools: true, + nodeIntegration: true, + preload: app.isPackaged + ? path.join(__dirname, 'preload.js') + : path.join(__dirname, '../../.erb/dll/preload.js'), + webSecurity: !store.get('ignore_cors'), + }, + width: 1440, + ...(nativeFrame && isLinux() && nativeFrameConfig.linux), + ...(nativeFrame && isMacOS() && nativeFrameConfig.macOS), + ...(nativeFrame && isWindows() && nativeFrameConfig.windows), }); - } - const menuBuilder = new MenuBuilder(mainWindow); - menuBuilder.buildMenu(); + electronLocalShortcut.register(mainWindow, 'Ctrl+Shift+I', () => { + mainWindow?.webContents.openDevTools(); + }); - // Open urls in the user's browser - mainWindow.webContents.setWindowOpenHandler((edata) => { - shell.openExternal(edata.url); - return { action: 'deny' }; - }); + ipcMain.on('window-dev-tools', () => { + mainWindow?.webContents.openDevTools(); + }); - if (store.get('disable_auto_updates') !== true) { - // eslint-disable-next-line - new AppUpdater(); - } + ipcMain.on('window-maximize', () => { + mainWindow?.maximize(); + }); + + ipcMain.on('window-unmaximize', () => { + mainWindow?.unmaximize(); + }); + + ipcMain.on('window-minimize', () => { + mainWindow?.minimize(); + }); + + ipcMain.on('window-close', () => { + mainWindow?.close(); + }); + + ipcMain.on('app-restart', () => { + // Fix for .AppImage + if (process.env.APPIMAGE) { + app.exit(); + app.relaunch({ + args: process.argv.slice(1).concat(['--appimage-extract-and-run']), + execPath: process.env.APPIMAGE, + }); + app.exit(0); + } else { + app.relaunch(); + app.exit(0); + } + }); + + ipcMain.on('global-media-keys-enable', () => { + enableMediaKeys(mainWindow); + }); + + ipcMain.on('global-media-keys-disable', () => { + disableMediaKeys(); + }); + + ipcMain.on('player-restore-queue', () => { + if (store.get('resume')) { + const queueLocation = join(app.getPath('userData'), 'queue'); + + access(queueLocation, constants.F_OK, (accessError) => { + if (accessError) { + console.error('unable to access saved queue: ', accessError); + return; + } + + readFile(queueLocation, (readError, buffer) => { + if (readError) { + console.error('failed to read saved queue: ', readError); + return; + } + + inflate(buffer, (decompressError, data) => { + if (decompressError) { + console.error('failed to decompress queue: ', decompressError); + return; + } + + const queue = JSON.parse(data.toString()); + getMainWindow()?.webContents.send('renderer-player-restore-queue', queue); + }); + }); + }); + } + }); + + const globalMediaKeysEnabled = store.get('global_media_hotkeys') as boolean; + + if (globalMediaKeysEnabled !== false) { + enableMediaKeys(mainWindow); + } + + mainWindow.loadURL(resolveHtmlPath('index.html')); + + mainWindow.on('ready-to-show', () => { + if (!mainWindow) { + throw new Error('"mainWindow" is not defined'); + } + if (process.env.START_MINIMIZED) { + mainWindow.minimize(); + } else { + mainWindow.show(); + createWinThumbarButtons(); + } + }); + + mainWindow.on('closed', () => { + mainWindow = null; + }); + + let saved = false; + + mainWindow.on('close', (event) => { + if (!exitFromTray && store.get('window_exit_to_tray')) { + if (isMacOS() && !forceQuit) { + exitFromTray = true; + } + event.preventDefault(); + mainWindow?.hide(); + } + + if (!saved && store.get('resume')) { + event.preventDefault(); + saved = true; + + getMainWindow()?.webContents.send('renderer-player-save-queue'); + + ipcMain.once('player-save-queue', async (_event, data: Record) => { + const queueLocation = join(app.getPath('userData'), 'queue'); + const serialized = JSON.stringify(data); + + try { + await new Promise((resolve, reject) => { + deflate(serialized, { level: 1 }, (error, deflated) => { + if (error) { + reject(error); + } else { + writeFile(queueLocation, deflated, (writeError) => { + if (writeError) { + reject(writeError); + } else { + resolve(); + } + }); + } + }); + }); + } catch (error) { + console.error('error saving queue state: ', error); + } finally { + mainWindow?.close(); + if (forceQuit) { + app.exit(); + } + } + }); + } + }); + + mainWindow.on('minimize', (event: any) => { + if (store.get('window_minimize_to_tray') === true) { + event.preventDefault(); + mainWindow?.hide(); + } + }); + + if (isWindows()) { + app.setAppUserModelId(process.execPath); + } + + if (isMacOS()) { + app.on('before-quit', () => { + forceQuit = true; + }); + } + + const menuBuilder = new MenuBuilder(mainWindow); + menuBuilder.buildMenu(); + + // Open urls in the user's browser + mainWindow.webContents.setWindowOpenHandler((edata) => { + shell.openExternal(edata.url); + return { action: 'deny' }; + }); + + if (store.get('disable_auto_updates') !== true) { + // eslint-disable-next-line + new AppUpdater(); + } }; app.commandLine.appendSwitch('disable-features', 'HardwareMediaKeyHandling,MediaSessionService'); @@ -420,231 +420,234 @@ app.commandLine.appendSwitch('disable-features', 'HardwareMediaKeyHandling,Media const MPV_BINARY_PATH = store.get('mpv_path') as string | undefined; const prefetchPlaylistParams = [ - '--prefetch-playlist=no', - '--prefetch-playlist=yes', - '--prefetch-playlist', + '--prefetch-playlist=no', + '--prefetch-playlist=yes', + '--prefetch-playlist', ]; const DEFAULT_MPV_PARAMETERS = (extraParameters?: string[]) => { - const parameters = ['--idle=yes']; + const parameters = ['--idle=yes']; - if (!extraParameters?.some((param) => prefetchPlaylistParams.includes(param))) { - parameters.push('--prefetch-playlist=yes'); - } + if (!extraParameters?.some((param) => prefetchPlaylistParams.includes(param))) { + parameters.push('--prefetch-playlist=yes'); + } - return parameters; + return parameters; }; let mpvInstance: MpvAPI | null = null; const createMpv = (data: { extraParameters?: string[]; properties?: Record }) => { - const { extraParameters, properties } = data; + const { extraParameters, properties } = data; - const params = uniq([...DEFAULT_MPV_PARAMETERS(extraParameters), ...(extraParameters || [])]); - console.log('Setting mpv params: ', params); + const params = uniq([...DEFAULT_MPV_PARAMETERS(extraParameters), ...(extraParameters || [])]); + console.log('Setting mpv params: ', params); - const mpv = new MpvAPI( - { - audio_only: true, - auto_restart: false, - binary: MPV_BINARY_PATH || '', - time_update: 1, - }, - params, - ); + const mpv = new MpvAPI( + { + audio_only: true, + auto_restart: false, + binary: MPV_BINARY_PATH || '', + time_update: 1, + }, + params, + ); - console.log('Setting MPV properties: ', properties); - mpv.setMultipleProperties(properties || {}); + console.log('Setting MPV properties: ', properties); + mpv.setMultipleProperties(properties || {}); - mpv.start().catch((error) => { - console.log('MPV failed to start', error); - }); + mpv.start().catch((error) => { + console.log('MPV failed to start', error); + }); - mpv.on('status', (status, ...rest) => { - console.log('MPV Event: status', status.property, status.value, rest); - if (status.property === 'playlist-pos') { - if (status.value === -1) { - mpv?.stop(); - } + mpv.on('status', (status, ...rest) => { + console.log('MPV Event: status', status.property, status.value, rest); + if (status.property === 'playlist-pos') { + if (status.value === -1) { + mpv?.stop(); + } - if (status.value !== 0) { - getMainWindow()?.webContents.send('renderer-player-auto-next'); - } - } - }); + if (status.value !== 0) { + getMainWindow()?.webContents.send('renderer-player-auto-next'); + } + } + }); - // Automatically updates the play button when the player is playing - mpv.on('resumed', () => { - console.log('MPV Event: resumed'); - getMainWindow()?.webContents.send('renderer-player-play'); - }); + // Automatically updates the play button when the player is playing + mpv.on('resumed', () => { + console.log('MPV Event: resumed'); + getMainWindow()?.webContents.send('renderer-player-play'); + }); - // Automatically updates the play button when the player is stopped - mpv.on('stopped', () => { - console.log('MPV Event: stopped'); - getMainWindow()?.webContents.send('renderer-player-stop'); - }); + // Automatically updates the play button when the player is stopped + mpv.on('stopped', () => { + console.log('MPV Event: stopped'); + getMainWindow()?.webContents.send('renderer-player-stop'); + }); - // Automatically updates the play button when the player is paused - mpv.on('paused', () => { - console.log('MPV Event: paused'); - getMainWindow()?.webContents.send('renderer-player-pause'); - }); + // Automatically updates the play button when the player is paused + mpv.on('paused', () => { + console.log('MPV Event: paused'); + getMainWindow()?.webContents.send('renderer-player-pause'); + }); - // Event output every interval set by time_update, used to update the current time - mpv.on('timeposition', (time: number) => { - getMainWindow()?.webContents.send('renderer-player-current-time', time); - }); + // Event output every interval set by time_update, used to update the current time + mpv.on('timeposition', (time: number) => { + getMainWindow()?.webContents.send('renderer-player-current-time', time); + }); - mpv.on('quit', () => { - console.log('MPV Event: quit'); - }); + mpv.on('quit', () => { + console.log('MPV Event: quit'); + }); - return mpv; + return mpv; }; export const getMpvInstance = () => { - return mpvInstance; + return mpvInstance; }; ipcMain.on('player-set-properties', async (_event, data: Record) => { - if (data.length === 0) { - return; - } + if (data.length === 0) { + return; + } - if (data.length === 1) { - getMpvInstance()?.setProperty(Object.keys(data)[0], Object.values(data)[0]); - } else { - getMpvInstance()?.setMultipleProperties(data); - } + if (data.length === 1) { + getMpvInstance()?.setProperty(Object.keys(data)[0], Object.values(data)[0]); + } else { + getMpvInstance()?.setMultipleProperties(data); + } }); ipcMain.on( - 'player-restart', - async (_event, data: { extraParameters?: string[]; properties?: Record }) => { - mpvInstance?.quit(); - mpvInstance = createMpv(data); - }, + 'player-restart', + async (_event, data: { extraParameters?: string[]; properties?: Record }) => { + mpvInstance?.quit(); + mpvInstance = createMpv(data); + }, ); ipcMain.on( - 'player-initialize', - async (_event, data: { extraParameters?: string[]; properties?: Record }) => { - console.log('Initializing MPV with data: ', data); - mpvInstance = createMpv(data); - }, + 'player-initialize', + async (_event, data: { extraParameters?: string[]; properties?: Record }) => { + console.log('Initializing MPV with data: ', data); + mpvInstance = createMpv(data); + }, ); ipcMain.on('player-quit', async () => { - mpvInstance?.stop(); - mpvInstance?.quit(); - mpvInstance = null; + mpvInstance?.stop(); + mpvInstance?.quit(); + mpvInstance = null; }); // Must duplicate with the one in renderer process settings.store.ts enum BindingActions { - GLOBAL_SEARCH = 'globalSearch', - LOCAL_SEARCH = 'localSearch', - MUTE = 'volumeMute', - NEXT = 'next', - PAUSE = 'pause', - PLAY = 'play', - PLAY_PAUSE = 'playPause', - PREVIOUS = 'previous', - SHUFFLE = 'toggleShuffle', - SKIP_BACKWARD = 'skipBackward', - SKIP_FORWARD = 'skipForward', - STOP = 'stop', - TOGGLE_FULLSCREEN_PLAYER = 'toggleFullscreenPlayer', - TOGGLE_QUEUE = 'toggleQueue', - TOGGLE_REPEAT = 'toggleRepeat', - VOLUME_DOWN = 'volumeDown', - VOLUME_UP = 'volumeUp', + GLOBAL_SEARCH = 'globalSearch', + LOCAL_SEARCH = 'localSearch', + MUTE = 'volumeMute', + NEXT = 'next', + PAUSE = 'pause', + PLAY = 'play', + PLAY_PAUSE = 'playPause', + PREVIOUS = 'previous', + SHUFFLE = 'toggleShuffle', + SKIP_BACKWARD = 'skipBackward', + SKIP_FORWARD = 'skipForward', + STOP = 'stop', + TOGGLE_FULLSCREEN_PLAYER = 'toggleFullscreenPlayer', + TOGGLE_QUEUE = 'toggleQueue', + TOGGLE_REPEAT = 'toggleRepeat', + VOLUME_DOWN = 'volumeDown', + VOLUME_UP = 'volumeUp', } const HOTKEY_ACTIONS: Record void> = { - [BindingActions.MUTE]: () => getMainWindow()?.webContents.send('renderer-player-volume-mute'), - [BindingActions.NEXT]: () => getMainWindow()?.webContents.send('renderer-player-next'), - [BindingActions.PAUSE]: () => getMainWindow()?.webContents.send('renderer-player-pause'), - [BindingActions.PLAY]: () => getMainWindow()?.webContents.send('renderer-player-play'), - [BindingActions.PLAY_PAUSE]: () => - getMainWindow()?.webContents.send('renderer-player-play-pause'), - [BindingActions.PREVIOUS]: () => getMainWindow()?.webContents.send('renderer-player-previous'), - [BindingActions.SHUFFLE]: () => - getMainWindow()?.webContents.send('renderer-player-toggle-shuffle'), - [BindingActions.SKIP_BACKWARD]: () => - getMainWindow()?.webContents.send('renderer-player-skip-backward'), - [BindingActions.SKIP_FORWARD]: () => - getMainWindow()?.webContents.send('renderer-player-skip-forward'), - [BindingActions.STOP]: () => getMainWindow()?.webContents.send('renderer-player-stop'), - [BindingActions.TOGGLE_REPEAT]: () => - getMainWindow()?.webContents.send('renderer-player-toggle-repeat'), - [BindingActions.VOLUME_UP]: () => getMainWindow()?.webContents.send('renderer-player-volume-up'), - [BindingActions.VOLUME_DOWN]: () => - getMainWindow()?.webContents.send('renderer-player-volume-down'), - [BindingActions.GLOBAL_SEARCH]: () => {}, - [BindingActions.LOCAL_SEARCH]: () => {}, - [BindingActions.TOGGLE_QUEUE]: () => {}, - [BindingActions.TOGGLE_FULLSCREEN_PLAYER]: () => {}, + [BindingActions.MUTE]: () => getMainWindow()?.webContents.send('renderer-player-volume-mute'), + [BindingActions.NEXT]: () => getMainWindow()?.webContents.send('renderer-player-next'), + [BindingActions.PAUSE]: () => getMainWindow()?.webContents.send('renderer-player-pause'), + [BindingActions.PLAY]: () => getMainWindow()?.webContents.send('renderer-player-play'), + [BindingActions.PLAY_PAUSE]: () => + getMainWindow()?.webContents.send('renderer-player-play-pause'), + [BindingActions.PREVIOUS]: () => getMainWindow()?.webContents.send('renderer-player-previous'), + [BindingActions.SHUFFLE]: () => + getMainWindow()?.webContents.send('renderer-player-toggle-shuffle'), + [BindingActions.SKIP_BACKWARD]: () => + getMainWindow()?.webContents.send('renderer-player-skip-backward'), + [BindingActions.SKIP_FORWARD]: () => + getMainWindow()?.webContents.send('renderer-player-skip-forward'), + [BindingActions.STOP]: () => getMainWindow()?.webContents.send('renderer-player-stop'), + [BindingActions.TOGGLE_REPEAT]: () => + getMainWindow()?.webContents.send('renderer-player-toggle-repeat'), + [BindingActions.VOLUME_UP]: () => + getMainWindow()?.webContents.send('renderer-player-volume-up'), + [BindingActions.VOLUME_DOWN]: () => + getMainWindow()?.webContents.send('renderer-player-volume-down'), + [BindingActions.GLOBAL_SEARCH]: () => {}, + [BindingActions.LOCAL_SEARCH]: () => {}, + [BindingActions.TOGGLE_QUEUE]: () => {}, + [BindingActions.TOGGLE_FULLSCREEN_PLAYER]: () => {}, }; ipcMain.on( - 'set-global-shortcuts', - ( - _event, - data: Record, - ) => { - // Since we're not tracking the previous shortcuts, we need to unregister all of them - globalShortcut.unregisterAll(); + 'set-global-shortcuts', + ( + _event, + data: Record, + ) => { + // Since we're not tracking the previous shortcuts, we need to unregister all of them + globalShortcut.unregisterAll(); - for (const shortcut of Object.keys(data)) { - const isGlobalHotkey = data[shortcut as BindingActions].isGlobal; - const isValidHotkey = - data[shortcut as BindingActions].hotkey && data[shortcut as BindingActions].hotkey !== ''; + for (const shortcut of Object.keys(data)) { + const isGlobalHotkey = data[shortcut as BindingActions].isGlobal; + const isValidHotkey = + data[shortcut as BindingActions].hotkey && + data[shortcut as BindingActions].hotkey !== ''; - if (isGlobalHotkey && isValidHotkey) { - const accelerator = hotkeyToElectronAccelerator(data[shortcut as BindingActions].hotkey); + if (isGlobalHotkey && isValidHotkey) { + const accelerator = hotkeyToElectronAccelerator( + data[shortcut as BindingActions].hotkey, + ); - globalShortcut.register(accelerator, () => { - HOTKEY_ACTIONS[shortcut as BindingActions](); - }); - } - } + globalShortcut.register(accelerator, () => { + HOTKEY_ACTIONS[shortcut as BindingActions](); + }); + } + } - const globalMediaKeysEnabled = store.get('global_media_hotkeys') as boolean; + const globalMediaKeysEnabled = store.get('global_media_hotkeys') as boolean; - if (globalMediaKeysEnabled) { - enableMediaKeys(mainWindow); - } - }, + if (globalMediaKeysEnabled) { + enableMediaKeys(mainWindow); + } + }, ); app.on('before-quit', () => { - getMpvInstance()?.stop(); - getMpvInstance()?.quit(); + getMpvInstance()?.stop(); + getMpvInstance()?.quit(); }); app.on('window-all-closed', () => { - globalShortcut.unregisterAll(); - getMpvInstance()?.quit(); - // Respect the OSX convention of having the application in memory even - // after all windows have been closed - if (isMacOS()) { - mainWindow = null; - } else { - app.quit(); - } + globalShortcut.unregisterAll(); + getMpvInstance()?.quit(); + // Respect the OSX convention of having the application in memory even + // after all windows have been closed + if (isMacOS()) { + mainWindow = null; + } else { + app.quit(); + } }); -app - .whenReady() - .then(() => { - createWindow(); - createTray(); - app.on('activate', () => { - // On macOS it's common to re-create a window in the app when the - // dock icon is clicked and there are no other windows open. - if (mainWindow === null) createWindow(); - }); - }) - .catch(console.log); +app.whenReady() + .then(() => { + createWindow(); + createTray(); + app.on('activate', () => { + // On macOS it's common to re-create a window in the app when the + // dock icon is clicked and there are no other windows open. + if (mainWindow === null) createWindow(); + }); + }) + .catch(console.log); diff --git a/src/main/menu.ts b/src/main/menu.ts index 6e46419c..e5baa686 100644 --- a/src/main/menu.ts +++ b/src/main/menu.ts @@ -1,269 +1,279 @@ import { app, Menu, shell, BrowserWindow, MenuItemConstructorOptions } from 'electron'; interface DarwinMenuItemConstructorOptions extends MenuItemConstructorOptions { - selector?: string; - submenu?: DarwinMenuItemConstructorOptions[] | Menu; + selector?: string; + submenu?: DarwinMenuItemConstructorOptions[] | Menu; } export default class MenuBuilder { - mainWindow: BrowserWindow; + mainWindow: BrowserWindow; - constructor(mainWindow: BrowserWindow) { - this.mainWindow = mainWindow; - } - - buildMenu(): Menu { - if (process.env.NODE_ENV === 'development' || process.env.DEBUG_PROD === 'true') { - this.setupDevelopmentEnvironment(); + constructor(mainWindow: BrowserWindow) { + this.mainWindow = mainWindow; } - const template = - process.platform === 'darwin' ? this.buildDarwinTemplate() : this.buildDefaultTemplate(); + buildMenu(): Menu { + if (process.env.NODE_ENV === 'development' || process.env.DEBUG_PROD === 'true') { + this.setupDevelopmentEnvironment(); + } - const menu = Menu.buildFromTemplate(template); - Menu.setApplicationMenu(menu); + const template = + process.platform === 'darwin' + ? this.buildDarwinTemplate() + : this.buildDefaultTemplate(); - return menu; - } + const menu = Menu.buildFromTemplate(template); + Menu.setApplicationMenu(menu); - setupDevelopmentEnvironment(): void { - this.mainWindow.webContents.on('context-menu', (_, props) => { - const { x, y } = props; + return menu; + } - Menu.buildFromTemplate([ - { - click: () => { - this.mainWindow.webContents.inspectElement(x, y); - }, - label: 'Inspect element', - }, - ]).popup({ window: this.mainWindow }); - }); - } + setupDevelopmentEnvironment(): void { + this.mainWindow.webContents.on('context-menu', (_, props) => { + const { x, y } = props; - buildDarwinTemplate(): MenuItemConstructorOptions[] { - const subMenuAbout: DarwinMenuItemConstructorOptions = { - label: 'Electron', - submenu: [ - { - label: 'About ElectronReact', - selector: 'orderFrontStandardAboutPanel:', - }, - { type: 'separator' }, - { label: 'Services', submenu: [] }, - { type: 'separator' }, - { - accelerator: 'Command+H', - label: 'Hide ElectronReact', - selector: 'hide:', - }, - { - accelerator: 'Command+Shift+H', - label: 'Hide Others', - selector: 'hideOtherApplications:', - }, - { label: 'Show All', selector: 'unhideAllApplications:' }, - { type: 'separator' }, - { - accelerator: 'Command+Q', - click: () => { - app.quit(); - }, - label: 'Quit', - }, - ], - }; - const subMenuEdit: DarwinMenuItemConstructorOptions = { - label: 'Edit', - submenu: [ - { accelerator: 'Command+Z', label: 'Undo', selector: 'undo:' }, - { accelerator: 'Shift+Command+Z', label: 'Redo', selector: 'redo:' }, - { type: 'separator' }, - { accelerator: 'Command+X', label: 'Cut', selector: 'cut:' }, - { accelerator: 'Command+C', label: 'Copy', selector: 'copy:' }, - { accelerator: 'Command+V', label: 'Paste', selector: 'paste:' }, - { - accelerator: 'Command+A', - label: 'Select All', - selector: 'selectAll:', - }, - ], - }; - const subMenuViewDev: MenuItemConstructorOptions = { - label: 'View', - submenu: [ - { - accelerator: 'Command+R', - click: () => { - this.mainWindow.webContents.reload(); - }, - label: 'Reload', - }, - { - accelerator: 'Ctrl+Command+F', - click: () => { - this.mainWindow.setFullScreen(!this.mainWindow.isFullScreen()); - }, - label: 'Toggle Full Screen', - }, - { - accelerator: 'Alt+Command+I', - click: () => { - this.mainWindow.webContents.toggleDevTools(); - }, - label: 'Toggle Developer Tools', - }, - ], - }; - const subMenuViewProd: MenuItemConstructorOptions = { - label: 'View', - submenu: [ - { - accelerator: 'Ctrl+Command+F', - click: () => { - this.mainWindow.setFullScreen(!this.mainWindow.isFullScreen()); - }, - label: 'Toggle Full Screen', - }, - ], - }; - const subMenuWindow: DarwinMenuItemConstructorOptions = { - label: 'Window', - submenu: [ - { - accelerator: 'Command+M', - label: 'Minimize', - selector: 'performMiniaturize:', - }, - { accelerator: 'Command+W', label: 'Close', selector: 'performClose:' }, - { type: 'separator' }, - { label: 'Bring All to Front', selector: 'arrangeInFront:' }, - ], - }; - const subMenuHelp: MenuItemConstructorOptions = { - label: 'Help', - submenu: [ - { - click() { - shell.openExternal('https://electronjs.org'); - }, - label: 'Learn More', - }, - { - click() { - shell.openExternal('https://github.com/electron/electron/tree/main/docs#readme'); - }, - label: 'Documentation', - }, - { - click() { - shell.openExternal('https://www.electronjs.org/community'); - }, - label: 'Community Discussions', - }, - { - click() { - shell.openExternal('https://github.com/electron/electron/issues'); - }, - label: 'Search Issues', - }, - ], - }; - - const subMenuView = - process.env.NODE_ENV === 'development' || process.env.DEBUG_PROD === 'true' - ? subMenuViewDev - : subMenuViewProd; - - return [subMenuAbout, subMenuEdit, subMenuView, subMenuWindow, subMenuHelp]; - } - - buildDefaultTemplate() { - const templateDefault = [ - { - label: '&File', - submenu: [ - { - accelerator: 'Ctrl+O', - label: '&Open', - }, - { - accelerator: 'Ctrl+W', - click: () => { - this.mainWindow.close(); - }, - label: '&Close', - }, - ], - }, - { - label: '&View', - submenu: - process.env.NODE_ENV === 'development' || process.env.DEBUG_PROD === 'true' - ? [ + Menu.buildFromTemplate([ { - accelerator: 'Ctrl+R', - click: () => { - this.mainWindow.webContents.reload(); - }, - label: '&Reload', + click: () => { + this.mainWindow.webContents.inspectElement(x, y); + }, + label: 'Inspect element', + }, + ]).popup({ window: this.mainWindow }); + }); + } + + buildDarwinTemplate(): MenuItemConstructorOptions[] { + const subMenuAbout: DarwinMenuItemConstructorOptions = { + label: 'Electron', + submenu: [ + { + label: 'About ElectronReact', + selector: 'orderFrontStandardAboutPanel:', + }, + { type: 'separator' }, + { label: 'Services', submenu: [] }, + { type: 'separator' }, + { + accelerator: 'Command+H', + label: 'Hide ElectronReact', + selector: 'hide:', }, { - accelerator: 'F11', - click: () => { - this.mainWindow.setFullScreen(!this.mainWindow.isFullScreen()); - }, - label: 'Toggle &Full Screen', + accelerator: 'Command+Shift+H', + label: 'Hide Others', + selector: 'hideOtherApplications:', + }, + { label: 'Show All', selector: 'unhideAllApplications:' }, + { type: 'separator' }, + { + accelerator: 'Command+Q', + click: () => { + app.quit(); + }, + label: 'Quit', + }, + ], + }; + const subMenuEdit: DarwinMenuItemConstructorOptions = { + label: 'Edit', + submenu: [ + { accelerator: 'Command+Z', label: 'Undo', selector: 'undo:' }, + { accelerator: 'Shift+Command+Z', label: 'Redo', selector: 'redo:' }, + { type: 'separator' }, + { accelerator: 'Command+X', label: 'Cut', selector: 'cut:' }, + { accelerator: 'Command+C', label: 'Copy', selector: 'copy:' }, + { accelerator: 'Command+V', label: 'Paste', selector: 'paste:' }, + { + accelerator: 'Command+A', + label: 'Select All', + selector: 'selectAll:', + }, + ], + }; + const subMenuViewDev: MenuItemConstructorOptions = { + label: 'View', + submenu: [ + { + accelerator: 'Command+R', + click: () => { + this.mainWindow.webContents.reload(); + }, + label: 'Reload', }, { - accelerator: 'Alt+Ctrl+I', - click: () => { - this.mainWindow.webContents.toggleDevTools(); - }, - label: 'Toggle &Developer Tools', + accelerator: 'Ctrl+Command+F', + click: () => { + this.mainWindow.setFullScreen(!this.mainWindow.isFullScreen()); + }, + label: 'Toggle Full Screen', }, - ] - : [ { - accelerator: 'F11', - click: () => { - this.mainWindow.setFullScreen(!this.mainWindow.isFullScreen()); - }, - label: 'Toggle &Full Screen', + accelerator: 'Alt+Command+I', + click: () => { + this.mainWindow.webContents.toggleDevTools(); + }, + label: 'Toggle Developer Tools', }, - ], - }, - { - label: 'Help', - submenu: [ - { - click() { - shell.openExternal('https://electronjs.org'); - }, - label: 'Learn More', - }, - { - click() { - shell.openExternal('https://github.com/electron/electron/tree/main/docs#readme'); - }, - label: 'Documentation', - }, - { - click() { - shell.openExternal('https://www.electronjs.org/community'); - }, - label: 'Community Discussions', - }, - { - click() { - shell.openExternal('https://github.com/electron/electron/issues'); - }, - label: 'Search Issues', - }, - ], - }, - ]; + ], + }; + const subMenuViewProd: MenuItemConstructorOptions = { + label: 'View', + submenu: [ + { + accelerator: 'Ctrl+Command+F', + click: () => { + this.mainWindow.setFullScreen(!this.mainWindow.isFullScreen()); + }, + label: 'Toggle Full Screen', + }, + ], + }; + const subMenuWindow: DarwinMenuItemConstructorOptions = { + label: 'Window', + submenu: [ + { + accelerator: 'Command+M', + label: 'Minimize', + selector: 'performMiniaturize:', + }, + { accelerator: 'Command+W', label: 'Close', selector: 'performClose:' }, + { type: 'separator' }, + { label: 'Bring All to Front', selector: 'arrangeInFront:' }, + ], + }; + const subMenuHelp: MenuItemConstructorOptions = { + label: 'Help', + submenu: [ + { + click() { + shell.openExternal('https://electronjs.org'); + }, + label: 'Learn More', + }, + { + click() { + shell.openExternal( + 'https://github.com/electron/electron/tree/main/docs#readme', + ); + }, + label: 'Documentation', + }, + { + click() { + shell.openExternal('https://www.electronjs.org/community'); + }, + label: 'Community Discussions', + }, + { + click() { + shell.openExternal('https://github.com/electron/electron/issues'); + }, + label: 'Search Issues', + }, + ], + }; - return templateDefault; - } + const subMenuView = + process.env.NODE_ENV === 'development' || process.env.DEBUG_PROD === 'true' + ? subMenuViewDev + : subMenuViewProd; + + return [subMenuAbout, subMenuEdit, subMenuView, subMenuWindow, subMenuHelp]; + } + + buildDefaultTemplate() { + const templateDefault = [ + { + label: '&File', + submenu: [ + { + accelerator: 'Ctrl+O', + label: '&Open', + }, + { + accelerator: 'Ctrl+W', + click: () => { + this.mainWindow.close(); + }, + label: '&Close', + }, + ], + }, + { + label: '&View', + submenu: + process.env.NODE_ENV === 'development' || process.env.DEBUG_PROD === 'true' + ? [ + { + accelerator: 'Ctrl+R', + click: () => { + this.mainWindow.webContents.reload(); + }, + label: '&Reload', + }, + { + accelerator: 'F11', + click: () => { + this.mainWindow.setFullScreen( + !this.mainWindow.isFullScreen(), + ); + }, + label: 'Toggle &Full Screen', + }, + { + accelerator: 'Alt+Ctrl+I', + click: () => { + this.mainWindow.webContents.toggleDevTools(); + }, + label: 'Toggle &Developer Tools', + }, + ] + : [ + { + accelerator: 'F11', + click: () => { + this.mainWindow.setFullScreen( + !this.mainWindow.isFullScreen(), + ); + }, + label: 'Toggle &Full Screen', + }, + ], + }, + { + label: 'Help', + submenu: [ + { + click() { + shell.openExternal('https://electronjs.org'); + }, + label: 'Learn More', + }, + { + click() { + shell.openExternal( + 'https://github.com/electron/electron/tree/main/docs#readme', + ); + }, + label: 'Documentation', + }, + { + click() { + shell.openExternal('https://www.electronjs.org/community'); + }, + label: 'Community Discussions', + }, + { + click() { + shell.openExternal('https://github.com/electron/electron/issues'); + }, + label: 'Search Issues', + }, + ], + }, + ]; + + return templateDefault; + } } diff --git a/src/main/preload.ts b/src/main/preload.ts index 7cf38577..5527baff 100644 --- a/src/main/preload.ts +++ b/src/main/preload.ts @@ -8,12 +8,12 @@ import { mpvPlayer, mpvPlayerListener } from './preload/mpv-player'; import { utils } from './preload/utils'; contextBridge.exposeInMainWorld('electron', { - browser, - ipc, - localSettings, - lyrics, - mpris, - mpvPlayer, - mpvPlayerListener, - utils, + browser, + ipc, + localSettings, + lyrics, + mpris, + mpvPlayer, + mpvPlayerListener, + utils, }); diff --git a/src/main/preload/browser.ts b/src/main/preload/browser.ts index 0ca1ede7..b9b18429 100644 --- a/src/main/preload/browser.ts +++ b/src/main/preload/browser.ts @@ -1,26 +1,26 @@ import { ipcRenderer } from 'electron'; const exit = () => { - ipcRenderer.send('window-close'); + ipcRenderer.send('window-close'); }; const maximize = () => { - ipcRenderer.send('window-maximize'); + ipcRenderer.send('window-maximize'); }; const minimize = () => { - ipcRenderer.send('window-minimize'); + ipcRenderer.send('window-minimize'); }; const unmaximize = () => { - ipcRenderer.send('window-unmaximize'); + ipcRenderer.send('window-unmaximize'); }; const devtools = () => { - ipcRenderer.send('window-dev-tools'); + ipcRenderer.send('window-dev-tools'); }; export const browser = { - devtools, - exit, - maximize, - minimize, - unmaximize, + devtools, + exit, + maximize, + minimize, + unmaximize, }; diff --git a/src/main/preload/ipc.ts b/src/main/preload/ipc.ts index 780b8830..32eaa597 100644 --- a/src/main/preload/ipc.ts +++ b/src/main/preload/ipc.ts @@ -1,14 +1,14 @@ import { ipcRenderer } from 'electron'; const removeAllListeners = (channel: string) => { - ipcRenderer.removeAllListeners(channel); + ipcRenderer.removeAllListeners(channel); }; const send = (channel: string, ...args: any[]) => { - ipcRenderer.send(channel, ...args); + ipcRenderer.send(channel, ...args); }; export const ipc = { - removeAllListeners, - send, + removeAllListeners, + send, }; diff --git a/src/main/preload/local-settings.ts b/src/main/preload/local-settings.ts index fc08369e..8facb8a3 100644 --- a/src/main/preload/local-settings.ts +++ b/src/main/preload/local-settings.ts @@ -4,49 +4,49 @@ import Store from 'electron-store'; const store = new Store(); const set = (property: string, value: string | Record | boolean | string[]) => { - store.set(`${property}`, value); + store.set(`${property}`, value); }; const get = (property: string) => { - return store.get(`${property}`); + return store.get(`${property}`); }; const restart = () => { - ipcRenderer.send('app-restart'); + ipcRenderer.send('app-restart'); }; const enableMediaKeys = () => { - ipcRenderer.send('global-media-keys-enable'); + ipcRenderer.send('global-media-keys-enable'); }; const disableMediaKeys = () => { - ipcRenderer.send('global-media-keys-disable'); + ipcRenderer.send('global-media-keys-disable'); }; const passwordGet = async (server: string): Promise => { - return ipcRenderer.invoke('password-get', server); + return ipcRenderer.invoke('password-get', server); }; const passwordRemove = (server: string) => { - ipcRenderer.send('password-remove', server); + ipcRenderer.send('password-remove', server); }; const passwordSet = async (password: string, server: string): Promise => { - return ipcRenderer.invoke('password-set', password, server); + return ipcRenderer.invoke('password-set', password, server); }; const setZoomFactor = (zoomFactor: number) => { - webFrame.setZoomFactor(zoomFactor / 100); + webFrame.setZoomFactor(zoomFactor / 100); }; export const localSettings = { - disableMediaKeys, - enableMediaKeys, - get, - passwordGet, - passwordRemove, - passwordSet, - restart, - set, - setZoomFactor, + disableMediaKeys, + enableMediaKeys, + get, + passwordGet, + passwordRemove, + passwordSet, + restart, + set, + setZoomFactor, }; diff --git a/src/main/preload/lyrics.ts b/src/main/preload/lyrics.ts index 27df51ed..a472357c 100644 --- a/src/main/preload/lyrics.ts +++ b/src/main/preload/lyrics.ts @@ -2,22 +2,22 @@ import { ipcRenderer } from 'electron'; import { LyricSearchQuery, QueueSong } from '/@/renderer/api/types'; const getRemoteLyricsBySong = (song: QueueSong) => { - const result = ipcRenderer.invoke('lyric-by-song', song); - return result; + const result = ipcRenderer.invoke('lyric-by-song', song); + return result; }; const searchRemoteLyrics = (params: LyricSearchQuery) => { - const result = ipcRenderer.invoke('lyric-search', params); - return result; + const result = ipcRenderer.invoke('lyric-search', params); + return result; }; const getRemoteLyricsByRemoteId = (id: string) => { - const result = ipcRenderer.invoke('lyric-by-remote-id', id); - return result; + const result = ipcRenderer.invoke('lyric-by-remote-id', id); + return result; }; export const lyrics = { - getRemoteLyricsByRemoteId, - getRemoteLyricsBySong, - searchRemoteLyrics, + getRemoteLyricsByRemoteId, + getRemoteLyricsBySong, + searchRemoteLyrics, }; diff --git a/src/main/preload/mpris.ts b/src/main/preload/mpris.ts index eeb84e94..273bb83f 100644 --- a/src/main/preload/mpris.ts +++ b/src/main/preload/mpris.ts @@ -2,69 +2,69 @@ import { IpcRendererEvent, ipcRenderer } from 'electron'; import { QueueSong } from '/@/renderer/api/types'; const updateSong = (args: { currentTime: number; song: QueueSong }) => { - ipcRenderer.send('mpris-update-song', args); + ipcRenderer.send('mpris-update-song', args); }; const updatePosition = (timeSec: number) => { - ipcRenderer.send('mpris-update-position', timeSec); + ipcRenderer.send('mpris-update-position', timeSec); }; const updateSeek = (timeSec: number) => { - ipcRenderer.send('mpris-update-seek', timeSec); + ipcRenderer.send('mpris-update-seek', timeSec); }; const updateVolume = (volume: number) => { - ipcRenderer.send('mpris-update-volume', volume); + ipcRenderer.send('mpris-update-volume', volume); }; const updateRepeat = (repeat: string) => { - ipcRenderer.send('mpris-update-repeat', repeat); + ipcRenderer.send('mpris-update-repeat', repeat); }; const updateShuffle = (shuffle: boolean) => { - ipcRenderer.send('mpris-update-shuffle', shuffle); + ipcRenderer.send('mpris-update-shuffle', shuffle); }; const toggleRepeat = () => { - ipcRenderer.send('mpris-toggle-repeat'); + ipcRenderer.send('mpris-toggle-repeat'); }; const toggleShuffle = () => { - ipcRenderer.send('mpris-toggle-shuffle'); + ipcRenderer.send('mpris-toggle-shuffle'); }; const requestPosition = (cb: (event: IpcRendererEvent, data: { position: number }) => void) => { - ipcRenderer.on('mpris-request-position', cb); + ipcRenderer.on('mpris-request-position', cb); }; const requestSeek = (cb: (event: IpcRendererEvent, data: { offset: number }) => void) => { - ipcRenderer.on('mpris-request-seek', cb); + ipcRenderer.on('mpris-request-seek', cb); }; const requestVolume = (cb: (event: IpcRendererEvent, data: { volume: number }) => void) => { - ipcRenderer.on('mpris-request-volume', cb); + ipcRenderer.on('mpris-request-volume', cb); }; const requestToggleRepeat = (cb: (event: IpcRendererEvent) => void) => { - ipcRenderer.on('mpris-request-toggle-repeat', cb); + ipcRenderer.on('mpris-request-toggle-repeat', cb); }; const requestToggleShuffle = (cb: (event: IpcRendererEvent) => void) => { - ipcRenderer.on('mpris-request-toggle-shuffle', cb); + ipcRenderer.on('mpris-request-toggle-shuffle', cb); }; export const mpris = { - requestPosition, - requestSeek, - requestToggleRepeat, - requestToggleShuffle, - requestVolume, - toggleRepeat, - toggleShuffle, - updatePosition, - updateRepeat, - updateSeek, - updateShuffle, - updateSong, - updateVolume, + requestPosition, + requestSeek, + requestToggleRepeat, + requestToggleShuffle, + requestVolume, + toggleRepeat, + toggleShuffle, + updatePosition, + updateRepeat, + updateSeek, + updateShuffle, + updateSong, + updateVolume, }; diff --git a/src/main/preload/mpv-player.ts b/src/main/preload/mpv-player.ts index 1875537a..e1f57da9 100644 --- a/src/main/preload/mpv-player.ts +++ b/src/main/preload/mpv-player.ts @@ -2,213 +2,213 @@ import { ipcRenderer, IpcRendererEvent } from 'electron'; import { PlayerData } from '/@/renderer/store'; const initialize = (data: { extraParameters?: string[]; properties?: Record }) => { - ipcRenderer.send('player-initialize', data); + ipcRenderer.send('player-initialize', data); }; const restart = (data: { extraParameters?: string[]; properties?: Record }) => { - ipcRenderer.send('player-restart', data); + ipcRenderer.send('player-restart', data); }; const isRunning = () => { - return ipcRenderer.invoke('player-is-running'); + return ipcRenderer.invoke('player-is-running'); }; const cleanup = () => { - return ipcRenderer.invoke('player-clean-up'); + return ipcRenderer.invoke('player-clean-up'); }; const setProperties = (data: Record) => { - console.log('Setting property :>>', data); - ipcRenderer.send('player-set-properties', data); + console.log('Setting property :>>', data); + ipcRenderer.send('player-set-properties', data); }; const autoNext = (data: PlayerData) => { - ipcRenderer.send('player-auto-next', data); + ipcRenderer.send('player-auto-next', data); }; const currentTime = () => { - ipcRenderer.send('player-current-time'); + ipcRenderer.send('player-current-time'); }; const mute = () => { - ipcRenderer.send('player-mute'); + ipcRenderer.send('player-mute'); }; const next = () => { - ipcRenderer.send('player-next'); + ipcRenderer.send('player-next'); }; const pause = () => { - ipcRenderer.send('player-pause'); + ipcRenderer.send('player-pause'); }; const play = () => { - ipcRenderer.send('player-play'); + ipcRenderer.send('player-play'); }; const previous = () => { - ipcRenderer.send('player-previous'); + ipcRenderer.send('player-previous'); }; const restoreQueue = () => { - ipcRenderer.send('player-restore-queue'); + ipcRenderer.send('player-restore-queue'); }; const saveQueue = (data: Record) => { - ipcRenderer.send('player-save-queue', data); + ipcRenderer.send('player-save-queue', data); }; const seek = (seconds: number) => { - ipcRenderer.send('player-seek', seconds); + ipcRenderer.send('player-seek', seconds); }; const seekTo = (seconds: number) => { - ipcRenderer.send('player-seek-to', seconds); + ipcRenderer.send('player-seek-to', seconds); }; const setQueue = (data: PlayerData, pause?: boolean) => { - ipcRenderer.send('player-set-queue', data, pause); + ipcRenderer.send('player-set-queue', data, pause); }; const setQueueNext = (data: PlayerData) => { - ipcRenderer.send('player-set-queue-next', data); + ipcRenderer.send('player-set-queue-next', data); }; const stop = () => { - ipcRenderer.send('player-stop'); + ipcRenderer.send('player-stop'); }; const volume = (value: number) => { - ipcRenderer.send('player-volume', value); + ipcRenderer.send('player-volume', value); }; const quit = () => { - ipcRenderer.send('player-quit'); + ipcRenderer.send('player-quit'); }; const getCurrentTime = async () => { - return ipcRenderer.invoke('player-get-time'); + return ipcRenderer.invoke('player-get-time'); }; const rendererAutoNext = (cb: (event: IpcRendererEvent, data: PlayerData) => void) => { - ipcRenderer.on('renderer-player-auto-next', cb); + ipcRenderer.on('renderer-player-auto-next', cb); }; const rendererCurrentTime = (cb: (event: IpcRendererEvent, data: number) => void) => { - ipcRenderer.on('renderer-player-current-time', cb); + ipcRenderer.on('renderer-player-current-time', cb); }; const rendererNext = (cb: (event: IpcRendererEvent, data: PlayerData) => void) => { - ipcRenderer.on('renderer-player-next', cb); + ipcRenderer.on('renderer-player-next', cb); }; const rendererPause = (cb: (event: IpcRendererEvent, data: PlayerData) => void) => { - ipcRenderer.on('renderer-player-pause', cb); + ipcRenderer.on('renderer-player-pause', cb); }; const rendererPlay = (cb: (event: IpcRendererEvent, data: PlayerData) => void) => { - ipcRenderer.on('renderer-player-play', cb); + ipcRenderer.on('renderer-player-play', cb); }; const rendererPlayPause = (cb: (event: IpcRendererEvent, data: PlayerData) => void) => { - ipcRenderer.on('renderer-player-play-pause', cb); + ipcRenderer.on('renderer-player-play-pause', cb); }; const rendererPrevious = (cb: (event: IpcRendererEvent, data: PlayerData) => void) => { - ipcRenderer.on('renderer-player-previous', cb); + ipcRenderer.on('renderer-player-previous', cb); }; const rendererStop = (cb: (event: IpcRendererEvent, data: PlayerData) => void) => { - ipcRenderer.on('renderer-player-stop', cb); + ipcRenderer.on('renderer-player-stop', cb); }; const rendererSkipForward = (cb: (event: IpcRendererEvent, data: PlayerData) => void) => { - ipcRenderer.on('renderer-player-skip-forward', cb); + ipcRenderer.on('renderer-player-skip-forward', cb); }; const rendererSkipBackward = (cb: (event: IpcRendererEvent, data: PlayerData) => void) => { - ipcRenderer.on('renderer-player-skip-backward', cb); + ipcRenderer.on('renderer-player-skip-backward', cb); }; const rendererVolumeUp = (cb: (event: IpcRendererEvent, data: PlayerData) => void) => { - ipcRenderer.on('renderer-player-volume-up', cb); + ipcRenderer.on('renderer-player-volume-up', cb); }; const rendererVolumeDown = (cb: (event: IpcRendererEvent, data: PlayerData) => void) => { - ipcRenderer.on('renderer-player-volume-down', cb); + ipcRenderer.on('renderer-player-volume-down', cb); }; const rendererVolumeMute = (cb: (event: IpcRendererEvent, data: PlayerData) => void) => { - ipcRenderer.on('renderer-player-volume-mute', cb); + ipcRenderer.on('renderer-player-volume-mute', cb); }; const rendererToggleRepeat = (cb: (event: IpcRendererEvent, data: PlayerData) => void) => { - ipcRenderer.on('renderer-player-toggle-repeat', cb); + ipcRenderer.on('renderer-player-toggle-repeat', cb); }; const rendererToggleShuffle = (cb: (event: IpcRendererEvent, data: PlayerData) => void) => { - ipcRenderer.on('renderer-player-toggle-shuffle', cb); + ipcRenderer.on('renderer-player-toggle-shuffle', cb); }; const rendererQuit = (cb: (event: IpcRendererEvent) => void) => { - ipcRenderer.on('renderer-player-quit', cb); + ipcRenderer.on('renderer-player-quit', cb); }; const rendererSaveQueue = (cb: (event: IpcRendererEvent) => void) => { - ipcRenderer.on('renderer-player-save-queue', cb); + ipcRenderer.on('renderer-player-save-queue', cb); }; const rendererRestoreQueue = (cb: (event: IpcRendererEvent) => void) => { - ipcRenderer.on('renderer-player-restore-queue', cb); + ipcRenderer.on('renderer-player-restore-queue', cb); }; const rendererError = (cb: (event: IpcRendererEvent, data: string) => void) => { - ipcRenderer.on('renderer-player-error', cb); + ipcRenderer.on('renderer-player-error', cb); }; export const mpvPlayer = { - autoNext, - cleanup, - currentTime, - getCurrentTime, - initialize, - isRunning, - mute, - next, - pause, - play, - previous, - quit, - restart, - restoreQueue, - saveQueue, - seek, - seekTo, - setProperties, - setQueue, - setQueueNext, - stop, - volume, + autoNext, + cleanup, + currentTime, + getCurrentTime, + initialize, + isRunning, + mute, + next, + pause, + play, + previous, + quit, + restart, + restoreQueue, + saveQueue, + seek, + seekTo, + setProperties, + setQueue, + setQueueNext, + stop, + volume, }; export const mpvPlayerListener = { - rendererAutoNext, - rendererCurrentTime, - rendererError, - rendererNext, - rendererPause, - rendererPlay, - rendererPlayPause, - rendererPrevious, - rendererQuit, - rendererRestoreQueue, - rendererSaveQueue, - rendererSkipBackward, - rendererSkipForward, - rendererStop, - rendererToggleRepeat, - rendererToggleShuffle, - rendererVolumeDown, - rendererVolumeMute, - rendererVolumeUp, + rendererAutoNext, + rendererCurrentTime, + rendererError, + rendererNext, + rendererPause, + rendererPlay, + rendererPlayPause, + rendererPrevious, + rendererQuit, + rendererRestoreQueue, + rendererSaveQueue, + rendererSkipBackward, + rendererSkipForward, + rendererStop, + rendererToggleRepeat, + rendererToggleShuffle, + rendererVolumeDown, + rendererVolumeMute, + rendererVolumeUp, }; diff --git a/src/main/preload/utils.ts b/src/main/preload/utils.ts index 54c31528..1b09b37e 100644 --- a/src/main/preload/utils.ts +++ b/src/main/preload/utils.ts @@ -1,7 +1,7 @@ import { isMacOS, isWindows, isLinux } from '../utils'; export const utils = { - isLinux, - isMacOS, - isWindows, + isLinux, + isMacOS, + isWindows, }; diff --git a/src/main/utils.ts b/src/main/utils.ts index 9ca5f52a..5ca169b3 100644 --- a/src/main/utils.ts +++ b/src/main/utils.ts @@ -6,47 +6,47 @@ import { URL } from 'url'; export let resolveHtmlPath: (htmlFileName: string) => string; if (process.env.NODE_ENV === 'development') { - const port = process.env.PORT || 4343; - resolveHtmlPath = (htmlFileName: string) => { - const url = new URL(`http://localhost:${port}`); - url.pathname = htmlFileName; - return url.href; - }; + const port = process.env.PORT || 4343; + resolveHtmlPath = (htmlFileName: string) => { + const url = new URL(`http://localhost:${port}`); + url.pathname = htmlFileName; + return url.href; + }; } else { - resolveHtmlPath = (htmlFileName: string) => { - return `file://${path.resolve(__dirname, '../renderer/', htmlFileName)}`; - }; + resolveHtmlPath = (htmlFileName: string) => { + return `file://${path.resolve(__dirname, '../renderer/', htmlFileName)}`; + }; } export const isMacOS = () => { - return process.platform === 'darwin'; + return process.platform === 'darwin'; }; export const isWindows = () => { - return process.platform === 'win32'; + return process.platform === 'win32'; }; export const isLinux = () => { - return process.platform === 'linux'; + return process.platform === 'linux'; }; export const hotkeyToElectronAccelerator = (hotkey: string) => { - let accelerator = hotkey; + let accelerator = hotkey; - const replacements = { - mod: 'CmdOrCtrl', - numpad: 'num', - numpadadd: 'numadd', - numpaddecimal: 'numdec', - numpaddivide: 'numdiv', - numpadenter: 'numenter', - numpadmultiply: 'nummult', - numpadsubtract: 'numsub', - }; + const replacements = { + mod: 'CmdOrCtrl', + numpad: 'num', + numpadadd: 'numadd', + numpaddecimal: 'numdec', + numpaddivide: 'numdiv', + numpadenter: 'numenter', + numpadmultiply: 'nummult', + numpadsubtract: 'numsub', + }; - Object.keys(replacements).forEach((key) => { - accelerator = accelerator.replace(key, replacements[key as keyof typeof replacements]); - }); + Object.keys(replacements).forEach((key) => { + accelerator = accelerator.replace(key, replacements[key as keyof typeof replacements]); + }); - return accelerator; + return accelerator; }; diff --git a/src/renderer/api/controller.ts b/src/renderer/api/controller.ts index 280ea7be..ea6ce788 100644 --- a/src/renderer/api/controller.ts +++ b/src/renderer/api/controller.ts @@ -1,53 +1,53 @@ import { useAuthStore } from '/@/renderer/store'; import { toast } from '/@/renderer/components/toast/index'; import type { - AlbumDetailArgs, - AlbumListArgs, - SongListArgs, - SongDetailArgs, - AlbumArtistDetailArgs, - AlbumArtistListArgs, - SetRatingArgs, - GenreListArgs, - CreatePlaylistArgs, - DeletePlaylistArgs, - PlaylistDetailArgs, - PlaylistListArgs, - MusicFolderListArgs, - PlaylistSongListArgs, - ArtistListArgs, - UpdatePlaylistArgs, - UserListArgs, - FavoriteArgs, - TopSongListArgs, - AddToPlaylistArgs, - AddToPlaylistResponse, - RemoveFromPlaylistArgs, - RemoveFromPlaylistResponse, - ScrobbleArgs, - ScrobbleResponse, - AlbumArtistDetailResponse, - FavoriteResponse, - CreatePlaylistResponse, - AlbumArtistListResponse, - AlbumDetailResponse, - AlbumListResponse, - ArtistListResponse, - GenreListResponse, - MusicFolderListResponse, - PlaylistDetailResponse, - PlaylistListResponse, - RatingResponse, - SongDetailResponse, - SongListResponse, - TopSongListResponse, - UpdatePlaylistResponse, - UserListResponse, - AuthenticationResponse, - SearchArgs, - SearchResponse, - LyricsArgs, - LyricsResponse, + AlbumDetailArgs, + AlbumListArgs, + SongListArgs, + SongDetailArgs, + AlbumArtistDetailArgs, + AlbumArtistListArgs, + SetRatingArgs, + GenreListArgs, + CreatePlaylistArgs, + DeletePlaylistArgs, + PlaylistDetailArgs, + PlaylistListArgs, + MusicFolderListArgs, + PlaylistSongListArgs, + ArtistListArgs, + UpdatePlaylistArgs, + UserListArgs, + FavoriteArgs, + TopSongListArgs, + AddToPlaylistArgs, + AddToPlaylistResponse, + RemoveFromPlaylistArgs, + RemoveFromPlaylistResponse, + ScrobbleArgs, + ScrobbleResponse, + AlbumArtistDetailResponse, + FavoriteResponse, + CreatePlaylistResponse, + AlbumArtistListResponse, + AlbumDetailResponse, + AlbumListResponse, + ArtistListResponse, + GenreListResponse, + MusicFolderListResponse, + PlaylistDetailResponse, + PlaylistListResponse, + RatingResponse, + SongDetailResponse, + SongListResponse, + TopSongListResponse, + UpdatePlaylistResponse, + UserListResponse, + AuthenticationResponse, + SearchArgs, + SearchResponse, + LyricsArgs, + LyricsResponse, } from '/@/renderer/api/types'; import { ServerType } from '/@/renderer/types'; import { DeletePlaylistResponse, RandomSongListArgs } from './types'; @@ -56,436 +56,445 @@ import { ssController } from '/@/renderer/api/subsonic/subsonic-controller'; import { jfController } from '/@/renderer/api/jellyfin/jellyfin-controller'; export type ControllerEndpoint = Partial<{ - addToPlaylist: (args: AddToPlaylistArgs) => Promise; - authenticate: ( - url: string, - body: { password: string; username: string }, - ) => Promise; - clearPlaylist: () => void; - createFavorite: (args: FavoriteArgs) => Promise; - createPlaylist: (args: CreatePlaylistArgs) => Promise; - deleteFavorite: (args: FavoriteArgs) => Promise; - deletePlaylist: (args: DeletePlaylistArgs) => Promise; - getAlbumArtistDetail: (args: AlbumArtistDetailArgs) => Promise; - getAlbumArtistList: (args: AlbumArtistListArgs) => Promise; - getAlbumDetail: (args: AlbumDetailArgs) => Promise; - getAlbumList: (args: AlbumListArgs) => Promise; - getArtistDetail: () => void; - getArtistInfo: (args: any) => void; - getArtistList: (args: ArtistListArgs) => Promise; - getFavoritesList: () => void; - getFolderItemList: () => void; - getFolderList: () => void; - getFolderSongs: () => void; - getGenreList: (args: GenreListArgs) => Promise; - getLyrics: (args: LyricsArgs) => Promise; - getMusicFolderList: (args: MusicFolderListArgs) => Promise; - getPlaylistDetail: (args: PlaylistDetailArgs) => Promise; - getPlaylistList: (args: PlaylistListArgs) => Promise; - getPlaylistSongList: (args: PlaylistSongListArgs) => Promise; - getRandomSongList: (args: RandomSongListArgs) => Promise; - getSongDetail: (args: SongDetailArgs) => Promise; - getSongList: (args: SongListArgs) => Promise; - getTopSongs: (args: TopSongListArgs) => Promise; - getUserList: (args: UserListArgs) => Promise; - removeFromPlaylist: (args: RemoveFromPlaylistArgs) => Promise; - scrobble: (args: ScrobbleArgs) => Promise; - search: (args: SearchArgs) => Promise; - setRating: (args: SetRatingArgs) => Promise; - updatePlaylist: (args: UpdatePlaylistArgs) => Promise; + addToPlaylist: (args: AddToPlaylistArgs) => Promise; + authenticate: ( + url: string, + body: { password: string; username: string }, + ) => Promise; + clearPlaylist: () => void; + createFavorite: (args: FavoriteArgs) => Promise; + createPlaylist: (args: CreatePlaylistArgs) => Promise; + deleteFavorite: (args: FavoriteArgs) => Promise; + deletePlaylist: (args: DeletePlaylistArgs) => Promise; + getAlbumArtistDetail: (args: AlbumArtistDetailArgs) => Promise; + getAlbumArtistList: (args: AlbumArtistListArgs) => Promise; + getAlbumDetail: (args: AlbumDetailArgs) => Promise; + getAlbumList: (args: AlbumListArgs) => Promise; + getArtistDetail: () => void; + getArtistInfo: (args: any) => void; + getArtistList: (args: ArtistListArgs) => Promise; + getFavoritesList: () => void; + getFolderItemList: () => void; + getFolderList: () => void; + getFolderSongs: () => void; + getGenreList: (args: GenreListArgs) => Promise; + getLyrics: (args: LyricsArgs) => Promise; + getMusicFolderList: (args: MusicFolderListArgs) => Promise; + getPlaylistDetail: (args: PlaylistDetailArgs) => Promise; + getPlaylistList: (args: PlaylistListArgs) => Promise; + getPlaylistSongList: (args: PlaylistSongListArgs) => Promise; + getRandomSongList: (args: RandomSongListArgs) => Promise; + getSongDetail: (args: SongDetailArgs) => Promise; + getSongList: (args: SongListArgs) => Promise; + getTopSongs: (args: TopSongListArgs) => Promise; + getUserList: (args: UserListArgs) => Promise; + removeFromPlaylist: (args: RemoveFromPlaylistArgs) => Promise; + scrobble: (args: ScrobbleArgs) => Promise; + search: (args: SearchArgs) => Promise; + setRating: (args: SetRatingArgs) => Promise; + updatePlaylist: (args: UpdatePlaylistArgs) => Promise; }>; type ApiController = { - jellyfin: ControllerEndpoint; - navidrome: ControllerEndpoint; - subsonic: ControllerEndpoint; + jellyfin: ControllerEndpoint; + navidrome: ControllerEndpoint; + subsonic: ControllerEndpoint; }; const endpoints: ApiController = { - jellyfin: { - addToPlaylist: jfController.addToPlaylist, - authenticate: jfController.authenticate, - clearPlaylist: undefined, - createFavorite: jfController.createFavorite, - createPlaylist: jfController.createPlaylist, - deleteFavorite: jfController.deleteFavorite, - deletePlaylist: jfController.deletePlaylist, - getAlbumArtistDetail: jfController.getAlbumArtistDetail, - getAlbumArtistList: jfController.getAlbumArtistList, - getAlbumDetail: jfController.getAlbumDetail, - getAlbumList: jfController.getAlbumList, - getArtistDetail: undefined, - getArtistInfo: undefined, - getArtistList: undefined, - getFavoritesList: undefined, - getFolderItemList: undefined, - getFolderList: undefined, - getFolderSongs: undefined, - getGenreList: jfController.getGenreList, - getLyrics: jfController.getLyrics, - getMusicFolderList: jfController.getMusicFolderList, - getPlaylistDetail: jfController.getPlaylistDetail, - getPlaylistList: jfController.getPlaylistList, - getPlaylistSongList: jfController.getPlaylistSongList, - getRandomSongList: jfController.getRandomSongList, - getSongDetail: undefined, - getSongList: jfController.getSongList, - getTopSongs: jfController.getTopSongList, - getUserList: undefined, - removeFromPlaylist: jfController.removeFromPlaylist, - scrobble: jfController.scrobble, - search: jfController.search, - setRating: undefined, - updatePlaylist: jfController.updatePlaylist, - }, - navidrome: { - addToPlaylist: ndController.addToPlaylist, - authenticate: ndController.authenticate, - clearPlaylist: undefined, - createFavorite: ssController.createFavorite, - createPlaylist: ndController.createPlaylist, - deleteFavorite: ssController.removeFavorite, - deletePlaylist: ndController.deletePlaylist, - getAlbumArtistDetail: ndController.getAlbumArtistDetail, - getAlbumArtistList: ndController.getAlbumArtistList, - getAlbumDetail: ndController.getAlbumDetail, - getAlbumList: ndController.getAlbumList, - getArtistDetail: undefined, - getArtistInfo: undefined, - getArtistList: undefined, - getFavoritesList: undefined, - getFolderItemList: undefined, - getFolderList: undefined, - getFolderSongs: undefined, - getGenreList: ndController.getGenreList, - getLyrics: undefined, - getMusicFolderList: ssController.getMusicFolderList, - getPlaylistDetail: ndController.getPlaylistDetail, - getPlaylistList: ndController.getPlaylistList, - getPlaylistSongList: ndController.getPlaylistSongList, - getRandomSongList: ssController.getRandomSongList, - getSongDetail: ndController.getSongDetail, - getSongList: ndController.getSongList, - getTopSongs: ssController.getTopSongList, - getUserList: ndController.getUserList, - removeFromPlaylist: ndController.removeFromPlaylist, - scrobble: ssController.scrobble, - search: ssController.search3, - setRating: ssController.setRating, - updatePlaylist: ndController.updatePlaylist, - }, - subsonic: { - authenticate: ssController.authenticate, - clearPlaylist: undefined, - createFavorite: ssController.createFavorite, - createPlaylist: undefined, - deleteFavorite: ssController.removeFavorite, - deletePlaylist: undefined, - getAlbumArtistDetail: undefined, - getAlbumArtistList: undefined, - getAlbumDetail: undefined, - getAlbumList: undefined, - getArtistDetail: undefined, - getArtistInfo: undefined, - getArtistList: undefined, - getFavoritesList: undefined, - getFolderItemList: undefined, - getFolderList: undefined, - getFolderSongs: undefined, - getGenreList: undefined, - getLyrics: undefined, - getMusicFolderList: ssController.getMusicFolderList, - getPlaylistDetail: undefined, - getPlaylistList: undefined, - getSongDetail: undefined, - getSongList: undefined, - getTopSongs: ssController.getTopSongList, - getUserList: undefined, - scrobble: ssController.scrobble, - search: ssController.search3, - setRating: undefined, - updatePlaylist: undefined, - }, + jellyfin: { + addToPlaylist: jfController.addToPlaylist, + authenticate: jfController.authenticate, + clearPlaylist: undefined, + createFavorite: jfController.createFavorite, + createPlaylist: jfController.createPlaylist, + deleteFavorite: jfController.deleteFavorite, + deletePlaylist: jfController.deletePlaylist, + getAlbumArtistDetail: jfController.getAlbumArtistDetail, + getAlbumArtistList: jfController.getAlbumArtistList, + getAlbumDetail: jfController.getAlbumDetail, + getAlbumList: jfController.getAlbumList, + getArtistDetail: undefined, + getArtistInfo: undefined, + getArtistList: undefined, + getFavoritesList: undefined, + getFolderItemList: undefined, + getFolderList: undefined, + getFolderSongs: undefined, + getGenreList: jfController.getGenreList, + getLyrics: jfController.getLyrics, + getMusicFolderList: jfController.getMusicFolderList, + getPlaylistDetail: jfController.getPlaylistDetail, + getPlaylistList: jfController.getPlaylistList, + getPlaylistSongList: jfController.getPlaylistSongList, + getRandomSongList: jfController.getRandomSongList, + getSongDetail: undefined, + getSongList: jfController.getSongList, + getTopSongs: jfController.getTopSongList, + getUserList: undefined, + removeFromPlaylist: jfController.removeFromPlaylist, + scrobble: jfController.scrobble, + search: jfController.search, + setRating: undefined, + updatePlaylist: jfController.updatePlaylist, + }, + navidrome: { + addToPlaylist: ndController.addToPlaylist, + authenticate: ndController.authenticate, + clearPlaylist: undefined, + createFavorite: ssController.createFavorite, + createPlaylist: ndController.createPlaylist, + deleteFavorite: ssController.removeFavorite, + deletePlaylist: ndController.deletePlaylist, + getAlbumArtistDetail: ndController.getAlbumArtistDetail, + getAlbumArtistList: ndController.getAlbumArtistList, + getAlbumDetail: ndController.getAlbumDetail, + getAlbumList: ndController.getAlbumList, + getArtistDetail: undefined, + getArtistInfo: undefined, + getArtistList: undefined, + getFavoritesList: undefined, + getFolderItemList: undefined, + getFolderList: undefined, + getFolderSongs: undefined, + getGenreList: ndController.getGenreList, + getLyrics: undefined, + getMusicFolderList: ssController.getMusicFolderList, + getPlaylistDetail: ndController.getPlaylistDetail, + getPlaylistList: ndController.getPlaylistList, + getPlaylistSongList: ndController.getPlaylistSongList, + getRandomSongList: ssController.getRandomSongList, + getSongDetail: ndController.getSongDetail, + getSongList: ndController.getSongList, + getTopSongs: ssController.getTopSongList, + getUserList: ndController.getUserList, + removeFromPlaylist: ndController.removeFromPlaylist, + scrobble: ssController.scrobble, + search: ssController.search3, + setRating: ssController.setRating, + updatePlaylist: ndController.updatePlaylist, + }, + subsonic: { + authenticate: ssController.authenticate, + clearPlaylist: undefined, + createFavorite: ssController.createFavorite, + createPlaylist: undefined, + deleteFavorite: ssController.removeFavorite, + deletePlaylist: undefined, + getAlbumArtistDetail: undefined, + getAlbumArtistList: undefined, + getAlbumDetail: undefined, + getAlbumList: undefined, + getArtistDetail: undefined, + getArtistInfo: undefined, + getArtistList: undefined, + getFavoritesList: undefined, + getFolderItemList: undefined, + getFolderList: undefined, + getFolderSongs: undefined, + getGenreList: undefined, + getLyrics: undefined, + getMusicFolderList: ssController.getMusicFolderList, + getPlaylistDetail: undefined, + getPlaylistList: undefined, + getSongDetail: undefined, + getSongList: undefined, + getTopSongs: ssController.getTopSongList, + getUserList: undefined, + scrobble: ssController.scrobble, + search: ssController.search3, + setRating: undefined, + updatePlaylist: undefined, + }, }; const apiController = (endpoint: keyof ControllerEndpoint, type?: ServerType) => { - const serverType = type || useAuthStore.getState().currentServer?.type; + const serverType = type || useAuthStore.getState().currentServer?.type; - if (!serverType) { - toast.error({ message: 'No server selected', title: 'Unable to route request' }); - throw new Error(`No server selected`); - } + if (!serverType) { + toast.error({ message: 'No server selected', title: 'Unable to route request' }); + throw new Error(`No server selected`); + } - const controllerFn = endpoints?.[serverType]?.[endpoint]; + const controllerFn = endpoints?.[serverType]?.[endpoint]; - if (typeof controllerFn !== 'function') { - toast.error({ - message: `Endpoint ${endpoint} is not implemented for ${serverType}`, - title: 'Unable to route request', - }); + if (typeof controllerFn !== 'function') { + toast.error({ + message: `Endpoint ${endpoint} is not implemented for ${serverType}`, + title: 'Unable to route request', + }); - throw new Error(`Endpoint ${endpoint} is not implemented for ${serverType}`); - } + throw new Error(`Endpoint ${endpoint} is not implemented for ${serverType}`); + } - return endpoints[serverType][endpoint]; + return endpoints[serverType][endpoint]; }; const authenticate = async ( - url: string, - body: { legacy?: boolean; password: string; username: string }, - type: ServerType, + url: string, + body: { legacy?: boolean; password: string; username: string }, + type: ServerType, ) => { - return (apiController('authenticate', type) as ControllerEndpoint['authenticate'])?.(url, body); + return (apiController('authenticate', type) as ControllerEndpoint['authenticate'])?.(url, body); }; const getAlbumList = async (args: AlbumListArgs) => { - return ( - apiController( - 'getAlbumList', - args.apiClientProps.server?.type, - ) as ControllerEndpoint['getAlbumList'] - )?.(args); + return ( + apiController( + 'getAlbumList', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['getAlbumList'] + )?.(args); }; const getAlbumDetail = async (args: AlbumDetailArgs) => { - return ( - apiController( - 'getAlbumDetail', - args.apiClientProps.server?.type, - ) as ControllerEndpoint['getAlbumDetail'] - )?.(args); + return ( + apiController( + 'getAlbumDetail', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['getAlbumDetail'] + )?.(args); }; const getSongList = async (args: SongListArgs) => { - return ( - apiController( - 'getSongList', - args.apiClientProps.server?.type, - ) as ControllerEndpoint['getSongList'] - )?.(args); + return ( + apiController( + 'getSongList', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['getSongList'] + )?.(args); }; const getSongDetail = async (args: SongDetailArgs) => { - return ( - apiController( - 'getSongDetail', - args.apiClientProps.server?.type, - ) as ControllerEndpoint['getSongDetail'] - )?.(args); + return ( + apiController( + 'getSongDetail', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['getSongDetail'] + )?.(args); }; const getMusicFolderList = async (args: MusicFolderListArgs) => { - return ( - apiController( - 'getMusicFolderList', - args.apiClientProps.server?.type, - ) as ControllerEndpoint['getMusicFolderList'] - )?.(args); + return ( + apiController( + 'getMusicFolderList', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['getMusicFolderList'] + )?.(args); }; const getGenreList = async (args: GenreListArgs) => { - return ( - apiController( - 'getGenreList', - args.apiClientProps.server?.type, - ) as ControllerEndpoint['getGenreList'] - )?.(args); + return ( + apiController( + 'getGenreList', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['getGenreList'] + )?.(args); }; const getAlbumArtistDetail = async (args: AlbumArtistDetailArgs) => { - return ( - apiController( - 'getAlbumArtistDetail', - args.apiClientProps.server?.type, - ) as ControllerEndpoint['getAlbumArtistDetail'] - )?.(args); + return ( + apiController( + 'getAlbumArtistDetail', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['getAlbumArtistDetail'] + )?.(args); }; const getAlbumArtistList = async (args: AlbumArtistListArgs) => { - return ( - apiController( - 'getAlbumArtistList', - args.apiClientProps.server?.type, - ) as ControllerEndpoint['getAlbumArtistList'] - )?.(args); + return ( + apiController( + 'getAlbumArtistList', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['getAlbumArtistList'] + )?.(args); }; const getArtistList = async (args: ArtistListArgs) => { - return ( - apiController( - 'getArtistList', - args.apiClientProps.server?.type, - ) as ControllerEndpoint['getArtistList'] - )?.(args); + return ( + apiController( + 'getArtistList', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['getArtistList'] + )?.(args); }; const getPlaylistList = async (args: PlaylistListArgs) => { - return ( - apiController( - 'getPlaylistList', - args.apiClientProps.server?.type, - ) as ControllerEndpoint['getPlaylistList'] - )?.(args); + return ( + apiController( + 'getPlaylistList', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['getPlaylistList'] + )?.(args); }; const createPlaylist = async (args: CreatePlaylistArgs) => { - return ( - apiController( - 'createPlaylist', - args.apiClientProps.server?.type, - ) as ControllerEndpoint['createPlaylist'] - )?.(args); + return ( + apiController( + 'createPlaylist', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['createPlaylist'] + )?.(args); }; const updatePlaylist = async (args: UpdatePlaylistArgs) => { - return ( - apiController( - 'updatePlaylist', - args.apiClientProps.server?.type, - ) as ControllerEndpoint['updatePlaylist'] - )?.(args); + return ( + apiController( + 'updatePlaylist', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['updatePlaylist'] + )?.(args); }; const deletePlaylist = async (args: DeletePlaylistArgs) => { - return ( - apiController( - 'deletePlaylist', - args.apiClientProps.server?.type, - ) as ControllerEndpoint['deletePlaylist'] - )?.(args); + return ( + apiController( + 'deletePlaylist', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['deletePlaylist'] + )?.(args); }; const addToPlaylist = async (args: AddToPlaylistArgs) => { - return ( - apiController( - 'addToPlaylist', - args.apiClientProps.server?.type, - ) as ControllerEndpoint['addToPlaylist'] - )?.(args); + return ( + apiController( + 'addToPlaylist', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['addToPlaylist'] + )?.(args); }; const removeFromPlaylist = async (args: RemoveFromPlaylistArgs) => { - return ( - apiController( - 'removeFromPlaylist', - args.apiClientProps.server?.type, - ) as ControllerEndpoint['removeFromPlaylist'] - )?.(args); + return ( + apiController( + 'removeFromPlaylist', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['removeFromPlaylist'] + )?.(args); }; const getPlaylistDetail = async (args: PlaylistDetailArgs) => { - return ( - apiController( - 'getPlaylistDetail', - args.apiClientProps.server?.type, - ) as ControllerEndpoint['getPlaylistDetail'] - )?.(args); + return ( + apiController( + 'getPlaylistDetail', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['getPlaylistDetail'] + )?.(args); }; const getPlaylistSongList = async (args: PlaylistSongListArgs) => { - return ( - apiController( - 'getPlaylistSongList', - args.apiClientProps.server?.type, - ) as ControllerEndpoint['getPlaylistSongList'] - )?.(args); + return ( + apiController( + 'getPlaylistSongList', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['getPlaylistSongList'] + )?.(args); }; const getUserList = async (args: UserListArgs) => { - return ( - apiController( - 'getUserList', - args.apiClientProps.server?.type, - ) as ControllerEndpoint['getUserList'] - )?.(args); + return ( + apiController( + 'getUserList', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['getUserList'] + )?.(args); }; const createFavorite = async (args: FavoriteArgs) => { - return ( - apiController( - 'createFavorite', - args.apiClientProps.server?.type, - ) as ControllerEndpoint['createFavorite'] - )?.(args); + return ( + apiController( + 'createFavorite', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['createFavorite'] + )?.(args); }; const deleteFavorite = async (args: FavoriteArgs) => { - return ( - apiController( - 'deleteFavorite', - args.apiClientProps.server?.type, - ) as ControllerEndpoint['deleteFavorite'] - )?.(args); + return ( + apiController( + 'deleteFavorite', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['deleteFavorite'] + )?.(args); }; const updateRating = async (args: SetRatingArgs) => { - return ( - apiController('setRating', args.apiClientProps.server?.type) as ControllerEndpoint['setRating'] - )?.(args); + return ( + apiController( + 'setRating', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['setRating'] + )?.(args); }; const getTopSongList = async (args: TopSongListArgs) => { - return ( - apiController( - 'getTopSongs', - args.apiClientProps.server?.type, - ) as ControllerEndpoint['getTopSongs'] - )?.(args); + return ( + apiController( + 'getTopSongs', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['getTopSongs'] + )?.(args); }; const scrobble = async (args: ScrobbleArgs) => { - return ( - apiController('scrobble', args.apiClientProps.server?.type) as ControllerEndpoint['scrobble'] - )?.(args); + return ( + apiController( + 'scrobble', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['scrobble'] + )?.(args); }; const search = async (args: SearchArgs) => { - return ( - apiController('search', args.apiClientProps.server?.type) as ControllerEndpoint['search'] - )?.(args); + return ( + apiController('search', args.apiClientProps.server?.type) as ControllerEndpoint['search'] + )?.(args); }; const getRandomSongList = async (args: RandomSongListArgs) => { - return ( - apiController( - 'getRandomSongList', - args.apiClientProps.server?.type, - ) as ControllerEndpoint['getRandomSongList'] - )?.(args); + return ( + apiController( + 'getRandomSongList', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['getRandomSongList'] + )?.(args); }; const getLyrics = async (args: LyricsArgs) => { - return ( - apiController('getLyrics', args.apiClientProps.server?.type) as ControllerEndpoint['getLyrics'] - )?.(args); + return ( + apiController( + 'getLyrics', + args.apiClientProps.server?.type, + ) as ControllerEndpoint['getLyrics'] + )?.(args); }; export const controller = { - addToPlaylist, - authenticate, - createFavorite, - createPlaylist, - deleteFavorite, - deletePlaylist, - getAlbumArtistDetail, - getAlbumArtistList, - getAlbumDetail, - getAlbumList, - getArtistList, - getGenreList, - getLyrics, - getMusicFolderList, - getPlaylistDetail, - getPlaylistList, - getPlaylistSongList, - getRandomSongList, - getSongDetail, - getSongList, - getTopSongList, - getUserList, - removeFromPlaylist, - scrobble, - search, - updatePlaylist, - updateRating, + addToPlaylist, + authenticate, + createFavorite, + createPlaylist, + deleteFavorite, + deletePlaylist, + getAlbumArtistDetail, + getAlbumArtistList, + getAlbumDetail, + getAlbumList, + getArtistList, + getGenreList, + getLyrics, + getMusicFolderList, + getPlaylistDetail, + getPlaylistList, + getPlaylistSongList, + getRandomSongList, + getSongDetail, + getSongList, + getTopSongList, + getUserList, + removeFromPlaylist, + scrobble, + search, + updatePlaylist, + updateRating, }; diff --git a/src/renderer/api/index.ts b/src/renderer/api/index.ts index c2d6bfde..93f68c94 100644 --- a/src/renderer/api/index.ts +++ b/src/renderer/api/index.ts @@ -1,5 +1,5 @@ import { controller } from '/@/renderer/api/controller'; export const api = { - controller, + controller, }; diff --git a/src/renderer/api/jellyfin.types.ts b/src/renderer/api/jellyfin.types.ts index e58d13f0..c1a57fac 100644 --- a/src/renderer/api/jellyfin.types.ts +++ b/src/renderer/api/jellyfin.types.ts @@ -1,16 +1,16 @@ export type JFBasePaginatedResponse = { - StartIndex: number; - TotalRecordCount: number; + StartIndex: number; + TotalRecordCount: number; }; export interface JFMusicFolderListResponse extends JFBasePaginatedResponse { - Items: JFMusicFolder[]; + Items: JFMusicFolder[]; } export type JFMusicFolderList = JFMusicFolder[]; export interface JFGenreListResponse extends JFBasePaginatedResponse { - Items: JFGenre[]; + Items: JFGenre[]; } export type JFGenreList = JFGenreListResponse; @@ -20,29 +20,29 @@ export type JFAlbumArtistDetailResponse = JFAlbumArtist; export type JFAlbumArtistDetail = JFAlbumArtistDetailResponse; export interface JFAlbumArtistListResponse extends JFBasePaginatedResponse { - Items: JFAlbumArtist[]; + Items: JFAlbumArtist[]; } export type JFAlbumArtistList = { - items: JFAlbumArtist[]; - startIndex: number; - totalRecordCount: number; + items: JFAlbumArtist[]; + startIndex: number; + totalRecordCount: number; }; export interface JFArtistListResponse extends JFBasePaginatedResponse { - Items: JFAlbumArtist[]; + Items: JFAlbumArtist[]; } export type JFArtistList = JFArtistListResponse; export interface JFAlbumListResponse extends JFBasePaginatedResponse { - Items: JFAlbum[]; + Items: JFAlbum[]; } export type JFAlbumList = { - items: JFAlbum[]; - startIndex: number; - totalRecordCount: number; + items: JFAlbum[]; + startIndex: number; + totalRecordCount: number; }; export type JFAlbumDetailResponse = JFAlbum; @@ -50,22 +50,22 @@ export type JFAlbumDetailResponse = JFAlbum; export type JFAlbumDetail = JFAlbum & { songs?: JFSong[] }; export interface JFSongListResponse extends JFBasePaginatedResponse { - Items: JFSong[]; + Items: JFSong[]; } export type JFSongList = { - items: JFSong[]; - startIndex: number; - totalRecordCount: number; + items: JFSong[]; + startIndex: number; + totalRecordCount: number; }; export type JFAddToPlaylistResponse = { - added: number; + added: number; }; export type JFAddToPlaylistParams = { - ids: string[]; - userId: string; + ids: string[]; + userId: string; }; export type JFAddToPlaylist = null; @@ -73,27 +73,27 @@ export type JFAddToPlaylist = null; export type JFRemoveFromPlaylistResponse = null; export type JFRemoveFromPlaylistParams = { - entryIds: string[]; + entryIds: string[]; }; export type JFRemoveFromPlaylist = null; export interface JFPlaylistListResponse extends JFBasePaginatedResponse { - Items: JFPlaylist[]; + Items: JFPlaylist[]; } export type JFPlaylistList = { - items: JFPlaylist[]; - startIndex: number; - totalRecordCount: number; + items: JFPlaylist[]; + startIndex: number; + totalRecordCount: number; }; export enum JFPlaylistListSort { - ALBUM_ARTIST = 'AlbumArtist,SortName', - DURATION = 'Runtime', - NAME = 'SortName', - RECENTLY_ADDED = 'DateCreated,SortName', - SONG_COUNT = 'ChildCount', + ALBUM_ARTIST = 'AlbumArtist,SortName', + DURATION = 'Runtime', + NAME = 'SortName', + RECENTLY_ADDED = 'DateCreated,SortName', + SONG_COUNT = 'ChildCount', } export type JFPlaylistDetailResponse = JFPlaylist; @@ -101,534 +101,534 @@ export type JFPlaylistDetailResponse = JFPlaylist; export type JFPlaylistDetail = JFPlaylist & { songs?: JFSong[] }; export type JFPlaylist = { - BackdropImageTags: string[]; - ChannelId: null; - ChildCount?: number; - DateCreated: string; - GenreItems: GenreItem[]; - Genres: string[]; - Id: string; - ImageBlurHashes: ImageBlurHashes; - ImageTags: ImageTags; - IsFolder: boolean; - LocationType: string; - MediaType: string; - Name: string; - Overview?: string; - RunTimeTicks: number; - ServerId: string; - Type: string; - UserData: UserData; + BackdropImageTags: string[]; + ChannelId: null; + ChildCount?: number; + DateCreated: string; + GenreItems: GenreItem[]; + Genres: string[]; + Id: string; + ImageBlurHashes: ImageBlurHashes; + ImageTags: ImageTags; + IsFolder: boolean; + LocationType: string; + MediaType: string; + Name: string; + Overview?: string; + RunTimeTicks: number; + ServerId: string; + Type: string; + UserData: UserData; }; export type JFRequestParams = { - albumArtistIds?: string; - artistIds?: string; - enableImageTypes?: string; - enableTotalRecordCount?: boolean; - enableUserData?: boolean; - excludeItemTypes?: string; - fields?: string; - imageTypeLimit?: number; - includeItemTypes?: string; - isFavorite?: boolean; - limit?: number; - parentId?: string; - recursive?: boolean; - searchTerm?: string; - sortBy?: string; - sortOrder?: 'Ascending' | 'Descending'; - startIndex?: number; - userId?: string; + albumArtistIds?: string; + artistIds?: string; + enableImageTypes?: string; + enableTotalRecordCount?: boolean; + enableUserData?: boolean; + excludeItemTypes?: string; + fields?: string; + imageTypeLimit?: number; + includeItemTypes?: string; + isFavorite?: boolean; + limit?: number; + parentId?: string; + recursive?: boolean; + searchTerm?: string; + sortBy?: string; + sortOrder?: 'Ascending' | 'Descending'; + startIndex?: number; + userId?: string; }; export type JFMusicFolder = { - BackdropImageTags: string[]; - ChannelId: null; - CollectionType: string; - Id: string; - ImageBlurHashes: ImageBlurHashes; - ImageTags: ImageTags; - IsFolder: boolean; - LocationType: string; - Name: string; - ServerId: string; - Type: string; - UserData: UserData; + BackdropImageTags: string[]; + ChannelId: null; + CollectionType: string; + Id: string; + ImageBlurHashes: ImageBlurHashes; + ImageTags: ImageTags; + IsFolder: boolean; + LocationType: string; + Name: string; + ServerId: string; + Type: string; + UserData: UserData; }; export type JFGenre = { - BackdropImageTags: any[]; - ChannelId: null; - Id: string; - ImageBlurHashes: any; - ImageTags: ImageTags; - LocationType: string; - Name: string; - ServerId: string; - Type: string; + BackdropImageTags: any[]; + ChannelId: null; + Id: string; + ImageBlurHashes: any; + ImageTags: ImageTags; + LocationType: string; + Name: string; + ServerId: string; + Type: string; }; export type JFAlbumArtist = { - BackdropImageTags: string[]; - ChannelId: null; - DateCreated: string; - ExternalUrls: ExternalURL[]; - GenreItems: GenreItem[]; - Genres: string[]; - Id: string; - ImageBlurHashes: any; - ImageTags: ImageTags; - LocationType: string; - Name: string; - Overview?: string; - RunTimeTicks: number; - ServerId: string; - Type: string; - UserData: { + BackdropImageTags: string[]; + ChannelId: null; + DateCreated: string; + ExternalUrls: ExternalURL[]; + GenreItems: GenreItem[]; + Genres: string[]; + Id: string; + ImageBlurHashes: any; + ImageTags: ImageTags; + LocationType: string; + Name: string; + Overview?: string; + RunTimeTicks: number; + ServerId: string; + Type: string; + UserData: { + IsFavorite: boolean; + Key: string; + PlayCount: number; + PlaybackPositionTicks: number; + Played: boolean; + }; +} & { + similarArtists: { + items: JFAlbumArtist[]; + }; +}; + +export type JFArtist = { + BackdropImageTags: string[]; + ChannelId: null; + DateCreated: string; + ExternalUrls: ExternalURL[]; + GenreItems: GenreItem[]; + Genres: string[]; + Id: string; + ImageBlurHashes: any; + ImageTags: string[]; + LocationType: string; + Name: string; + Overview?: string; + RunTimeTicks: number; + ServerId: string; + Type: string; +}; + +export type JFAlbum = { + AlbumArtist: string; + AlbumArtists: JFGenericItem[]; + AlbumPrimaryImageTag: string; + ArtistItems: JFGenericItem[]; + Artists: string[]; + ChannelId: null; + ChildCount?: number; + DateCreated: string; + DateLastMediaAdded?: string; + ExternalUrls: ExternalURL[]; + GenreItems: JFGenericItem[]; + Genres: string[]; + Id: string; + ImageBlurHashes: ImageBlurHashes; + ImageTags: ImageTags; + IsFolder: boolean; + LocationType: string; + Name: string; + ParentLogoImageTag: string; + ParentLogoItemId: string; + PremiereDate?: string; + ProductionYear: number; + RunTimeTicks: number; + ServerId: string; + Type: string; + UserData?: UserData; +} & { + songs?: JFSong[]; +}; + +export type JFSong = { + Album: string; + AlbumArtist: string; + AlbumArtists: JFGenericItem[]; + AlbumId: string; + AlbumPrimaryImageTag: string; + ArtistItems: JFGenericItem[]; + Artists: string[]; + BackdropImageTags: string[]; + ChannelId: null; + DateCreated: string; + ExternalUrls: ExternalURL[]; + GenreItems: JFGenericItem[]; + Genres: string[]; + Id: string; + ImageBlurHashes: ImageBlurHashes; + ImageTags: ImageTags; + IndexNumber: number; + IsFolder: boolean; + LocationType: string; + MediaSources: MediaSources[]; + MediaType: string; + Name: string; + ParentIndexNumber: number; + PlaylistItemId?: string; + PremiereDate?: string; + ProductionYear: number; + RunTimeTicks: number; + ServerId: string; + SortName: string; + Type: string; + UserData?: UserData; +}; + +type ImageBlurHashes = { + Backdrop?: any; + Logo?: any; + Primary?: any; +}; + +type ImageTags = { + Logo?: string; + Primary?: string; +}; + +type UserData = { IsFavorite: boolean; Key: string; PlayCount: number; PlaybackPositionTicks: number; Played: boolean; - }; -} & { - similarArtists: { - items: JFAlbumArtist[]; - }; -}; - -export type JFArtist = { - BackdropImageTags: string[]; - ChannelId: null; - DateCreated: string; - ExternalUrls: ExternalURL[]; - GenreItems: GenreItem[]; - Genres: string[]; - Id: string; - ImageBlurHashes: any; - ImageTags: string[]; - LocationType: string; - Name: string; - Overview?: string; - RunTimeTicks: number; - ServerId: string; - Type: string; -}; - -export type JFAlbum = { - AlbumArtist: string; - AlbumArtists: JFGenericItem[]; - AlbumPrimaryImageTag: string; - ArtistItems: JFGenericItem[]; - Artists: string[]; - ChannelId: null; - ChildCount?: number; - DateCreated: string; - DateLastMediaAdded?: string; - ExternalUrls: ExternalURL[]; - GenreItems: JFGenericItem[]; - Genres: string[]; - Id: string; - ImageBlurHashes: ImageBlurHashes; - ImageTags: ImageTags; - IsFolder: boolean; - LocationType: string; - Name: string; - ParentLogoImageTag: string; - ParentLogoItemId: string; - PremiereDate?: string; - ProductionYear: number; - RunTimeTicks: number; - ServerId: string; - Type: string; - UserData?: UserData; -} & { - songs?: JFSong[]; -}; - -export type JFSong = { - Album: string; - AlbumArtist: string; - AlbumArtists: JFGenericItem[]; - AlbumId: string; - AlbumPrimaryImageTag: string; - ArtistItems: JFGenericItem[]; - Artists: string[]; - BackdropImageTags: string[]; - ChannelId: null; - DateCreated: string; - ExternalUrls: ExternalURL[]; - GenreItems: JFGenericItem[]; - Genres: string[]; - Id: string; - ImageBlurHashes: ImageBlurHashes; - ImageTags: ImageTags; - IndexNumber: number; - IsFolder: boolean; - LocationType: string; - MediaSources: MediaSources[]; - MediaType: string; - Name: string; - ParentIndexNumber: number; - PlaylistItemId?: string; - PremiereDate?: string; - ProductionYear: number; - RunTimeTicks: number; - ServerId: string; - SortName: string; - Type: string; - UserData?: UserData; -}; - -type ImageBlurHashes = { - Backdrop?: any; - Logo?: any; - Primary?: any; -}; - -type ImageTags = { - Logo?: string; - Primary?: string; -}; - -type UserData = { - IsFavorite: boolean; - Key: string; - PlayCount: number; - PlaybackPositionTicks: number; - Played: boolean; }; type ExternalURL = { - Name: string; - Url: string; + Name: string; + Url: string; }; type GenreItem = { - Id: string; - Name: string; + Id: string; + Name: string; }; export type JFGenericItem = { - Id: string; - Name: string; + Id: string; + Name: string; }; type MediaSources = { - Bitrate: number; - Container: string; - DefaultAudioStreamIndex: number; - ETag: string; - Formats: any[]; - GenPtsInput: boolean; - Id: string; - IgnoreDts: boolean; - IgnoreIndex: boolean; - IsInfiniteStream: boolean; - IsRemote: boolean; - MediaAttachments: any[]; - MediaStreams: MediaStream[]; - Name: string; - Path: string; - Protocol: string; - ReadAtNativeFramerate: boolean; - RequiredHttpHeaders: any; - RequiresClosing: boolean; - RequiresLooping: boolean; - RequiresOpening: boolean; - RunTimeTicks: number; - Size: number; - SupportsDirectPlay: boolean; - SupportsDirectStream: boolean; - SupportsProbing: boolean; - SupportsTranscoding: boolean; - Type: string; + Bitrate: number; + Container: string; + DefaultAudioStreamIndex: number; + ETag: string; + Formats: any[]; + GenPtsInput: boolean; + Id: string; + IgnoreDts: boolean; + IgnoreIndex: boolean; + IsInfiniteStream: boolean; + IsRemote: boolean; + MediaAttachments: any[]; + MediaStreams: MediaStream[]; + Name: string; + Path: string; + Protocol: string; + ReadAtNativeFramerate: boolean; + RequiredHttpHeaders: any; + RequiresClosing: boolean; + RequiresLooping: boolean; + RequiresOpening: boolean; + RunTimeTicks: number; + Size: number; + SupportsDirectPlay: boolean; + SupportsDirectStream: boolean; + SupportsProbing: boolean; + SupportsTranscoding: boolean; + Type: string; }; type MediaStream = { - AspectRatio?: string; - BitDepth?: number; - BitRate?: number; - ChannelLayout?: string; - Channels?: number; - Codec: string; - CodecTimeBase: string; - ColorSpace?: string; - Comment?: string; - DisplayTitle?: string; - Height?: number; - Index: number; - IsDefault: boolean; - IsExternal: boolean; - IsForced: boolean; - IsInterlaced: boolean; - IsTextSubtitleStream: boolean; - Level: number; - PixelFormat?: string; - Profile?: string; - RealFrameRate?: number; - RefFrames?: number; - SampleRate?: number; - SupportsExternalStream: boolean; - TimeBase: string; - Type: string; - Width?: number; + AspectRatio?: string; + BitDepth?: number; + BitRate?: number; + ChannelLayout?: string; + Channels?: number; + Codec: string; + CodecTimeBase: string; + ColorSpace?: string; + Comment?: string; + DisplayTitle?: string; + Height?: number; + Index: number; + IsDefault: boolean; + IsExternal: boolean; + IsForced: boolean; + IsInterlaced: boolean; + IsTextSubtitleStream: boolean; + Level: number; + PixelFormat?: string; + Profile?: string; + RealFrameRate?: number; + RefFrames?: number; + SampleRate?: number; + SupportsExternalStream: boolean; + TimeBase: string; + Type: string; + Width?: number; }; export enum JFExternalType { - MUSICBRAINZ = 'MusicBrainz', - THEAUDIODB = 'TheAudioDb', + MUSICBRAINZ = 'MusicBrainz', + THEAUDIODB = 'TheAudioDb', } export enum JFImageType { - LOGO = 'Logo', - PRIMARY = 'Primary', + LOGO = 'Logo', + PRIMARY = 'Primary', } export enum JFItemType { - AUDIO = 'Audio', - MUSICALBUM = 'MusicAlbum', + AUDIO = 'Audio', + MUSICALBUM = 'MusicAlbum', } export enum JFCollectionType { - MUSIC = 'music', - PLAYLISTS = 'playlists', + MUSIC = 'music', + PLAYLISTS = 'playlists', } export interface JFAuthenticate { - AccessToken: string; - ServerId: string; - SessionInfo: SessionInfo; - User: User; + AccessToken: string; + ServerId: string; + SessionInfo: SessionInfo; + User: User; } type SessionInfo = { - AdditionalUsers: any[]; - ApplicationVersion: string; - Capabilities: Capabilities; - Client: string; - DeviceId: string; - DeviceName: string; - HasCustomDeviceName: boolean; - Id: string; - IsActive: boolean; - LastActivityDate: string; - LastPlaybackCheckIn: string; - NowPlayingQueue: any[]; - NowPlayingQueueFullItems: any[]; - PlayState: PlayState; - PlayableMediaTypes: any[]; - RemoteEndPoint: string; - ServerId: string; - SupportedCommands: any[]; - SupportsMediaControl: boolean; - SupportsRemoteControl: boolean; - UserId: string; - UserName: string; + AdditionalUsers: any[]; + ApplicationVersion: string; + Capabilities: Capabilities; + Client: string; + DeviceId: string; + DeviceName: string; + HasCustomDeviceName: boolean; + Id: string; + IsActive: boolean; + LastActivityDate: string; + LastPlaybackCheckIn: string; + NowPlayingQueue: any[]; + NowPlayingQueueFullItems: any[]; + PlayState: PlayState; + PlayableMediaTypes: any[]; + RemoteEndPoint: string; + ServerId: string; + SupportedCommands: any[]; + SupportsMediaControl: boolean; + SupportsRemoteControl: boolean; + UserId: string; + UserName: string; }; type Capabilities = { - PlayableMediaTypes: any[]; - SupportedCommands: any[]; - SupportsContentUploading: boolean; - SupportsMediaControl: boolean; - SupportsPersistentIdentifier: boolean; - SupportsSync: boolean; + PlayableMediaTypes: any[]; + SupportedCommands: any[]; + SupportsContentUploading: boolean; + SupportsMediaControl: boolean; + SupportsPersistentIdentifier: boolean; + SupportsSync: boolean; }; type PlayState = { - CanSeek: boolean; - IsMuted: boolean; - IsPaused: boolean; - RepeatMode: string; + CanSeek: boolean; + IsMuted: boolean; + IsPaused: boolean; + RepeatMode: string; }; type User = { - Configuration: Configuration; - EnableAutoLogin: boolean; - HasConfiguredEasyPassword: boolean; - HasConfiguredPassword: boolean; - HasPassword: boolean; - Id: string; - LastActivityDate: string; - LastLoginDate: string; - Name: string; - Policy: Policy; - ServerId: string; + Configuration: Configuration; + EnableAutoLogin: boolean; + HasConfiguredEasyPassword: boolean; + HasConfiguredPassword: boolean; + HasPassword: boolean; + Id: string; + LastActivityDate: string; + LastLoginDate: string; + Name: string; + Policy: Policy; + ServerId: string; }; type Configuration = { - DisplayCollectionsView: boolean; - DisplayMissingEpisodes: boolean; - EnableLocalPassword: boolean; - EnableNextEpisodeAutoPlay: boolean; - GroupedFolders: any[]; - HidePlayedInLatest: boolean; - LatestItemsExcludes: any[]; - MyMediaExcludes: any[]; - OrderedViews: any[]; - PlayDefaultAudioTrack: boolean; - RememberAudioSelections: boolean; - RememberSubtitleSelections: boolean; - SubtitleLanguagePreference: string; - SubtitleMode: string; + DisplayCollectionsView: boolean; + DisplayMissingEpisodes: boolean; + EnableLocalPassword: boolean; + EnableNextEpisodeAutoPlay: boolean; + GroupedFolders: any[]; + HidePlayedInLatest: boolean; + LatestItemsExcludes: any[]; + MyMediaExcludes: any[]; + OrderedViews: any[]; + PlayDefaultAudioTrack: boolean; + RememberAudioSelections: boolean; + RememberSubtitleSelections: boolean; + SubtitleLanguagePreference: string; + SubtitleMode: string; }; type Policy = { - AccessSchedules: any[]; - AuthenticationProviderId: string; - BlockUnratedItems: any[]; - BlockedChannels: any[]; - BlockedMediaFolders: any[]; - BlockedTags: any[]; - EnableAllChannels: boolean; - EnableAllDevices: boolean; - EnableAllFolders: boolean; - EnableAudioPlaybackTranscoding: boolean; - EnableContentDeletion: boolean; - EnableContentDeletionFromFolders: any[]; - EnableContentDownloading: boolean; - EnableLiveTvAccess: boolean; - EnableLiveTvManagement: boolean; - EnableMediaConversion: boolean; - EnableMediaPlayback: boolean; - EnablePlaybackRemuxing: boolean; - EnablePublicSharing: boolean; - EnableRemoteAccess: boolean; - EnableRemoteControlOfOtherUsers: boolean; - EnableSharedDeviceControl: boolean; - EnableSyncTranscoding: boolean; - EnableUserPreferenceAccess: boolean; - EnableVideoPlaybackTranscoding: boolean; - EnabledChannels: any[]; - EnabledDevices: any[]; - EnabledFolders: any[]; - ForceRemoteSourceTranscoding: boolean; - InvalidLoginAttemptCount: number; - IsAdministrator: boolean; - IsDisabled: boolean; - IsHidden: boolean; - LoginAttemptsBeforeLockout: number; - MaxActiveSessions: number; - PasswordResetProviderId: string; - RemoteClientBitrateLimit: number; - SyncPlayAccess: string; + AccessSchedules: any[]; + AuthenticationProviderId: string; + BlockUnratedItems: any[]; + BlockedChannels: any[]; + BlockedMediaFolders: any[]; + BlockedTags: any[]; + EnableAllChannels: boolean; + EnableAllDevices: boolean; + EnableAllFolders: boolean; + EnableAudioPlaybackTranscoding: boolean; + EnableContentDeletion: boolean; + EnableContentDeletionFromFolders: any[]; + EnableContentDownloading: boolean; + EnableLiveTvAccess: boolean; + EnableLiveTvManagement: boolean; + EnableMediaConversion: boolean; + EnableMediaPlayback: boolean; + EnablePlaybackRemuxing: boolean; + EnablePublicSharing: boolean; + EnableRemoteAccess: boolean; + EnableRemoteControlOfOtherUsers: boolean; + EnableSharedDeviceControl: boolean; + EnableSyncTranscoding: boolean; + EnableUserPreferenceAccess: boolean; + EnableVideoPlaybackTranscoding: boolean; + EnabledChannels: any[]; + EnabledDevices: any[]; + EnabledFolders: any[]; + ForceRemoteSourceTranscoding: boolean; + InvalidLoginAttemptCount: number; + IsAdministrator: boolean; + IsDisabled: boolean; + IsHidden: boolean; + LoginAttemptsBeforeLockout: number; + MaxActiveSessions: number; + PasswordResetProviderId: string; + RemoteClientBitrateLimit: number; + SyncPlayAccess: string; }; type JFBaseParams = { - enableImageTypes?: JFImageType[]; - fields?: string; - imageTypeLimit?: number; - parentId?: string; - recursive?: boolean; - searchTerm?: string; - userId?: string; + enableImageTypes?: JFImageType[]; + fields?: string; + imageTypeLimit?: number; + parentId?: string; + recursive?: boolean; + searchTerm?: string; + userId?: string; }; type JFPaginationParams = { - limit?: number; - nameStartsWith?: string; - sortOrder?: JFSortOrder; - startIndex?: number; + limit?: number; + nameStartsWith?: string; + sortOrder?: JFSortOrder; + startIndex?: number; }; export enum JFSortOrder { - ASC = 'Ascending', - DESC = 'Descending', + ASC = 'Ascending', + DESC = 'Descending', } export enum JFAlbumListSort { - ALBUM_ARTIST = 'AlbumArtist,SortName', - COMMUNITY_RATING = 'CommunityRating,SortName', - CRITIC_RATING = 'CriticRating,SortName', - NAME = 'SortName', - RANDOM = 'Random,SortName', - RECENTLY_ADDED = 'DateCreated,SortName', - RELEASE_DATE = 'ProductionYear,PremiereDate,SortName', + ALBUM_ARTIST = 'AlbumArtist,SortName', + COMMUNITY_RATING = 'CommunityRating,SortName', + CRITIC_RATING = 'CriticRating,SortName', + NAME = 'SortName', + RANDOM = 'Random,SortName', + RECENTLY_ADDED = 'DateCreated,SortName', + RELEASE_DATE = 'ProductionYear,PremiereDate,SortName', } export type JFAlbumListParams = { - albumArtistIds?: string; - artistIds?: string; - filters?: string; - genreIds?: string; - genres?: string; - includeItemTypes: 'MusicAlbum'; - isFavorite?: boolean; - searchTerm?: string; - sortBy?: JFAlbumListSort; - tags?: string; - years?: string; + albumArtistIds?: string; + artistIds?: string; + filters?: string; + genreIds?: string; + genres?: string; + includeItemTypes: 'MusicAlbum'; + isFavorite?: boolean; + searchTerm?: string; + sortBy?: JFAlbumListSort; + tags?: string; + years?: string; } & JFBaseParams & - JFPaginationParams; + JFPaginationParams; export enum JFSongListSort { - ALBUM = 'Album,SortName', - ALBUM_ARTIST = 'AlbumArtist,Album,SortName', - ARTIST = 'Artist,Album,SortName', - COMMUNITY_RATING = 'CommunityRating,SortName', - DURATION = 'Runtime,AlbumArtist,Album,SortName', - NAME = 'Name,SortName', - PLAY_COUNT = 'PlayCount,SortName', - RANDOM = 'Random,SortName', - RECENTLY_ADDED = 'DateCreated,SortName', - RECENTLY_PLAYED = 'DatePlayed,SortName', - RELEASE_DATE = 'PremiereDate,AlbumArtist,Album,SortName', + ALBUM = 'Album,SortName', + ALBUM_ARTIST = 'AlbumArtist,Album,SortName', + ARTIST = 'Artist,Album,SortName', + COMMUNITY_RATING = 'CommunityRating,SortName', + DURATION = 'Runtime,AlbumArtist,Album,SortName', + NAME = 'Name,SortName', + PLAY_COUNT = 'PlayCount,SortName', + RANDOM = 'Random,SortName', + RECENTLY_ADDED = 'DateCreated,SortName', + RECENTLY_PLAYED = 'DatePlayed,SortName', + RELEASE_DATE = 'PremiereDate,AlbumArtist,Album,SortName', } export type JFSongListParams = { - albumArtistIds?: string; - albumIds?: string; - artistIds?: string; - contributingArtistIds?: string; - filters?: string; - genreIds?: string; - genres?: string; - ids?: string; - includeItemTypes: 'Audio'; - searchTerm?: string; - sortBy?: JFSongListSort; - years?: string; + albumArtistIds?: string; + albumIds?: string; + artistIds?: string; + contributingArtistIds?: string; + filters?: string; + genreIds?: string; + genres?: string; + ids?: string; + includeItemTypes: 'Audio'; + searchTerm?: string; + sortBy?: JFSongListSort; + years?: string; } & JFBaseParams & - JFPaginationParams; + JFPaginationParams; export enum JFAlbumArtistListSort { - ALBUM = 'Album,SortName', - DURATION = 'Runtime,AlbumArtist,Album,SortName', - NAME = 'Name,SortName', - RANDOM = 'Random,SortName', - RECENTLY_ADDED = 'DateCreated,SortName', - RELEASE_DATE = 'PremiereDate,AlbumArtist,Album,SortName', + ALBUM = 'Album,SortName', + DURATION = 'Runtime,AlbumArtist,Album,SortName', + NAME = 'Name,SortName', + RANDOM = 'Random,SortName', + RECENTLY_ADDED = 'DateCreated,SortName', + RELEASE_DATE = 'PremiereDate,AlbumArtist,Album,SortName', } export type JFAlbumArtistListParams = { - filters?: string; - genres?: string; - sortBy?: JFAlbumArtistListSort; - years?: string; + filters?: string; + genres?: string; + sortBy?: JFAlbumArtistListSort; + years?: string; } & JFBaseParams & - JFPaginationParams; + JFPaginationParams; export enum JFArtistListSort { - ALBUM = 'Album,SortName', - DURATION = 'Runtime,AlbumArtist,Album,SortName', - NAME = 'Name,SortName', - RANDOM = 'Random,SortName', - RECENTLY_ADDED = 'DateCreated,SortName', - RELEASE_DATE = 'PremiereDate,AlbumArtist,Album,SortName', + ALBUM = 'Album,SortName', + DURATION = 'Runtime,AlbumArtist,Album,SortName', + NAME = 'Name,SortName', + RANDOM = 'Random,SortName', + RECENTLY_ADDED = 'DateCreated,SortName', + RELEASE_DATE = 'PremiereDate,AlbumArtist,Album,SortName', } export type JFArtistListParams = { - filters?: string; - genres?: string; - sortBy?: JFArtistListSort; - years?: string; + filters?: string; + genres?: string; + sortBy?: JFArtistListSort; + years?: string; } & JFBaseParams & - JFPaginationParams; + JFPaginationParams; export type JFCreatePlaylistResponse = { - Id: string; + Id: string; }; export type JFCreatePlaylist = JFCreatePlaylistResponse; diff --git a/src/renderer/api/jellyfin/jellyfin-api.ts b/src/renderer/api/jellyfin/jellyfin-api.ts index fdcbe4a5..74b8857c 100644 --- a/src/renderer/api/jellyfin/jellyfin-api.ts +++ b/src/renderer/api/jellyfin/jellyfin-api.ts @@ -11,340 +11,340 @@ import { authenticationFailure } from '/@/renderer/api/utils'; const c = initContract(); export const contract = c.router({ - addToPlaylist: { - body: z.null(), - method: 'POST', - path: 'playlists/:id/items', - query: jfType._parameters.addToPlaylist, - responses: { - 204: jfType._response.addToPlaylist, - 400: jfType._response.error, + addToPlaylist: { + body: z.null(), + method: 'POST', + path: 'playlists/:id/items', + query: jfType._parameters.addToPlaylist, + responses: { + 204: jfType._response.addToPlaylist, + 400: jfType._response.error, + }, }, - }, - authenticate: { - body: jfType._parameters.authenticate, - headers: z.object({ - 'X-Emby-Authorization': z.string(), - }), - method: 'POST', - path: 'users/authenticatebyname', - responses: { - 200: jfType._response.authenticate, - 400: jfType._response.error, + authenticate: { + body: jfType._parameters.authenticate, + headers: z.object({ + 'X-Emby-Authorization': z.string(), + }), + method: 'POST', + path: 'users/authenticatebyname', + responses: { + 200: jfType._response.authenticate, + 400: jfType._response.error, + }, }, - }, - createFavorite: { - body: jfType._parameters.favorite, - method: 'POST', - path: 'users/:userId/favoriteitems/:id', - responses: { - 200: jfType._response.favorite, - 400: jfType._response.error, + createFavorite: { + body: jfType._parameters.favorite, + method: 'POST', + path: 'users/:userId/favoriteitems/:id', + responses: { + 200: jfType._response.favorite, + 400: jfType._response.error, + }, }, - }, - createPlaylist: { - body: jfType._parameters.createPlaylist, - method: 'POST', - path: 'playlists', - responses: { - 200: jfType._response.createPlaylist, - 400: jfType._response.error, + createPlaylist: { + body: jfType._parameters.createPlaylist, + method: 'POST', + path: 'playlists', + responses: { + 200: jfType._response.createPlaylist, + 400: jfType._response.error, + }, }, - }, - deletePlaylist: { - body: null, - method: 'DELETE', - path: 'items/:id', - responses: { - 204: jfType._response.deletePlaylist, - 400: jfType._response.error, + deletePlaylist: { + body: null, + method: 'DELETE', + path: 'items/:id', + responses: { + 204: jfType._response.deletePlaylist, + 400: jfType._response.error, + }, }, - }, - getAlbumArtistDetail: { - method: 'GET', - path: 'users/:userId/items/:id', - query: jfType._parameters.albumArtistDetail, - responses: { - 200: jfType._response.albumArtist, - 400: jfType._response.error, + getAlbumArtistDetail: { + method: 'GET', + path: 'users/:userId/items/:id', + query: jfType._parameters.albumArtistDetail, + responses: { + 200: jfType._response.albumArtist, + 400: jfType._response.error, + }, }, - }, - getAlbumArtistList: { - method: 'GET', - path: 'artists/albumArtists', - query: jfType._parameters.albumArtistList, - responses: { - 200: jfType._response.albumArtistList, - 400: jfType._response.error, + getAlbumArtistList: { + method: 'GET', + path: 'artists/albumArtists', + query: jfType._parameters.albumArtistList, + responses: { + 200: jfType._response.albumArtistList, + 400: jfType._response.error, + }, }, - }, - getAlbumDetail: { - method: 'GET', - path: 'users/:userId/items/:id', - query: jfType._parameters.albumDetail, - responses: { - 200: jfType._response.album, - 400: jfType._response.error, + getAlbumDetail: { + method: 'GET', + path: 'users/:userId/items/:id', + query: jfType._parameters.albumDetail, + responses: { + 200: jfType._response.album, + 400: jfType._response.error, + }, }, - }, - getAlbumList: { - method: 'GET', - path: 'users/:userId/items', - query: jfType._parameters.albumList, - responses: { - 200: jfType._response.albumList, - 400: jfType._response.error, + getAlbumList: { + method: 'GET', + path: 'users/:userId/items', + query: jfType._parameters.albumList, + responses: { + 200: jfType._response.albumList, + 400: jfType._response.error, + }, }, - }, - getArtistList: { - method: 'GET', - path: 'artists', - query: jfType._parameters.albumArtistList, - responses: { - 200: jfType._response.albumArtistList, - 400: jfType._response.error, + getArtistList: { + method: 'GET', + path: 'artists', + query: jfType._parameters.albumArtistList, + responses: { + 200: jfType._response.albumArtistList, + 400: jfType._response.error, + }, }, - }, - getGenreList: { - method: 'GET', - path: 'genres', - responses: { - 200: jfType._response.genreList, - 400: jfType._response.error, + getGenreList: { + method: 'GET', + path: 'genres', + responses: { + 200: jfType._response.genreList, + 400: jfType._response.error, + }, }, - }, - getMusicFolderList: { - method: 'GET', - path: 'users/:userId/items', - responses: { - 200: jfType._response.musicFolderList, - 400: jfType._response.error, + getMusicFolderList: { + method: 'GET', + path: 'users/:userId/items', + responses: { + 200: jfType._response.musicFolderList, + 400: jfType._response.error, + }, }, - }, - getPlaylistDetail: { - method: 'GET', - path: 'users/:userId/items/:id', - query: jfType._parameters.playlistDetail, - responses: { - 200: jfType._response.playlist, - 400: jfType._response.error, + getPlaylistDetail: { + method: 'GET', + path: 'users/:userId/items/:id', + query: jfType._parameters.playlistDetail, + responses: { + 200: jfType._response.playlist, + 400: jfType._response.error, + }, }, - }, - getPlaylistList: { - method: 'GET', - path: 'users/:userId/items', - query: jfType._parameters.playlistList, - responses: { - 200: jfType._response.playlistList, - 400: jfType._response.error, + getPlaylistList: { + method: 'GET', + path: 'users/:userId/items', + query: jfType._parameters.playlistList, + responses: { + 200: jfType._response.playlistList, + 400: jfType._response.error, + }, }, - }, - getPlaylistSongList: { - method: 'GET', - path: 'playlists/:id/items', - query: jfType._parameters.songList, - responses: { - 200: jfType._response.playlistSongList, - 400: jfType._response.error, + getPlaylistSongList: { + method: 'GET', + path: 'playlists/:id/items', + query: jfType._parameters.songList, + responses: { + 200: jfType._response.playlistSongList, + 400: jfType._response.error, + }, }, - }, - getSimilarArtistList: { - method: 'GET', - path: 'artists/:id/similar', - query: jfType._parameters.similarArtistList, - responses: { - 200: jfType._response.albumArtistList, - 400: jfType._response.error, + getSimilarArtistList: { + method: 'GET', + path: 'artists/:id/similar', + query: jfType._parameters.similarArtistList, + responses: { + 200: jfType._response.albumArtistList, + 400: jfType._response.error, + }, }, - }, - getSongDetail: { - method: 'GET', - path: 'song/:id', - responses: { - 200: jfType._response.song, - 400: jfType._response.error, + getSongDetail: { + method: 'GET', + path: 'song/:id', + responses: { + 200: jfType._response.song, + 400: jfType._response.error, + }, }, - }, - getSongList: { - method: 'GET', - path: 'users/:userId/items', - query: jfType._parameters.songList, - responses: { - 200: jfType._response.songList, - 400: jfType._response.error, + getSongList: { + method: 'GET', + path: 'users/:userId/items', + query: jfType._parameters.songList, + responses: { + 200: jfType._response.songList, + 400: jfType._response.error, + }, }, - }, - getSongLyrics: { - method: 'GET', - path: 'users/:userId/Items/:id/Lyrics', - responses: { - 200: jfType._response.lyrics, - 404: jfType._response.error, + getSongLyrics: { + method: 'GET', + path: 'users/:userId/Items/:id/Lyrics', + responses: { + 200: jfType._response.lyrics, + 404: jfType._response.error, + }, }, - }, - getTopSongsList: { - method: 'GET', - path: 'users/:userId/items', - query: jfType._parameters.songList, - responses: { - 200: jfType._response.topSongsList, - 400: jfType._response.error, + getTopSongsList: { + method: 'GET', + path: 'users/:userId/items', + query: jfType._parameters.songList, + responses: { + 200: jfType._response.topSongsList, + 400: jfType._response.error, + }, }, - }, - removeFavorite: { - body: jfType._parameters.favorite, - method: 'DELETE', - path: 'users/:userId/favoriteitems/:id', - responses: { - 200: jfType._response.favorite, - 400: jfType._response.error, + removeFavorite: { + body: jfType._parameters.favorite, + method: 'DELETE', + path: 'users/:userId/favoriteitems/:id', + responses: { + 200: jfType._response.favorite, + 400: jfType._response.error, + }, }, - }, - removeFromPlaylist: { - body: null, - method: 'DELETE', - path: 'playlists/:id/items', - query: jfType._parameters.removeFromPlaylist, - responses: { - 200: jfType._response.removeFromPlaylist, - 400: jfType._response.error, + removeFromPlaylist: { + body: null, + method: 'DELETE', + path: 'playlists/:id/items', + query: jfType._parameters.removeFromPlaylist, + responses: { + 200: jfType._response.removeFromPlaylist, + 400: jfType._response.error, + }, }, - }, - scrobblePlaying: { - body: jfType._parameters.scrobble, - method: 'POST', - path: 'sessions/playing', - responses: { - 200: jfType._response.scrobble, - 400: jfType._response.error, + scrobblePlaying: { + body: jfType._parameters.scrobble, + method: 'POST', + path: 'sessions/playing', + responses: { + 200: jfType._response.scrobble, + 400: jfType._response.error, + }, }, - }, - scrobbleProgress: { - body: jfType._parameters.scrobble, - method: 'POST', - path: 'sessions/playing/progress', - responses: { - 200: jfType._response.scrobble, - 400: jfType._response.error, + scrobbleProgress: { + body: jfType._parameters.scrobble, + method: 'POST', + path: 'sessions/playing/progress', + responses: { + 200: jfType._response.scrobble, + 400: jfType._response.error, + }, }, - }, - scrobbleStopped: { - body: jfType._parameters.scrobble, - method: 'POST', - path: 'sessions/playing/stopped', - responses: { - 200: jfType._response.scrobble, - 400: jfType._response.error, + scrobbleStopped: { + body: jfType._parameters.scrobble, + method: 'POST', + path: 'sessions/playing/stopped', + responses: { + 200: jfType._response.scrobble, + 400: jfType._response.error, + }, }, - }, - search: { - method: 'GET', - path: 'users/:userId/items', - query: jfType._parameters.search, - responses: { - 200: jfType._response.search, - 400: jfType._response.error, + search: { + method: 'GET', + path: 'users/:userId/items', + query: jfType._parameters.search, + responses: { + 200: jfType._response.search, + 400: jfType._response.error, + }, }, - }, - updatePlaylist: { - body: jfType._parameters.updatePlaylist, - method: 'PUT', - path: 'items/:id', - responses: { - 200: jfType._response.updatePlaylist, - 400: jfType._response.error, + updatePlaylist: { + body: jfType._parameters.updatePlaylist, + method: 'PUT', + path: 'items/:id', + responses: { + 200: jfType._response.updatePlaylist, + 400: jfType._response.error, + }, }, - }, }); const axiosClient = axios.create({}); axiosClient.defaults.paramsSerializer = (params) => { - return qs.stringify(params, { arrayFormat: 'repeat' }); + return qs.stringify(params, { arrayFormat: 'repeat' }); }; axiosClient.interceptors.response.use( - (response) => { - return response; - }, - (error) => { - if (error.response && error.response.status === 401) { - const currentServer = useAuthStore.getState().currentServer; + (response) => { + return response; + }, + (error) => { + if (error.response && error.response.status === 401) { + const currentServer = useAuthStore.getState().currentServer; - authenticationFailure(currentServer); - } + authenticationFailure(currentServer); + } - return Promise.reject(error); - }, + return Promise.reject(error); + }, ); const parsePath = (fullPath: string) => { - const [path, params] = fullPath.split('?'); + const [path, params] = fullPath.split('?'); - const parsedParams = qs.parse(params); - const notNilParams = omitBy(parsedParams, (value) => value === 'undefined' || value === 'null'); + const parsedParams = qs.parse(params); + const notNilParams = omitBy(parsedParams, (value) => value === 'undefined' || value === 'null'); - return { - params: notNilParams, - path, - }; + return { + params: notNilParams, + path, + }; }; export const jfApiClient = (args: { - server: ServerListItem | null; - signal?: AbortSignal; - url?: string; + server: ServerListItem | null; + signal?: AbortSignal; + url?: string; }) => { - const { server, url, signal } = args; + const { server, url, signal } = args; - return initClient(contract, { - api: async ({ path, method, headers, body }) => { - let baseUrl: string | undefined; - let token: string | undefined; + return initClient(contract, { + api: async ({ path, method, headers, body }) => { + let baseUrl: string | undefined; + let token: string | undefined; - const { params, path: api } = parsePath(path); + const { params, path: api } = parsePath(path); - if (server) { - baseUrl = `${server?.url}`; - token = server?.credential; - } else { - baseUrl = url; - } + if (server) { + baseUrl = `${server?.url}`; + token = server?.credential; + } else { + baseUrl = url; + } - try { - const result = await axiosClient.request({ - data: body, - headers: { - ...headers, - ...(token && { 'X-MediaBrowser-Token': token }), - }, - method: method as Method, - params, - signal, - url: `${baseUrl}/${api}`, - }); - return { - body: result.data, - headers: result.headers as any, - status: result.status, - }; - } catch (e: Error | AxiosError | any) { - if (isAxiosError(e)) { - const error = e as AxiosError; - const response = error.response as AxiosResponse; - return { - body: response?.data, - headers: response?.headers as any, - status: response.status, - }; - } - throw e; - } - }, - baseHeaders: { - 'Content-Type': 'application/json', - }, - baseUrl: '', - jsonQuery: false, - }); + try { + const result = await axiosClient.request({ + data: body, + headers: { + ...headers, + ...(token && { 'X-MediaBrowser-Token': token }), + }, + method: method as Method, + params, + signal, + url: `${baseUrl}/${api}`, + }); + return { + body: result.data, + headers: result.headers as any, + status: result.status, + }; + } catch (e: Error | AxiosError | any) { + if (isAxiosError(e)) { + const error = e as AxiosError; + const response = error.response as AxiosResponse; + return { + body: response?.data, + headers: response?.headers as any, + status: response.status, + }; + } + throw e; + } + }, + baseHeaders: { + 'Content-Type': 'application/json', + }, + baseUrl: '', + jsonQuery: false, + }); }; diff --git a/src/renderer/api/jellyfin/jellyfin-controller.ts b/src/renderer/api/jellyfin/jellyfin-controller.ts index 01d85477..e1d82315 100644 --- a/src/renderer/api/jellyfin/jellyfin-controller.ts +++ b/src/renderer/api/jellyfin/jellyfin-controller.ts @@ -1,51 +1,51 @@ import { - AuthenticationResponse, - MusicFolderListArgs, - MusicFolderListResponse, - GenreListArgs, - AlbumArtistDetailArgs, - AlbumArtistListArgs, - albumArtistListSortMap, - sortOrderMap, - ArtistListArgs, - artistListSortMap, - AlbumDetailArgs, - AlbumListArgs, - albumListSortMap, - TopSongListArgs, - SongListArgs, - songListSortMap, - AddToPlaylistArgs, - RemoveFromPlaylistArgs, - PlaylistDetailArgs, - PlaylistSongListArgs, - PlaylistListArgs, - playlistListSortMap, - CreatePlaylistArgs, - CreatePlaylistResponse, - UpdatePlaylistArgs, - UpdatePlaylistResponse, - DeletePlaylistArgs, - FavoriteArgs, - FavoriteResponse, - ScrobbleArgs, - ScrobbleResponse, - GenreListResponse, - AlbumArtistDetailResponse, - AlbumArtistListResponse, - AlbumDetailResponse, - AlbumListResponse, - SongListResponse, - AddToPlaylistResponse, - RemoveFromPlaylistResponse, - PlaylistDetailResponse, - PlaylistListResponse, - SearchArgs, - SearchResponse, - RandomSongListResponse, - RandomSongListArgs, - LyricsArgs, - LyricsResponse, + AuthenticationResponse, + MusicFolderListArgs, + MusicFolderListResponse, + GenreListArgs, + AlbumArtistDetailArgs, + AlbumArtistListArgs, + albumArtistListSortMap, + sortOrderMap, + ArtistListArgs, + artistListSortMap, + AlbumDetailArgs, + AlbumListArgs, + albumListSortMap, + TopSongListArgs, + SongListArgs, + songListSortMap, + AddToPlaylistArgs, + RemoveFromPlaylistArgs, + PlaylistDetailArgs, + PlaylistSongListArgs, + PlaylistListArgs, + playlistListSortMap, + CreatePlaylistArgs, + CreatePlaylistResponse, + UpdatePlaylistArgs, + UpdatePlaylistResponse, + DeletePlaylistArgs, + FavoriteArgs, + FavoriteResponse, + ScrobbleArgs, + ScrobbleResponse, + GenreListResponse, + AlbumArtistDetailResponse, + AlbumArtistListResponse, + AlbumDetailResponse, + AlbumListResponse, + SongListResponse, + AddToPlaylistResponse, + RemoveFromPlaylistResponse, + PlaylistDetailResponse, + PlaylistListResponse, + SearchArgs, + SearchResponse, + RandomSongListResponse, + RandomSongListArgs, + LyricsArgs, + LyricsResponse, } from '/@/renderer/api/types'; import { jfApiClient } from '/@/renderer/api/jellyfin/jellyfin-api'; import { jfNormalize } from './jellyfin-normalize'; @@ -55,848 +55,854 @@ import { z } from 'zod'; import { JFSongListSort, JFSortOrder } from '/@/renderer/api/jellyfin.types'; const formatCommaDelimitedString = (value: string[]) => { - return value.join(','); + return value.join(','); }; const authenticate = async ( - url: string, - body: { - password: string; - username: string; - }, -): Promise => { - const cleanServerUrl = url.replace(/\/$/, ''); - - const res = await jfApiClient({ server: null, url: cleanServerUrl }).authenticate({ + url: string, body: { - Pw: body.password, - Username: body.username, + password: string; + username: string; }, - headers: { - 'x-emby-authorization': `MediaBrowser Client="Feishin", Device="PC", DeviceId="Feishin", Version="${packageJson.version}"`, - }, - }); +): Promise => { + const cleanServerUrl = url.replace(/\/$/, ''); - if (res.status !== 200) { - throw new Error('Failed to authenticate'); - } + const res = await jfApiClient({ server: null, url: cleanServerUrl }).authenticate({ + body: { + Pw: body.password, + Username: body.username, + }, + headers: { + 'x-emby-authorization': `MediaBrowser Client="Feishin", Device="PC", DeviceId="Feishin", Version="${packageJson.version}"`, + }, + }); - return { - credential: res.body.AccessToken, - userId: res.body.User.Id, - username: res.body.User.Name, - }; + if (res.status !== 200) { + throw new Error('Failed to authenticate'); + } + + return { + credential: res.body.AccessToken, + userId: res.body.User.Id, + username: res.body.User.Name, + }; }; const getMusicFolderList = async (args: MusicFolderListArgs): Promise => { - const { apiClientProps } = args; - const userId = apiClientProps.server?.userId; + const { apiClientProps } = args; + const userId = apiClientProps.server?.userId; - if (!userId) throw new Error('No userId found'); + if (!userId) throw new Error('No userId found'); - const res = await jfApiClient(apiClientProps).getMusicFolderList({ - params: { - userId, - }, - }); + const res = await jfApiClient(apiClientProps).getMusicFolderList({ + params: { + userId, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to get genre list'); - } + if (res.status !== 200) { + throw new Error('Failed to get genre list'); + } - const musicFolders = res.body.Items.filter( - (folder) => folder.CollectionType === jfType._enum.collection.MUSIC, - ); + const musicFolders = res.body.Items.filter( + (folder) => folder.CollectionType === jfType._enum.collection.MUSIC, + ); - return { - items: musicFolders.map(jfNormalize.musicFolder), - startIndex: 0, - totalRecordCount: musicFolders?.length || 0, - }; + return { + items: musicFolders.map(jfNormalize.musicFolder), + startIndex: 0, + totalRecordCount: musicFolders?.length || 0, + }; }; const getGenreList = async (args: GenreListArgs): Promise => { - const { apiClientProps } = args; + const { apiClientProps } = args; - const res = await jfApiClient(apiClientProps).getGenreList(); + const res = await jfApiClient(apiClientProps).getGenreList(); - if (res.status !== 200) { - throw new Error('Failed to get genre list'); - } + if (res.status !== 200) { + throw new Error('Failed to get genre list'); + } - return { - items: res.body.Items.map(jfNormalize.genre), - startIndex: 0, - totalRecordCount: res.body?.Items?.length || 0, - }; + return { + items: res.body.Items.map(jfNormalize.genre), + startIndex: 0, + totalRecordCount: res.body?.Items?.length || 0, + }; }; const getAlbumArtistDetail = async ( - args: AlbumArtistDetailArgs, + args: AlbumArtistDetailArgs, ): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - if (!apiClientProps.server?.userId) { - throw new Error('No userId found'); - } + if (!apiClientProps.server?.userId) { + throw new Error('No userId found'); + } - const res = await jfApiClient(apiClientProps).getAlbumArtistDetail({ - params: { - id: query.id, - userId: apiClientProps.server?.userId, - }, - query: { - Fields: 'Genres, Overview', - }, - }); + const res = await jfApiClient(apiClientProps).getAlbumArtistDetail({ + params: { + id: query.id, + userId: apiClientProps.server?.userId, + }, + query: { + Fields: 'Genres, Overview', + }, + }); - const similarArtistsRes = await jfApiClient(apiClientProps).getSimilarArtistList({ - params: { - id: query.id, - }, - query: { - Limit: 10, - }, - }); + const similarArtistsRes = await jfApiClient(apiClientProps).getSimilarArtistList({ + params: { + id: query.id, + }, + query: { + Limit: 10, + }, + }); - if (res.status !== 200 || similarArtistsRes.status !== 200) { - throw new Error('Failed to get album artist detail'); - } + if (res.status !== 200 || similarArtistsRes.status !== 200) { + throw new Error('Failed to get album artist detail'); + } - return jfNormalize.albumArtist( - { ...res.body, similarArtists: similarArtistsRes.body }, - apiClientProps.server, - ); + return jfNormalize.albumArtist( + { ...res.body, similarArtists: similarArtistsRes.body }, + apiClientProps.server, + ); }; const getAlbumArtistList = async (args: AlbumArtistListArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const res = await jfApiClient(apiClientProps).getAlbumArtistList({ - query: { - Fields: 'Genres, DateCreated, ExternalUrls, Overview', - ImageTypeLimit: 1, - Limit: query.limit, - ParentId: query.musicFolderId, - Recursive: true, - SearchTerm: query.searchTerm, - SortBy: albumArtistListSortMap.jellyfin[query.sortBy] || 'Name,SortName', - SortOrder: sortOrderMap.jellyfin[query.sortOrder], - StartIndex: query.startIndex, - UserId: apiClientProps.server?.userId || undefined, - }, - }); + const res = await jfApiClient(apiClientProps).getAlbumArtistList({ + query: { + Fields: 'Genres, DateCreated, ExternalUrls, Overview', + ImageTypeLimit: 1, + Limit: query.limit, + ParentId: query.musicFolderId, + Recursive: true, + SearchTerm: query.searchTerm, + SortBy: albumArtistListSortMap.jellyfin[query.sortBy] || 'Name,SortName', + SortOrder: sortOrderMap.jellyfin[query.sortOrder], + StartIndex: query.startIndex, + UserId: apiClientProps.server?.userId || undefined, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to get album artist list'); - } + if (res.status !== 200) { + throw new Error('Failed to get album artist list'); + } - return { - items: res.body.Items.map((item) => jfNormalize.albumArtist(item, apiClientProps.server)), - startIndex: query.startIndex, - totalRecordCount: res.body.TotalRecordCount, - }; + return { + items: res.body.Items.map((item) => jfNormalize.albumArtist(item, apiClientProps.server)), + startIndex: query.startIndex, + totalRecordCount: res.body.TotalRecordCount, + }; }; const getArtistList = async (args: ArtistListArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const res = await jfApiClient(apiClientProps).getAlbumArtistList({ - query: { - Limit: query.limit, - ParentId: query.musicFolderId, - Recursive: true, - SortBy: artistListSortMap.jellyfin[query.sortBy] || 'Name,SortName', - SortOrder: sortOrderMap.jellyfin[query.sortOrder], - StartIndex: query.startIndex, - }, - }); + const res = await jfApiClient(apiClientProps).getAlbumArtistList({ + query: { + Limit: query.limit, + ParentId: query.musicFolderId, + Recursive: true, + SortBy: artistListSortMap.jellyfin[query.sortBy] || 'Name,SortName', + SortOrder: sortOrderMap.jellyfin[query.sortOrder], + StartIndex: query.startIndex, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to get artist list'); - } + if (res.status !== 200) { + throw new Error('Failed to get artist list'); + } - return { - items: res.body.Items.map((item) => jfNormalize.albumArtist(item, apiClientProps.server)), - startIndex: query.startIndex, - totalRecordCount: res.body.TotalRecordCount, - }; + return { + items: res.body.Items.map((item) => jfNormalize.albumArtist(item, apiClientProps.server)), + startIndex: query.startIndex, + totalRecordCount: res.body.TotalRecordCount, + }; }; const getAlbumDetail = async (args: AlbumDetailArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - if (!apiClientProps.server?.userId) { - throw new Error('No userId found'); - } + if (!apiClientProps.server?.userId) { + throw new Error('No userId found'); + } - const res = await jfApiClient(apiClientProps).getAlbumDetail({ - params: { - id: query.id, - userId: apiClientProps.server.userId, - }, - query: { - Fields: 'Genres, DateCreated, ChildCount', - }, - }); + const res = await jfApiClient(apiClientProps).getAlbumDetail({ + params: { + id: query.id, + userId: apiClientProps.server.userId, + }, + query: { + Fields: 'Genres, DateCreated, ChildCount', + }, + }); - const songsRes = await jfApiClient(apiClientProps).getSongList({ - params: { - userId: apiClientProps.server.userId, - }, - query: { - Fields: 'Genres, DateCreated, MediaSources, ParentId', - IncludeItemTypes: 'Audio', - ParentId: query.id, - SortBy: 'Album,SortName', - }, - }); + const songsRes = await jfApiClient(apiClientProps).getSongList({ + params: { + userId: apiClientProps.server.userId, + }, + query: { + Fields: 'Genres, DateCreated, MediaSources, ParentId', + IncludeItemTypes: 'Audio', + ParentId: query.id, + SortBy: 'Album,SortName', + }, + }); - if (res.status !== 200 || songsRes.status !== 200) { - throw new Error('Failed to get album detail'); - } + if (res.status !== 200 || songsRes.status !== 200) { + throw new Error('Failed to get album detail'); + } - return jfNormalize.album({ ...res.body, Songs: songsRes.body.Items }, apiClientProps.server); + return jfNormalize.album({ ...res.body, Songs: songsRes.body.Items }, apiClientProps.server); }; const getAlbumList = async (args: AlbumListArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - if (!apiClientProps.server?.userId) { - throw new Error('No userId found'); - } - - const yearsGroup = []; - if (query._custom?.jellyfin?.minYear && query._custom?.jellyfin?.maxYear) { - for ( - let i = Number(query._custom?.jellyfin?.minYear); - i <= Number(query._custom?.jellyfin?.maxYear); - i += 1 - ) { - yearsGroup.push(String(i)); + if (!apiClientProps.server?.userId) { + throw new Error('No userId found'); } - } - const yearsFilter = yearsGroup.length ? yearsGroup.join(',') : undefined; + const yearsGroup = []; + if (query._custom?.jellyfin?.minYear && query._custom?.jellyfin?.maxYear) { + for ( + let i = Number(query._custom?.jellyfin?.minYear); + i <= Number(query._custom?.jellyfin?.maxYear); + i += 1 + ) { + yearsGroup.push(String(i)); + } + } - const res = await jfApiClient(apiClientProps).getAlbumList({ - params: { - userId: apiClientProps.server?.userId, - }, - query: { - AlbumArtistIds: query.artistIds ? formatCommaDelimitedString(query.artistIds) : undefined, - IncludeItemTypes: 'MusicAlbum', - Limit: query.limit, - ParentId: query.musicFolderId, - Recursive: true, - SearchTerm: query.searchTerm, - SortBy: albumListSortMap.jellyfin[query.sortBy] || 'SortName', - SortOrder: sortOrderMap.jellyfin[query.sortOrder], - StartIndex: query.startIndex, - ...query._custom?.jellyfin, - Years: yearsFilter, - }, - }); + const yearsFilter = yearsGroup.length ? yearsGroup.join(',') : undefined; - if (res.status !== 200) { - throw new Error('Failed to get album list'); - } + const res = await jfApiClient(apiClientProps).getAlbumList({ + params: { + userId: apiClientProps.server?.userId, + }, + query: { + AlbumArtistIds: query.artistIds + ? formatCommaDelimitedString(query.artistIds) + : undefined, + IncludeItemTypes: 'MusicAlbum', + Limit: query.limit, + ParentId: query.musicFolderId, + Recursive: true, + SearchTerm: query.searchTerm, + SortBy: albumListSortMap.jellyfin[query.sortBy] || 'SortName', + SortOrder: sortOrderMap.jellyfin[query.sortOrder], + StartIndex: query.startIndex, + ...query._custom?.jellyfin, + Years: yearsFilter, + }, + }); - return { - items: res.body.Items.map((item) => jfNormalize.album(item, apiClientProps.server)), - startIndex: query.startIndex, - totalRecordCount: res.body.TotalRecordCount, - }; + if (res.status !== 200) { + throw new Error('Failed to get album list'); + } + + return { + items: res.body.Items.map((item) => jfNormalize.album(item, apiClientProps.server)), + startIndex: query.startIndex, + totalRecordCount: res.body.TotalRecordCount, + }; }; const getTopSongList = async (args: TopSongListArgs): Promise => { - const { apiClientProps, query } = args; + const { apiClientProps, query } = args; - if (!apiClientProps.server?.userId) { - throw new Error('No userId found'); - } + if (!apiClientProps.server?.userId) { + throw new Error('No userId found'); + } - const res = await jfApiClient(apiClientProps).getTopSongsList({ - params: { - userId: apiClientProps.server?.userId, - }, - query: { - ArtistIds: query.artistId, - Fields: 'Genres, DateCreated, MediaSources, ParentId', - IncludeItemTypes: 'Audio', - Limit: query.limit, - Recursive: true, - SortBy: 'CommunityRating,SortName', - SortOrder: 'Descending', - UserId: apiClientProps.server?.userId, - }, - }); + const res = await jfApiClient(apiClientProps).getTopSongsList({ + params: { + userId: apiClientProps.server?.userId, + }, + query: { + ArtistIds: query.artistId, + Fields: 'Genres, DateCreated, MediaSources, ParentId', + IncludeItemTypes: 'Audio', + Limit: query.limit, + Recursive: true, + SortBy: 'CommunityRating,SortName', + SortOrder: 'Descending', + UserId: apiClientProps.server?.userId, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to get top song list'); - } + if (res.status !== 200) { + throw new Error('Failed to get top song list'); + } - return { - items: res.body.Items.map((item) => jfNormalize.song(item, apiClientProps.server, '')), - startIndex: 0, - totalRecordCount: res.body.TotalRecordCount, - }; + return { + items: res.body.Items.map((item) => jfNormalize.song(item, apiClientProps.server, '')), + startIndex: 0, + totalRecordCount: res.body.TotalRecordCount, + }; }; const getSongList = async (args: SongListArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - if (!apiClientProps.server?.userId) { - throw new Error('No userId found'); - } - - const yearsGroup = []; - if (query._custom?.jellyfin?.minYear && query._custom?.jellyfin?.maxYear) { - for ( - let i = Number(query._custom?.jellyfin?.minYear); - i <= Number(query._custom?.jellyfin?.maxYear); - i += 1 - ) { - yearsGroup.push(String(i)); + if (!apiClientProps.server?.userId) { + throw new Error('No userId found'); } - } - const yearsFilter = yearsGroup.length ? formatCommaDelimitedString(yearsGroup) : undefined; - const albumIdsFilter = query.albumIds ? formatCommaDelimitedString(query.albumIds) : undefined; - const artistIdsFilter = query.artistIds ? formatCommaDelimitedString(query.artistIds) : undefined; + const yearsGroup = []; + if (query._custom?.jellyfin?.minYear && query._custom?.jellyfin?.maxYear) { + for ( + let i = Number(query._custom?.jellyfin?.minYear); + i <= Number(query._custom?.jellyfin?.maxYear); + i += 1 + ) { + yearsGroup.push(String(i)); + } + } - const res = await jfApiClient(apiClientProps).getSongList({ - params: { - userId: apiClientProps.server?.userId, - }, - query: { - AlbumIds: albumIdsFilter, - ArtistIds: artistIdsFilter, - Fields: 'Genres, DateCreated, MediaSources, ParentId', - IncludeItemTypes: 'Audio', - Limit: query.limit, - ParentId: query.musicFolderId, - Recursive: true, - SearchTerm: query.searchTerm, - SortBy: songListSortMap.jellyfin[query.sortBy] || 'Album,SortName', - SortOrder: sortOrderMap.jellyfin[query.sortOrder], - StartIndex: query.startIndex, - ...query._custom?.jellyfin, - Years: yearsFilter, - }, - }); + const yearsFilter = yearsGroup.length ? formatCommaDelimitedString(yearsGroup) : undefined; + const albumIdsFilter = query.albumIds ? formatCommaDelimitedString(query.albumIds) : undefined; + const artistIdsFilter = query.artistIds + ? formatCommaDelimitedString(query.artistIds) + : undefined; - if (res.status !== 200) { - throw new Error('Failed to get song list'); - } + const res = await jfApiClient(apiClientProps).getSongList({ + params: { + userId: apiClientProps.server?.userId, + }, + query: { + AlbumIds: albumIdsFilter, + ArtistIds: artistIdsFilter, + Fields: 'Genres, DateCreated, MediaSources, ParentId', + IncludeItemTypes: 'Audio', + Limit: query.limit, + ParentId: query.musicFolderId, + Recursive: true, + SearchTerm: query.searchTerm, + SortBy: songListSortMap.jellyfin[query.sortBy] || 'Album,SortName', + SortOrder: sortOrderMap.jellyfin[query.sortOrder], + StartIndex: query.startIndex, + ...query._custom?.jellyfin, + Years: yearsFilter, + }, + }); - return { - items: res.body.Items.map((item) => jfNormalize.song(item, apiClientProps.server, '')), - startIndex: query.startIndex, - totalRecordCount: res.body.TotalRecordCount, - }; + if (res.status !== 200) { + throw new Error('Failed to get song list'); + } + + return { + items: res.body.Items.map((item) => jfNormalize.song(item, apiClientProps.server, '')), + startIndex: query.startIndex, + totalRecordCount: res.body.TotalRecordCount, + }; }; const addToPlaylist = async (args: AddToPlaylistArgs): Promise => { - const { query, body, apiClientProps } = args; + const { query, body, apiClientProps } = args; - if (!apiClientProps.server?.userId) { - throw new Error('No userId found'); - } + if (!apiClientProps.server?.userId) { + throw new Error('No userId found'); + } - const res = await jfApiClient(apiClientProps).addToPlaylist({ - body: null, - params: { - id: query.id, - }, - query: { - Ids: body.songId, - UserId: apiClientProps.server?.userId, - }, - }); + const res = await jfApiClient(apiClientProps).addToPlaylist({ + body: null, + params: { + id: query.id, + }, + query: { + Ids: body.songId, + UserId: apiClientProps.server?.userId, + }, + }); - if (res.status !== 204) { - throw new Error('Failed to add to playlist'); - } + if (res.status !== 204) { + throw new Error('Failed to add to playlist'); + } - return null; + return null; }; const removeFromPlaylist = async ( - args: RemoveFromPlaylistArgs, + args: RemoveFromPlaylistArgs, ): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const res = await jfApiClient(apiClientProps).removeFromPlaylist({ - body: null, - params: { - id: query.id, - }, - query: { - EntryIds: query.songId, - }, - }); + const res = await jfApiClient(apiClientProps).removeFromPlaylist({ + body: null, + params: { + id: query.id, + }, + query: { + EntryIds: query.songId, + }, + }); - if (res.status !== 204) { - throw new Error('Failed to remove from playlist'); - } + if (res.status !== 204) { + throw new Error('Failed to remove from playlist'); + } - return null; + return null; }; const getPlaylistDetail = async (args: PlaylistDetailArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - if (!apiClientProps.server?.userId) { - throw new Error('No userId found'); - } + if (!apiClientProps.server?.userId) { + throw new Error('No userId found'); + } - const res = await jfApiClient(apiClientProps).getPlaylistDetail({ - params: { - id: query.id, - userId: apiClientProps.server?.userId, - }, - query: { - Fields: 'Genres, DateCreated, MediaSources, ChildCount, ParentId', - Ids: query.id, - }, - }); + const res = await jfApiClient(apiClientProps).getPlaylistDetail({ + params: { + id: query.id, + userId: apiClientProps.server?.userId, + }, + query: { + Fields: 'Genres, DateCreated, MediaSources, ChildCount, ParentId', + Ids: query.id, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to get playlist detail'); - } + if (res.status !== 200) { + throw new Error('Failed to get playlist detail'); + } - return jfNormalize.playlist(res.body, apiClientProps.server); + return jfNormalize.playlist(res.body, apiClientProps.server); }; const getPlaylistSongList = async (args: PlaylistSongListArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - if (!apiClientProps.server?.userId) { - throw new Error('No userId found'); - } + if (!apiClientProps.server?.userId) { + throw new Error('No userId found'); + } - const res = await jfApiClient(apiClientProps).getPlaylistSongList({ - params: { - id: query.id, - }, - query: { - Fields: 'Genres, DateCreated, MediaSources, UserData, ParentId', - IncludeItemTypes: 'Audio', - Limit: query.limit, - SortBy: query.sortBy ? songListSortMap.jellyfin[query.sortBy] : undefined, - SortOrder: query.sortOrder ? sortOrderMap.jellyfin[query.sortOrder] : undefined, - StartIndex: 0, - UserId: apiClientProps.server?.userId, - }, - }); + const res = await jfApiClient(apiClientProps).getPlaylistSongList({ + params: { + id: query.id, + }, + query: { + Fields: 'Genres, DateCreated, MediaSources, UserData, ParentId', + IncludeItemTypes: 'Audio', + Limit: query.limit, + SortBy: query.sortBy ? songListSortMap.jellyfin[query.sortBy] : undefined, + SortOrder: query.sortOrder ? sortOrderMap.jellyfin[query.sortOrder] : undefined, + StartIndex: 0, + UserId: apiClientProps.server?.userId, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to get playlist song list'); - } + if (res.status !== 200) { + throw new Error('Failed to get playlist song list'); + } - return { - items: res.body.Items.map((item) => jfNormalize.song(item, apiClientProps.server, '')), - startIndex: query.startIndex, - totalRecordCount: res.body.TotalRecordCount, - }; + return { + items: res.body.Items.map((item) => jfNormalize.song(item, apiClientProps.server, '')), + startIndex: query.startIndex, + totalRecordCount: res.body.TotalRecordCount, + }; }; const getPlaylistList = async (args: PlaylistListArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - if (!apiClientProps.server?.userId) { - throw new Error('No userId found'); - } + if (!apiClientProps.server?.userId) { + throw new Error('No userId found'); + } - const res = await jfApiClient(apiClientProps).getPlaylistList({ - params: { - userId: apiClientProps.server?.userId, - }, - query: { - Fields: 'ChildCount, Genres, DateCreated, ParentId, Overview', - IncludeItemTypes: 'Playlist', - Limit: query.limit, - MediaTypes: 'Audio', - Recursive: true, - SortBy: playlistListSortMap.jellyfin[query.sortBy], - SortOrder: sortOrderMap.jellyfin[query.sortOrder], - StartIndex: query.startIndex, - }, - }); + const res = await jfApiClient(apiClientProps).getPlaylistList({ + params: { + userId: apiClientProps.server?.userId, + }, + query: { + Fields: 'ChildCount, Genres, DateCreated, ParentId, Overview', + IncludeItemTypes: 'Playlist', + Limit: query.limit, + MediaTypes: 'Audio', + Recursive: true, + SortBy: playlistListSortMap.jellyfin[query.sortBy], + SortOrder: sortOrderMap.jellyfin[query.sortOrder], + StartIndex: query.startIndex, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to get playlist list'); - } + if (res.status !== 200) { + throw new Error('Failed to get playlist list'); + } - return { - items: res.body.Items.map((item) => jfNormalize.playlist(item, apiClientProps.server)), - startIndex: 0, - totalRecordCount: res.body.TotalRecordCount, - }; + return { + items: res.body.Items.map((item) => jfNormalize.playlist(item, apiClientProps.server)), + startIndex: 0, + totalRecordCount: res.body.TotalRecordCount, + }; }; const createPlaylist = async (args: CreatePlaylistArgs): Promise => { - const { body, apiClientProps } = args; + const { body, apiClientProps } = args; - if (!apiClientProps.server?.userId) { - throw new Error('No userId found'); - } + if (!apiClientProps.server?.userId) { + throw new Error('No userId found'); + } - const res = await jfApiClient(apiClientProps).createPlaylist({ - body: { - MediaType: 'Audio', - Name: body.name, - Overview: body.comment || '', - UserId: apiClientProps.server.userId, - }, - }); + const res = await jfApiClient(apiClientProps).createPlaylist({ + body: { + MediaType: 'Audio', + Name: body.name, + Overview: body.comment || '', + UserId: apiClientProps.server.userId, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to create playlist'); - } + if (res.status !== 200) { + throw new Error('Failed to create playlist'); + } - return { - id: res.body.Id, - }; + return { + id: res.body.Id, + }; }; const updatePlaylist = async (args: UpdatePlaylistArgs): Promise => { - const { query, body, apiClientProps } = args; + const { query, body, apiClientProps } = args; - if (!apiClientProps.server?.userId) { - throw new Error('No userId found'); - } + if (!apiClientProps.server?.userId) { + throw new Error('No userId found'); + } - const res = await jfApiClient(apiClientProps).updatePlaylist({ - body: { - Genres: body.genres?.map((item) => ({ Id: item.id, Name: item.name })) || [], - MediaType: 'Audio', - Name: body.name, - Overview: body.comment || '', - PremiereDate: null, - ProviderIds: {}, - Tags: [], - UserId: apiClientProps.server?.userId, // Required - }, - params: { - id: query.id, - }, - }); + const res = await jfApiClient(apiClientProps).updatePlaylist({ + body: { + Genres: body.genres?.map((item) => ({ Id: item.id, Name: item.name })) || [], + MediaType: 'Audio', + Name: body.name, + Overview: body.comment || '', + PremiereDate: null, + ProviderIds: {}, + Tags: [], + UserId: apiClientProps.server?.userId, // Required + }, + params: { + id: query.id, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to update playlist'); - } + if (res.status !== 200) { + throw new Error('Failed to update playlist'); + } - return null; + return null; }; const deletePlaylist = async (args: DeletePlaylistArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const res = await jfApiClient(apiClientProps).deletePlaylist({ - body: null, - params: { - id: query.id, - }, - }); + const res = await jfApiClient(apiClientProps).deletePlaylist({ + body: null, + params: { + id: query.id, + }, + }); - if (res.status !== 204) { - throw new Error('Failed to delete playlist'); - } + if (res.status !== 204) { + throw new Error('Failed to delete playlist'); + } - return null; + return null; }; const createFavorite = async (args: FavoriteArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - if (!apiClientProps.server?.userId) { - throw new Error('No userId found'); - } + if (!apiClientProps.server?.userId) { + throw new Error('No userId found'); + } - for (const id of query.id) { - await jfApiClient(apiClientProps).createFavorite({ - body: {}, - params: { - id, - userId: apiClientProps.server?.userId, - }, - }); - } + for (const id of query.id) { + await jfApiClient(apiClientProps).createFavorite({ + body: {}, + params: { + id, + userId: apiClientProps.server?.userId, + }, + }); + } - return null; + return null; }; const deleteFavorite = async (args: FavoriteArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - if (!apiClientProps.server?.userId) { - throw new Error('No userId found'); - } + if (!apiClientProps.server?.userId) { + throw new Error('No userId found'); + } - for (const id of query.id) { - await jfApiClient(apiClientProps).removeFavorite({ - body: {}, - params: { - id, - userId: apiClientProps.server?.userId, - }, - }); - } + for (const id of query.id) { + await jfApiClient(apiClientProps).removeFavorite({ + body: {}, + params: { + id, + userId: apiClientProps.server?.userId, + }, + }); + } - return null; + return null; }; const scrobble = async (args: ScrobbleArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const position = query.position && Math.round(query.position); + const position = query.position && Math.round(query.position); - if (query.submission) { - // Checked by jellyfin-plugin-lastfm for whether or not to send the "finished" scrobble (uses PositionTicks) - jfApiClient(apiClientProps).scrobbleStopped({ - body: { - IsPaused: true, - ItemId: query.id, - PositionTicks: position, - }, - }); + if (query.submission) { + // Checked by jellyfin-plugin-lastfm for whether or not to send the "finished" scrobble (uses PositionTicks) + jfApiClient(apiClientProps).scrobbleStopped({ + body: { + IsPaused: true, + ItemId: query.id, + PositionTicks: position, + }, + }); - return null; - } + return null; + } - if (query.event === 'start') { - jfApiClient(apiClientProps).scrobblePlaying({ - body: { - ItemId: query.id, - PositionTicks: position, - }, - }); + if (query.event === 'start') { + jfApiClient(apiClientProps).scrobblePlaying({ + body: { + ItemId: query.id, + PositionTicks: position, + }, + }); - return null; - } + return null; + } + + if (query.event === 'pause') { + jfApiClient(apiClientProps).scrobbleProgress({ + body: { + EventName: query.event, + IsPaused: true, + ItemId: query.id, + PositionTicks: position, + }, + }); + + return null; + } + + if (query.event === 'unpause') { + jfApiClient(apiClientProps).scrobbleProgress({ + body: { + EventName: query.event, + IsPaused: false, + ItemId: query.id, + PositionTicks: position, + }, + }); + + return null; + } - if (query.event === 'pause') { jfApiClient(apiClientProps).scrobbleProgress({ - body: { - EventName: query.event, - IsPaused: true, - ItemId: query.id, - PositionTicks: position, - }, + body: { + ItemId: query.id, + PositionTicks: position, + }, }); return null; - } - - if (query.event === 'unpause') { - jfApiClient(apiClientProps).scrobbleProgress({ - body: { - EventName: query.event, - IsPaused: false, - ItemId: query.id, - PositionTicks: position, - }, - }); - - return null; - } - - jfApiClient(apiClientProps).scrobbleProgress({ - body: { - ItemId: query.id, - PositionTicks: position, - }, - }); - - return null; }; const search = async (args: SearchArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - if (!apiClientProps.server?.userId) { - throw new Error('No userId found'); - } - - let albums: z.infer['Items'] = []; - let albumArtists: z.infer['Items'] = []; - let songs: z.infer['Items'] = []; - - if (query.albumLimit) { - const res = await jfApiClient(apiClientProps).getAlbumList({ - params: { - userId: apiClientProps.server?.userId, - }, - query: { - EnableTotalRecordCount: true, - ImageTypeLimit: 1, - IncludeItemTypes: 'MusicAlbum', - Limit: query.albumLimit, - Recursive: true, - SearchTerm: query.query, - SortBy: 'SortName', - SortOrder: 'Ascending', - StartIndex: query.albumStartIndex || 0, - }, - }); - - if (res.status !== 200) { - throw new Error('Failed to get album list'); + if (!apiClientProps.server?.userId) { + throw new Error('No userId found'); } - albums = res.body.Items; - } + let albums: z.infer['Items'] = []; + let albumArtists: z.infer['Items'] = []; + let songs: z.infer['Items'] = []; - if (query.albumArtistLimit) { - const res = await jfApiClient(apiClientProps).getAlbumArtistList({ - query: { - EnableTotalRecordCount: true, - Fields: 'Genres, DateCreated, ExternalUrls, Overview', - ImageTypeLimit: 1, - IncludeArtists: true, - Limit: query.albumArtistLimit, - Recursive: true, - SearchTerm: query.query, - StartIndex: query.albumArtistStartIndex || 0, - UserId: apiClientProps.server?.userId, - }, - }); + if (query.albumLimit) { + const res = await jfApiClient(apiClientProps).getAlbumList({ + params: { + userId: apiClientProps.server?.userId, + }, + query: { + EnableTotalRecordCount: true, + ImageTypeLimit: 1, + IncludeItemTypes: 'MusicAlbum', + Limit: query.albumLimit, + Recursive: true, + SearchTerm: query.query, + SortBy: 'SortName', + SortOrder: 'Ascending', + StartIndex: query.albumStartIndex || 0, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to get album artist list'); + if (res.status !== 200) { + throw new Error('Failed to get album list'); + } + + albums = res.body.Items; } - albumArtists = res.body.Items; - } + if (query.albumArtistLimit) { + const res = await jfApiClient(apiClientProps).getAlbumArtistList({ + query: { + EnableTotalRecordCount: true, + Fields: 'Genres, DateCreated, ExternalUrls, Overview', + ImageTypeLimit: 1, + IncludeArtists: true, + Limit: query.albumArtistLimit, + Recursive: true, + SearchTerm: query.query, + StartIndex: query.albumArtistStartIndex || 0, + UserId: apiClientProps.server?.userId, + }, + }); - if (query.songLimit) { - const res = await jfApiClient(apiClientProps).getSongList({ - params: { - userId: apiClientProps.server?.userId, - }, - query: { - EnableTotalRecordCount: true, - Fields: 'Genres, DateCreated, MediaSources, ParentId', - IncludeItemTypes: 'Audio', - Limit: query.songLimit, - Recursive: true, - SearchTerm: query.query, - SortBy: 'Album,SortName', - SortOrder: 'Ascending', - StartIndex: query.songStartIndex || 0, - UserId: apiClientProps.server?.userId, - }, - }); + if (res.status !== 200) { + throw new Error('Failed to get album artist list'); + } - if (res.status !== 200) { - throw new Error('Failed to get song list'); + albumArtists = res.body.Items; } - songs = res.body.Items; - } + if (query.songLimit) { + const res = await jfApiClient(apiClientProps).getSongList({ + params: { + userId: apiClientProps.server?.userId, + }, + query: { + EnableTotalRecordCount: true, + Fields: 'Genres, DateCreated, MediaSources, ParentId', + IncludeItemTypes: 'Audio', + Limit: query.songLimit, + Recursive: true, + SearchTerm: query.query, + SortBy: 'Album,SortName', + SortOrder: 'Ascending', + StartIndex: query.songStartIndex || 0, + UserId: apiClientProps.server?.userId, + }, + }); - return { - albumArtists: albumArtists.map((item) => jfNormalize.albumArtist(item, apiClientProps.server)), - albums: albums.map((item) => jfNormalize.album(item, apiClientProps.server)), - songs: songs.map((item) => jfNormalize.song(item, apiClientProps.server, '')), - }; + if (res.status !== 200) { + throw new Error('Failed to get song list'); + } + + songs = res.body.Items; + } + + return { + albumArtists: albumArtists.map((item) => + jfNormalize.albumArtist(item, apiClientProps.server), + ), + albums: albums.map((item) => jfNormalize.album(item, apiClientProps.server)), + songs: songs.map((item) => jfNormalize.song(item, apiClientProps.server, '')), + }; }; const getRandomSongList = async (args: RandomSongListArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - if (!apiClientProps.server?.userId) { - throw new Error('No userId found'); - } - - const yearsGroup = []; - if (query.minYear && query.maxYear) { - for (let i = Number(query.minYear); i <= Number(query.maxYear); i += 1) { - yearsGroup.push(String(i)); + if (!apiClientProps.server?.userId) { + throw new Error('No userId found'); } - } - const yearsFilter = yearsGroup.length ? formatCommaDelimitedString(yearsGroup) : undefined; + const yearsGroup = []; + if (query.minYear && query.maxYear) { + for (let i = Number(query.minYear); i <= Number(query.maxYear); i += 1) { + yearsGroup.push(String(i)); + } + } - const res = await jfApiClient(apiClientProps).getSongList({ - params: { - userId: apiClientProps.server?.userId, - }, - query: { - Fields: 'Genres, DateCreated, MediaSources, ParentId', - GenreIds: query.genre ? query.genre : undefined, - IncludeItemTypes: 'Audio', - Limit: query.limit, - ParentId: query.musicFolderId, - Recursive: true, - SortBy: JFSongListSort.RANDOM, - SortOrder: JFSortOrder.ASC, - StartIndex: 0, - Years: yearsFilter, - }, - }); + const yearsFilter = yearsGroup.length ? formatCommaDelimitedString(yearsGroup) : undefined; - if (res.status !== 200) { - throw new Error('Failed to get random songs'); - } + const res = await jfApiClient(apiClientProps).getSongList({ + params: { + userId: apiClientProps.server?.userId, + }, + query: { + Fields: 'Genres, DateCreated, MediaSources, ParentId', + GenreIds: query.genre ? query.genre : undefined, + IncludeItemTypes: 'Audio', + Limit: query.limit, + ParentId: query.musicFolderId, + Recursive: true, + SortBy: JFSongListSort.RANDOM, + SortOrder: JFSortOrder.ASC, + StartIndex: 0, + Years: yearsFilter, + }, + }); - return { - items: res.body.Items.map((item) => jfNormalize.song(item, apiClientProps.server, '')), - startIndex: 0, - totalRecordCount: res.body.Items.length || 0, - }; + if (res.status !== 200) { + throw new Error('Failed to get random songs'); + } + + return { + items: res.body.Items.map((item) => jfNormalize.song(item, apiClientProps.server, '')), + startIndex: 0, + totalRecordCount: res.body.Items.length || 0, + }; }; const getLyrics = async (args: LyricsArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - if (!apiClientProps.server?.userId) { - throw new Error('No userId found'); - } + if (!apiClientProps.server?.userId) { + throw new Error('No userId found'); + } - const res = await jfApiClient(apiClientProps).getSongLyrics({ - params: { - id: query.songId, - userId: apiClientProps.server?.userId, - }, - }); + const res = await jfApiClient(apiClientProps).getSongLyrics({ + params: { + id: query.songId, + userId: apiClientProps.server?.userId, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to get lyrics'); - } + if (res.status !== 200) { + throw new Error('Failed to get lyrics'); + } - if (res.body.Lyrics.length > 0 && res.body.Lyrics[0].Start === undefined) { - return res.body.Lyrics[0].Text; - } + if (res.body.Lyrics.length > 0 && res.body.Lyrics[0].Start === undefined) { + return res.body.Lyrics[0].Text; + } - return res.body.Lyrics.map((lyric) => [lyric.Start! / 1e4, lyric.Text]); + return res.body.Lyrics.map((lyric) => [lyric.Start! / 1e4, lyric.Text]); }; export const jfController = { - addToPlaylist, - authenticate, - createFavorite, - createPlaylist, - deleteFavorite, - deletePlaylist, - getAlbumArtistDetail, - getAlbumArtistList, - getAlbumDetail, - getAlbumList, - getArtistList, - getGenreList, - getLyrics, - getMusicFolderList, - getPlaylistDetail, - getPlaylistList, - getPlaylistSongList, - getRandomSongList, - getSongList, - getTopSongList, - removeFromPlaylist, - scrobble, - search, - updatePlaylist, + addToPlaylist, + authenticate, + createFavorite, + createPlaylist, + deleteFavorite, + deletePlaylist, + getAlbumArtistDetail, + getAlbumArtistList, + getAlbumDetail, + getAlbumList, + getArtistList, + getGenreList, + getLyrics, + getMusicFolderList, + getPlaylistDetail, + getPlaylistList, + getPlaylistSongList, + getRandomSongList, + getSongList, + getTopSongList, + removeFromPlaylist, + scrobble, + search, + updatePlaylist, }; diff --git a/src/renderer/api/jellyfin/jellyfin-normalize.ts b/src/renderer/api/jellyfin/jellyfin-normalize.ts index 60079519..ed4dc1ec 100644 --- a/src/renderer/api/jellyfin/jellyfin-normalize.ts +++ b/src/renderer/api/jellyfin/jellyfin-normalize.ts @@ -3,312 +3,316 @@ import { z } from 'zod'; import { JFAlbum, JFPlaylist, JFMusicFolder, JFGenre } from '/@/renderer/api/jellyfin.types'; import { jfType } from '/@/renderer/api/jellyfin/jellyfin-types'; import { - Song, - LibraryItem, - Album, - AlbumArtist, - Playlist, - MusicFolder, - Genre, + Song, + LibraryItem, + Album, + AlbumArtist, + Playlist, + MusicFolder, + Genre, } from '/@/renderer/api/types'; import { ServerListItem, ServerType } from '/@/renderer/types'; const getStreamUrl = (args: { - container?: string; - deviceId: string; - eTag?: string; - id: string; - mediaSourceId?: string; - server: ServerListItem | null; + container?: string; + deviceId: string; + eTag?: string; + id: string; + mediaSourceId?: string; + server: ServerListItem | null; }) => { - const { id, server, deviceId } = args; + const { id, server, deviceId } = args; - return ( - `${server?.url}/audio` + - `/${id}/universal` + - `?userId=${server?.userId}` + - `&deviceId=${deviceId}` + - '&audioCodec=aac' + - `&api_key=${server?.credential}` + - `&playSessionId=${deviceId}` + - '&container=opus,mp3,aac,m4a,m4b,flac,wav,ogg' + - '&transcodingContainer=ts' + - '&transcodingProtocol=hls' - ); + return ( + `${server?.url}/audio` + + `/${id}/universal` + + `?userId=${server?.userId}` + + `&deviceId=${deviceId}` + + '&audioCodec=aac' + + `&api_key=${server?.credential}` + + `&playSessionId=${deviceId}` + + '&container=opus,mp3,aac,m4a,m4b,flac,wav,ogg' + + '&transcodingContainer=ts' + + '&transcodingProtocol=hls' + ); }; const getAlbumArtistCoverArtUrl = (args: { - baseUrl: string; - item: z.infer; - size: number; + baseUrl: string; + item: z.infer; + size: number; }) => { - const size = args.size ? args.size : 300; + const size = args.size ? args.size : 300; - if (!args.item.ImageTags?.Primary) { - return null; - } + if (!args.item.ImageTags?.Primary) { + return null; + } - return ( - `${args.baseUrl}/Items` + - `/${args.item.Id}` + - '/Images/Primary' + - `?width=${size}&height=${size}` + - '&quality=96' - ); + return ( + `${args.baseUrl}/Items` + + `/${args.item.Id}` + + '/Images/Primary' + + `?width=${size}&height=${size}` + + '&quality=96' + ); }; const getAlbumCoverArtUrl = (args: { baseUrl: string; item: JFAlbum; size: number }) => { - const size = args.size ? args.size : 300; + const size = args.size ? args.size : 300; - if (!args.item.ImageTags?.Primary && !args.item?.AlbumPrimaryImageTag) { - return null; - } + if (!args.item.ImageTags?.Primary && !args.item?.AlbumPrimaryImageTag) { + return null; + } - return ( - `${args.baseUrl}/Items` + - `/${args.item.Id}` + - '/Images/Primary' + - `?width=${size}&height=${size}` + - '&quality=96' - ); + return ( + `${args.baseUrl}/Items` + + `/${args.item.Id}` + + '/Images/Primary' + + `?width=${size}&height=${size}` + + '&quality=96' + ); }; const getSongCoverArtUrl = (args: { - baseUrl: string; - item: z.infer; - size: number; + baseUrl: string; + item: z.infer; + size: number; }) => { - const size = args.size ? args.size : 100; + const size = args.size ? args.size : 100; - if (args.item.ImageTags.Primary) { - return ( - `${args.baseUrl}/Items` + - `/${args.item.Id}` + - '/Images/Primary' + - `?width=${size}&height=${size}` + - '&quality=96' - ); - } + if (args.item.ImageTags.Primary) { + return ( + `${args.baseUrl}/Items` + + `/${args.item.Id}` + + '/Images/Primary' + + `?width=${size}&height=${size}` + + '&quality=96' + ); + } - if (args.item?.AlbumPrimaryImageTag) { - // Fall back to album art if no image embedded - return ( - `${args.baseUrl}/Items` + - `/${args.item?.AlbumId}` + - '/Images/Primary' + - `?width=${size}&height=${size}` + - '&quality=96' - ); - } + if (args.item?.AlbumPrimaryImageTag) { + // Fall back to album art if no image embedded + return ( + `${args.baseUrl}/Items` + + `/${args.item?.AlbumId}` + + '/Images/Primary' + + `?width=${size}&height=${size}` + + '&quality=96' + ); + } - return null; + return null; }; const getPlaylistCoverArtUrl = (args: { baseUrl: string; item: JFPlaylist; size: number }) => { - const size = args.size ? args.size : 300; + const size = args.size ? args.size : 300; - if (!args.item.ImageTags?.Primary) { - return null; - } + if (!args.item.ImageTags?.Primary) { + return null; + } - return ( - `${args.baseUrl}/Items` + - `/${args.item.Id}` + - '/Images/Primary' + - `?width=${size}&height=${size}` + - '&quality=96' - ); + return ( + `${args.baseUrl}/Items` + + `/${args.item.Id}` + + '/Images/Primary' + + `?width=${size}&height=${size}` + + '&quality=96' + ); }; const normalizeSong = ( - item: z.infer, - server: ServerListItem | null, - deviceId: string, - imageSize?: number, + item: z.infer, + server: ServerListItem | null, + deviceId: string, + imageSize?: number, ): Song => { - return { - album: item.Album, - albumArtists: item.AlbumArtists?.map((entry) => ({ - id: entry.Id, - imageUrl: null, - name: entry.Name, - })), - albumId: item.AlbumId, - artistName: item?.ArtistItems?.[0]?.Name, - artists: item?.ArtistItems?.map((entry) => ({ - id: entry.Id, - imageUrl: null, - name: entry.Name, - })), - bitRate: item.MediaSources && Number(Math.trunc(item.MediaSources[0]?.Bitrate / 1000)), - bpm: null, - channels: null, - comment: null, - compilation: null, - container: (item.MediaSources && item.MediaSources[0]?.Container) || null, - createdAt: item.DateCreated, - discNumber: (item.ParentIndexNumber && item.ParentIndexNumber) || 1, - duration: item.RunTimeTicks / 10000000, - genres: item.GenreItems.map((entry: any) => ({ id: entry.Id, name: entry.Name })), - id: item.Id, - imagePlaceholderUrl: null, - imageUrl: getSongCoverArtUrl({ baseUrl: server?.url || '', item, size: imageSize || 100 }), - itemType: LibraryItem.SONG, - lastPlayedAt: null, - lyrics: null, - name: item.Name, - path: (item.MediaSources && item.MediaSources[0]?.Path) || null, - playCount: (item.UserData && item.UserData.PlayCount) || 0, - playlistItemId: item.PlaylistItemId, - // releaseDate: (item.ProductionYear && new Date(item.ProductionYear, 0, 1).toISOString()) || null, - releaseDate: null, - releaseYear: item.ProductionYear ? String(item.ProductionYear) : null, - serverId: server?.id || '', - serverType: ServerType.JELLYFIN, - size: item.MediaSources && item.MediaSources[0]?.Size, - streamUrl: getStreamUrl({ - container: item.MediaSources?.[0]?.Container, - deviceId, - eTag: item.MediaSources?.[0]?.ETag, - id: item.Id, - mediaSourceId: item.MediaSources?.[0]?.Id, - server, - }), - trackNumber: item.IndexNumber, - uniqueId: nanoid(), - updatedAt: item.DateCreated, - userFavorite: (item.UserData && item.UserData.IsFavorite) || false, - userRating: null, - }; + return { + album: item.Album, + albumArtists: item.AlbumArtists?.map((entry) => ({ + id: entry.Id, + imageUrl: null, + name: entry.Name, + })), + albumId: item.AlbumId, + artistName: item?.ArtistItems?.[0]?.Name, + artists: item?.ArtistItems?.map((entry) => ({ + id: entry.Id, + imageUrl: null, + name: entry.Name, + })), + bitRate: item.MediaSources && Number(Math.trunc(item.MediaSources[0]?.Bitrate / 1000)), + bpm: null, + channels: null, + comment: null, + compilation: null, + container: (item.MediaSources && item.MediaSources[0]?.Container) || null, + createdAt: item.DateCreated, + discNumber: (item.ParentIndexNumber && item.ParentIndexNumber) || 1, + duration: item.RunTimeTicks / 10000000, + genres: item.GenreItems.map((entry: any) => ({ id: entry.Id, name: entry.Name })), + id: item.Id, + imagePlaceholderUrl: null, + imageUrl: getSongCoverArtUrl({ baseUrl: server?.url || '', item, size: imageSize || 100 }), + itemType: LibraryItem.SONG, + lastPlayedAt: null, + lyrics: null, + name: item.Name, + path: (item.MediaSources && item.MediaSources[0]?.Path) || null, + playCount: (item.UserData && item.UserData.PlayCount) || 0, + playlistItemId: item.PlaylistItemId, + // releaseDate: (item.ProductionYear && new Date(item.ProductionYear, 0, 1).toISOString()) || null, + releaseDate: null, + releaseYear: item.ProductionYear ? String(item.ProductionYear) : null, + serverId: server?.id || '', + serverType: ServerType.JELLYFIN, + size: item.MediaSources && item.MediaSources[0]?.Size, + streamUrl: getStreamUrl({ + container: item.MediaSources?.[0]?.Container, + deviceId, + eTag: item.MediaSources?.[0]?.ETag, + id: item.Id, + mediaSourceId: item.MediaSources?.[0]?.Id, + server, + }), + trackNumber: item.IndexNumber, + uniqueId: nanoid(), + updatedAt: item.DateCreated, + userFavorite: (item.UserData && item.UserData.IsFavorite) || false, + userRating: null, + }; }; const normalizeAlbum = ( - item: z.infer, - server: ServerListItem | null, - imageSize?: number, + item: z.infer, + server: ServerListItem | null, + imageSize?: number, ): Album => { - return { - albumArtists: - item.AlbumArtists.map((entry) => ({ - id: entry.Id, - imageUrl: null, - name: entry.Name, - })) || [], - artists: item.ArtistItems?.map((entry) => ({ id: entry.Id, imageUrl: null, name: entry.Name })), - backdropImageUrl: null, - createdAt: item.DateCreated, - duration: item.RunTimeTicks / 10000, - genres: item.GenreItems?.map((entry) => ({ id: entry.Id, name: entry.Name })), - id: item.Id, - imagePlaceholderUrl: null, - imageUrl: getAlbumCoverArtUrl({ - baseUrl: server?.url || '', - item, - size: imageSize || 300, - }), - isCompilation: null, - itemType: LibraryItem.ALBUM, - lastPlayedAt: null, - name: item.Name, - playCount: item.UserData?.PlayCount || 0, - releaseDate: item.PremiereDate?.split('T')[0] || null, - releaseYear: item.ProductionYear || null, - serverId: server?.id || '', - serverType: ServerType.JELLYFIN, - size: null, - songCount: item?.ChildCount || null, - songs: item.Songs?.map((song) => normalizeSong(song, server, '', imageSize)), - uniqueId: nanoid(), - updatedAt: item?.DateLastMediaAdded || item.DateCreated, - userFavorite: item.UserData?.IsFavorite || false, - userRating: null, - }; + return { + albumArtists: + item.AlbumArtists.map((entry) => ({ + id: entry.Id, + imageUrl: null, + name: entry.Name, + })) || [], + artists: item.ArtistItems?.map((entry) => ({ + id: entry.Id, + imageUrl: null, + name: entry.Name, + })), + backdropImageUrl: null, + createdAt: item.DateCreated, + duration: item.RunTimeTicks / 10000, + genres: item.GenreItems?.map((entry) => ({ id: entry.Id, name: entry.Name })), + id: item.Id, + imagePlaceholderUrl: null, + imageUrl: getAlbumCoverArtUrl({ + baseUrl: server?.url || '', + item, + size: imageSize || 300, + }), + isCompilation: null, + itemType: LibraryItem.ALBUM, + lastPlayedAt: null, + name: item.Name, + playCount: item.UserData?.PlayCount || 0, + releaseDate: item.PremiereDate?.split('T')[0] || null, + releaseYear: item.ProductionYear || null, + serverId: server?.id || '', + serverType: ServerType.JELLYFIN, + size: null, + songCount: item?.ChildCount || null, + songs: item.Songs?.map((song) => normalizeSong(song, server, '', imageSize)), + uniqueId: nanoid(), + updatedAt: item?.DateLastMediaAdded || item.DateCreated, + userFavorite: item.UserData?.IsFavorite || false, + userRating: null, + }; }; const normalizeAlbumArtist = ( - item: z.infer & { - similarArtists?: z.infer; - }, - server: ServerListItem | null, - imageSize?: number, + item: z.infer & { + similarArtists?: z.infer; + }, + server: ServerListItem | null, + imageSize?: number, ): AlbumArtist => { - const similarArtists = - item.similarArtists?.Items?.filter((entry) => entry.Name !== 'Various Artists').map( - (entry) => ({ - id: entry.Id, - imageUrl: getAlbumArtistCoverArtUrl({ - baseUrl: server?.url || '', - item: entry, - size: imageSize || 300, - }), - name: entry.Name, - }), - ) || []; + const similarArtists = + item.similarArtists?.Items?.filter((entry) => entry.Name !== 'Various Artists').map( + (entry) => ({ + id: entry.Id, + imageUrl: getAlbumArtistCoverArtUrl({ + baseUrl: server?.url || '', + item: entry, + size: imageSize || 300, + }), + name: entry.Name, + }), + ) || []; - return { - albumCount: null, - backgroundImageUrl: null, - biography: item.Overview || null, - duration: item.RunTimeTicks / 10000, - genres: item.GenreItems?.map((entry) => ({ id: entry.Id, name: entry.Name })), - id: item.Id, - imageUrl: getAlbumArtistCoverArtUrl({ - baseUrl: server?.url || '', - item, - size: imageSize || 300, - }), - itemType: LibraryItem.ALBUM_ARTIST, - lastPlayedAt: null, - name: item.Name, - playCount: item.UserData?.PlayCount || 0, - serverId: server?.id || '', - serverType: ServerType.JELLYFIN, - similarArtists, - songCount: null, - userFavorite: item.UserData?.IsFavorite || false, - userRating: null, - }; + return { + albumCount: null, + backgroundImageUrl: null, + biography: item.Overview || null, + duration: item.RunTimeTicks / 10000, + genres: item.GenreItems?.map((entry) => ({ id: entry.Id, name: entry.Name })), + id: item.Id, + imageUrl: getAlbumArtistCoverArtUrl({ + baseUrl: server?.url || '', + item, + size: imageSize || 300, + }), + itemType: LibraryItem.ALBUM_ARTIST, + lastPlayedAt: null, + name: item.Name, + playCount: item.UserData?.PlayCount || 0, + serverId: server?.id || '', + serverType: ServerType.JELLYFIN, + similarArtists, + songCount: null, + userFavorite: item.UserData?.IsFavorite || false, + userRating: null, + }; }; const normalizePlaylist = ( - item: z.infer, - server: ServerListItem | null, - imageSize?: number, + item: z.infer, + server: ServerListItem | null, + imageSize?: number, ): Playlist => { - const imageUrl = getPlaylistCoverArtUrl({ - baseUrl: server?.url || '', - item, - size: imageSize || 300, - }); + const imageUrl = getPlaylistCoverArtUrl({ + baseUrl: server?.url || '', + item, + size: imageSize || 300, + }); - const imagePlaceholderUrl = null; + const imagePlaceholderUrl = null; - return { - description: item.Overview || null, - duration: item.RunTimeTicks / 10000, - genres: item.GenreItems?.map((entry) => ({ id: entry.Id, name: entry.Name })), - id: item.Id, - imagePlaceholderUrl, - imageUrl: imageUrl || null, - itemType: LibraryItem.PLAYLIST, - name: item.Name, - owner: null, - ownerId: null, - public: null, - rules: null, - serverId: server?.id || '', - serverType: ServerType.JELLYFIN, - size: null, - songCount: item?.ChildCount || null, - sync: null, - }; + return { + description: item.Overview || null, + duration: item.RunTimeTicks / 10000, + genres: item.GenreItems?.map((entry) => ({ id: entry.Id, name: entry.Name })), + id: item.Id, + imagePlaceholderUrl, + imageUrl: imageUrl || null, + itemType: LibraryItem.PLAYLIST, + name: item.Name, + owner: null, + ownerId: null, + public: null, + rules: null, + serverId: server?.id || '', + serverType: ServerType.JELLYFIN, + size: null, + songCount: item?.ChildCount || null, + sync: null, + }; }; const normalizeMusicFolder = (item: JFMusicFolder): MusicFolder => { - return { - id: item.Id, - name: item.Name, - }; + return { + id: item.Id, + name: item.Name, + }; }; // const normalizeArtist = (item: any) => { @@ -332,12 +336,12 @@ const normalizeMusicFolder = (item: JFMusicFolder): MusicFolder => { // }; const normalizeGenre = (item: JFGenre): Genre => { - return { - albumCount: undefined, - id: item.Id, - name: item.Name, - songCount: undefined, - }; + return { + albumCount: undefined, + id: item.Id, + name: item.Name, + songCount: undefined, + }; }; // const normalizeFolder = (item: any) => { @@ -360,10 +364,10 @@ const normalizeGenre = (item: JFGenre): Genre => { // }; export const jfNormalize = { - album: normalizeAlbum, - albumArtist: normalizeAlbumArtist, - genre: normalizeGenre, - musicFolder: normalizeMusicFolder, - playlist: normalizePlaylist, - song: normalizeSong, + album: normalizeAlbum, + albumArtist: normalizeAlbumArtist, + genre: normalizeGenre, + musicFolder: normalizeMusicFolder, + playlist: normalizePlaylist, + song: normalizeSong, }; diff --git a/src/renderer/api/jellyfin/jellyfin-types.ts b/src/renderer/api/jellyfin/jellyfin-types.ts index 1173bfe6..4bc8b009 100644 --- a/src/renderer/api/jellyfin/jellyfin-types.ts +++ b/src/renderer/api/jellyfin/jellyfin-types.ts @@ -3,550 +3,550 @@ import { z } from 'zod'; const sortOrderValues = ['Ascending', 'Descending'] as const; const jfExternal = { - IMDB: 'Imdb', - MUSIC_BRAINZ: 'MusicBrainz', - THE_AUDIO_DB: 'TheAudioDb', - THE_MOVIE_DB: 'TheMovieDb', - TVDB: 'Tvdb', + IMDB: 'Imdb', + MUSIC_BRAINZ: 'MusicBrainz', + THE_AUDIO_DB: 'TheAudioDb', + THE_MOVIE_DB: 'TheMovieDb', + TVDB: 'Tvdb', }; const jfImage = { - BACKDROP: 'Backdrop', - BANNER: 'Banner', - BOX: 'Box', - CHAPTER: 'Chapter', - DISC: 'Disc', - LOGO: 'Logo', - PRIMARY: 'Primary', - THUMB: 'Thumb', + BACKDROP: 'Backdrop', + BANNER: 'Banner', + BOX: 'Box', + CHAPTER: 'Chapter', + DISC: 'Disc', + LOGO: 'Logo', + PRIMARY: 'Primary', + THUMB: 'Thumb', } as const; const jfCollection = { - MUSIC: 'music', - PLAYLISTS: 'playlists', + MUSIC: 'music', + PLAYLISTS: 'playlists', } as const; const error = z.object({ - errors: z.object({ - recursive: z.array(z.string()), - }), - status: z.number(), - title: z.string(), - traceId: z.string(), - type: z.string(), + errors: z.object({ + recursive: z.array(z.string()), + }), + status: z.number(), + title: z.string(), + traceId: z.string(), + type: z.string(), }); const baseParameters = z.object({ - AlbumArtistIds: z.string().optional(), - ArtistIds: z.string().optional(), - ContributingArtistIds: z.string().optional(), - EnableImageTypes: z.string().optional(), - EnableTotalRecordCount: z.boolean().optional(), - EnableUserData: z.boolean().optional(), - EnableUserDataTypes: z.boolean().optional(), - ExcludeArtistIds: z.string().optional(), - ExcludeItemIds: z.string().optional(), - ExcludeItemTypes: z.string().optional(), - Fields: z.string().optional(), - ImageTypeLimit: z.number().optional(), - IncludeArtists: z.boolean().optional(), - IncludeGenres: z.boolean().optional(), - IncludeItemTypes: z.string().optional(), - IncludeMedia: z.boolean().optional(), - IncludePeople: z.boolean().optional(), - IncludeStudios: z.boolean().optional(), - IsFavorite: z.boolean().optional(), - Limit: z.number().optional(), - MediaTypes: z.string().optional(), - NameStartsWith: z.string().optional(), - ParentId: z.string().optional(), - Recursive: z.boolean().optional(), - SearchTerm: z.string().optional(), - SortBy: z.string().optional(), - SortOrder: z.enum(sortOrderValues).optional(), - StartIndex: z.number().optional(), - Tags: z.string().optional(), - UserId: z.string().optional(), - Years: z.string().optional(), + AlbumArtistIds: z.string().optional(), + ArtistIds: z.string().optional(), + ContributingArtistIds: z.string().optional(), + EnableImageTypes: z.string().optional(), + EnableTotalRecordCount: z.boolean().optional(), + EnableUserData: z.boolean().optional(), + EnableUserDataTypes: z.boolean().optional(), + ExcludeArtistIds: z.string().optional(), + ExcludeItemIds: z.string().optional(), + ExcludeItemTypes: z.string().optional(), + Fields: z.string().optional(), + ImageTypeLimit: z.number().optional(), + IncludeArtists: z.boolean().optional(), + IncludeGenres: z.boolean().optional(), + IncludeItemTypes: z.string().optional(), + IncludeMedia: z.boolean().optional(), + IncludePeople: z.boolean().optional(), + IncludeStudios: z.boolean().optional(), + IsFavorite: z.boolean().optional(), + Limit: z.number().optional(), + MediaTypes: z.string().optional(), + NameStartsWith: z.string().optional(), + ParentId: z.string().optional(), + Recursive: z.boolean().optional(), + SearchTerm: z.string().optional(), + SortBy: z.string().optional(), + SortOrder: z.enum(sortOrderValues).optional(), + StartIndex: z.number().optional(), + Tags: z.string().optional(), + UserId: z.string().optional(), + Years: z.string().optional(), }); const paginationParameters = z.object({ - Limit: z.number().optional(), - SortOrder: z.enum(sortOrderValues).optional(), - StartIndex: z.number().optional(), + Limit: z.number().optional(), + SortOrder: z.enum(sortOrderValues).optional(), + StartIndex: z.number().optional(), }); const pagination = z.object({ - StartIndex: z.number(), - TotalRecordCount: z.number(), + StartIndex: z.number(), + TotalRecordCount: z.number(), }); const imageTags = z.object({ - Logo: z.string().optional(), - Primary: z.string().optional(), + Logo: z.string().optional(), + Primary: z.string().optional(), }); const imageBlurHashes = z.object({ - Backdrop: z.record(z.string(), z.string()).optional(), - Logo: z.record(z.string(), z.string()).optional(), - Primary: z.record(z.string(), z.string()).optional(), + Backdrop: z.record(z.string(), z.string()).optional(), + Logo: z.record(z.string(), z.string()).optional(), + Primary: z.record(z.string(), z.string()).optional(), }); const userData = z.object({ - IsFavorite: z.boolean(), - Key: z.string(), - PlayCount: z.number(), - PlaybackPositionTicks: z.number(), - Played: z.boolean(), + IsFavorite: z.boolean(), + Key: z.string(), + PlayCount: z.number(), + PlaybackPositionTicks: z.number(), + Played: z.boolean(), }); const externalUrl = z.object({ - Name: z.string(), - Url: z.string(), + Name: z.string(), + Url: z.string(), }); const mediaStream = z.object({ - AspectRatio: z.string().optional(), - BitDepth: z.number().optional(), - BitRate: z.number().optional(), - ChannelLayout: z.string().optional(), - Channels: z.number().optional(), - Codec: z.string(), - CodecTimeBase: z.string(), - ColorSpace: z.string().optional(), - Comment: z.string().optional(), - DisplayTitle: z.string().optional(), - Height: z.number().optional(), - Index: z.number(), - IsDefault: z.boolean(), - IsExternal: z.boolean(), - IsForced: z.boolean(), - IsInterlaced: z.boolean(), - IsTextSubtitleStream: z.boolean(), - Level: z.number(), - PixelFormat: z.string().optional(), - Profile: z.string().optional(), - RealFrameRate: z.number().optional(), - RefFrames: z.number().optional(), - SampleRate: z.number().optional(), - SupportsExternalStream: z.boolean(), - TimeBase: z.string(), - Type: z.string(), - Width: z.number().optional(), + AspectRatio: z.string().optional(), + BitDepth: z.number().optional(), + BitRate: z.number().optional(), + ChannelLayout: z.string().optional(), + Channels: z.number().optional(), + Codec: z.string(), + CodecTimeBase: z.string(), + ColorSpace: z.string().optional(), + Comment: z.string().optional(), + DisplayTitle: z.string().optional(), + Height: z.number().optional(), + Index: z.number(), + IsDefault: z.boolean(), + IsExternal: z.boolean(), + IsForced: z.boolean(), + IsInterlaced: z.boolean(), + IsTextSubtitleStream: z.boolean(), + Level: z.number(), + PixelFormat: z.string().optional(), + Profile: z.string().optional(), + RealFrameRate: z.number().optional(), + RefFrames: z.number().optional(), + SampleRate: z.number().optional(), + SupportsExternalStream: z.boolean(), + TimeBase: z.string(), + Type: z.string(), + Width: z.number().optional(), }); const mediaSources = z.object({ - Bitrate: z.number(), - Container: z.string(), - DefaultAudioStreamIndex: z.number(), - ETag: z.string(), - Formats: z.array(z.any()), - GenPtsInput: z.boolean(), - Id: z.string(), - IgnoreDts: z.boolean(), - IgnoreIndex: z.boolean(), - IsInfiniteStream: z.boolean(), - IsRemote: z.boolean(), - MediaAttachments: z.array(z.any()), - MediaStreams: z.array(mediaStream), - Name: z.string(), - Path: z.string(), - Protocol: z.string(), - ReadAtNativeFramerate: z.boolean(), - RequiredHttpHeaders: z.any(), - RequiresClosing: z.boolean(), - RequiresLooping: z.boolean(), - RequiresOpening: z.boolean(), - RunTimeTicks: z.number(), - Size: z.number(), - SupportsDirectPlay: z.boolean(), - SupportsDirectStream: z.boolean(), - SupportsProbing: z.boolean(), - SupportsTranscoding: z.boolean(), - Type: z.string(), + Bitrate: z.number(), + Container: z.string(), + DefaultAudioStreamIndex: z.number(), + ETag: z.string(), + Formats: z.array(z.any()), + GenPtsInput: z.boolean(), + Id: z.string(), + IgnoreDts: z.boolean(), + IgnoreIndex: z.boolean(), + IsInfiniteStream: z.boolean(), + IsRemote: z.boolean(), + MediaAttachments: z.array(z.any()), + MediaStreams: z.array(mediaStream), + Name: z.string(), + Path: z.string(), + Protocol: z.string(), + ReadAtNativeFramerate: z.boolean(), + RequiredHttpHeaders: z.any(), + RequiresClosing: z.boolean(), + RequiresLooping: z.boolean(), + RequiresOpening: z.boolean(), + RunTimeTicks: z.number(), + Size: z.number(), + SupportsDirectPlay: z.boolean(), + SupportsDirectStream: z.boolean(), + SupportsProbing: z.boolean(), + SupportsTranscoding: z.boolean(), + Type: z.string(), }); const sessionInfo = z.object({ - AdditionalUsers: z.array(z.any()), - ApplicationVersion: z.string(), - Capabilities: z.object({ + AdditionalUsers: z.array(z.any()), + ApplicationVersion: z.string(), + Capabilities: z.object({ + PlayableMediaTypes: z.array(z.any()), + SupportedCommands: z.array(z.any()), + SupportsContentUploading: z.boolean(), + SupportsMediaControl: z.boolean(), + SupportsPersistentIdentifier: z.boolean(), + SupportsSync: z.boolean(), + }), + Client: z.string(), + DeviceId: z.string(), + DeviceName: z.string(), + HasCustomDeviceName: z.boolean(), + Id: z.string(), + IsActive: z.boolean(), + LastActivityDate: z.string(), + LastPlaybackCheckIn: z.string(), + NowPlayingQueue: z.array(z.any()), + NowPlayingQueueFullItems: z.array(z.any()), + PlayState: z.object({ + CanSeek: z.boolean(), + IsMuted: z.boolean(), + IsPaused: z.boolean(), + RepeatMode: z.string(), + }), PlayableMediaTypes: z.array(z.any()), + RemoteEndPoint: z.string(), + ServerId: z.string(), SupportedCommands: z.array(z.any()), - SupportsContentUploading: z.boolean(), SupportsMediaControl: z.boolean(), - SupportsPersistentIdentifier: z.boolean(), - SupportsSync: z.boolean(), - }), - Client: z.string(), - DeviceId: z.string(), - DeviceName: z.string(), - HasCustomDeviceName: z.boolean(), - Id: z.string(), - IsActive: z.boolean(), - LastActivityDate: z.string(), - LastPlaybackCheckIn: z.string(), - NowPlayingQueue: z.array(z.any()), - NowPlayingQueueFullItems: z.array(z.any()), - PlayState: z.object({ - CanSeek: z.boolean(), - IsMuted: z.boolean(), - IsPaused: z.boolean(), - RepeatMode: z.string(), - }), - PlayableMediaTypes: z.array(z.any()), - RemoteEndPoint: z.string(), - ServerId: z.string(), - SupportedCommands: z.array(z.any()), - SupportsMediaControl: z.boolean(), - SupportsRemoteControl: z.boolean(), - UserId: z.string(), - UserName: z.string(), + SupportsRemoteControl: z.boolean(), + UserId: z.string(), + UserName: z.string(), }); const configuration = z.object({ - DisplayCollectionsView: z.boolean(), - DisplayMissingEpisodes: z.boolean(), - EnableLocalPassword: z.boolean(), - EnableNextEpisodeAutoPlay: z.boolean(), - GroupedFolders: z.array(z.any()), - HidePlayedInLatest: z.boolean(), - LatestItemsExcludes: z.array(z.any()), - MyMediaExcludes: z.array(z.any()), - OrderedViews: z.array(z.any()), - PlayDefaultAudioTrack: z.boolean(), - RememberAudioSelections: z.boolean(), - RememberSubtitleSelections: z.boolean(), - SubtitleLanguagePreference: z.string(), - SubtitleMode: z.string(), + DisplayCollectionsView: z.boolean(), + DisplayMissingEpisodes: z.boolean(), + EnableLocalPassword: z.boolean(), + EnableNextEpisodeAutoPlay: z.boolean(), + GroupedFolders: z.array(z.any()), + HidePlayedInLatest: z.boolean(), + LatestItemsExcludes: z.array(z.any()), + MyMediaExcludes: z.array(z.any()), + OrderedViews: z.array(z.any()), + PlayDefaultAudioTrack: z.boolean(), + RememberAudioSelections: z.boolean(), + RememberSubtitleSelections: z.boolean(), + SubtitleLanguagePreference: z.string(), + SubtitleMode: z.string(), }); const policy = z.object({ - AccessSchedules: z.array(z.any()), - AuthenticationProviderId: z.string(), - BlockUnratedItems: z.array(z.any()), - BlockedChannels: z.array(z.any()), - BlockedMediaFolders: z.array(z.any()), - BlockedTags: z.array(z.any()), - EnableAllChannels: z.boolean(), - EnableAllDevices: z.boolean(), - EnableAllFolders: z.boolean(), - EnableAudioPlaybackTranscoding: z.boolean(), - EnableContentDeletion: z.boolean(), - EnableContentDeletionFromFolders: z.array(z.any()), - EnableContentDownloading: z.boolean(), - EnableLiveTvAccess: z.boolean(), - EnableLiveTvManagement: z.boolean(), - EnableMediaConversion: z.boolean(), - EnableMediaPlayback: z.boolean(), - EnablePlaybackRemuxing: z.boolean(), - EnablePublicSharing: z.boolean(), - EnableRemoteAccess: z.boolean(), - EnableRemoteControlOfOtherUsers: z.boolean(), - EnableSharedDeviceControl: z.boolean(), - EnableSyncTranscoding: z.boolean(), - EnableUserPreferenceAccess: z.boolean(), - EnableVideoPlaybackTranscoding: z.boolean(), - EnabledChannels: z.array(z.any()), - EnabledDevices: z.array(z.any()), - EnabledFolders: z.array(z.any()), - ForceRemoteSourceTranscoding: z.boolean(), - InvalidLoginAttemptCount: z.number(), - IsAdministrator: z.boolean(), - IsDisabled: z.boolean(), - IsHidden: z.boolean(), - LoginAttemptsBeforeLockout: z.number(), - MaxActiveSessions: z.number(), - PasswordResetProviderId: z.string(), - RemoteClientBitrateLimit: z.number(), - SyncPlayAccess: z.string(), + AccessSchedules: z.array(z.any()), + AuthenticationProviderId: z.string(), + BlockUnratedItems: z.array(z.any()), + BlockedChannels: z.array(z.any()), + BlockedMediaFolders: z.array(z.any()), + BlockedTags: z.array(z.any()), + EnableAllChannels: z.boolean(), + EnableAllDevices: z.boolean(), + EnableAllFolders: z.boolean(), + EnableAudioPlaybackTranscoding: z.boolean(), + EnableContentDeletion: z.boolean(), + EnableContentDeletionFromFolders: z.array(z.any()), + EnableContentDownloading: z.boolean(), + EnableLiveTvAccess: z.boolean(), + EnableLiveTvManagement: z.boolean(), + EnableMediaConversion: z.boolean(), + EnableMediaPlayback: z.boolean(), + EnablePlaybackRemuxing: z.boolean(), + EnablePublicSharing: z.boolean(), + EnableRemoteAccess: z.boolean(), + EnableRemoteControlOfOtherUsers: z.boolean(), + EnableSharedDeviceControl: z.boolean(), + EnableSyncTranscoding: z.boolean(), + EnableUserPreferenceAccess: z.boolean(), + EnableVideoPlaybackTranscoding: z.boolean(), + EnabledChannels: z.array(z.any()), + EnabledDevices: z.array(z.any()), + EnabledFolders: z.array(z.any()), + ForceRemoteSourceTranscoding: z.boolean(), + InvalidLoginAttemptCount: z.number(), + IsAdministrator: z.boolean(), + IsDisabled: z.boolean(), + IsHidden: z.boolean(), + LoginAttemptsBeforeLockout: z.number(), + MaxActiveSessions: z.number(), + PasswordResetProviderId: z.string(), + RemoteClientBitrateLimit: z.number(), + SyncPlayAccess: z.string(), }); const user = z.object({ - Configuration: configuration, - EnableAutoLogin: z.boolean(), - HasConfiguredEasyPassword: z.boolean(), - HasConfiguredPassword: z.boolean(), - HasPassword: z.boolean(), - Id: z.string(), - LastActivityDate: z.string(), - LastLoginDate: z.string(), - Name: z.string(), - Policy: policy, - ServerId: z.string(), + Configuration: configuration, + EnableAutoLogin: z.boolean(), + HasConfiguredEasyPassword: z.boolean(), + HasConfiguredPassword: z.boolean(), + HasPassword: z.boolean(), + Id: z.string(), + LastActivityDate: z.string(), + LastLoginDate: z.string(), + Name: z.string(), + Policy: policy, + ServerId: z.string(), }); const authenticateParameters = z.object({ - Pw: z.string(), - Username: z.string(), + Pw: z.string(), + Username: z.string(), }); const authenticate = z.object({ - AccessToken: z.string(), - ServerId: z.string(), - SessionInfo: sessionInfo, - User: user, + AccessToken: z.string(), + ServerId: z.string(), + SessionInfo: sessionInfo, + User: user, }); const genreItem = z.object({ - Id: z.string(), - Name: z.string(), + Id: z.string(), + Name: z.string(), }); const genre = z.object({ - BackdropImageTags: z.array(z.any()), - ChannelId: z.null(), - Id: z.string(), - ImageBlurHashes: imageBlurHashes, - ImageTags: imageTags, - LocationType: z.string(), - Name: z.string(), - ServerId: z.string(), - Type: z.string(), + BackdropImageTags: z.array(z.any()), + ChannelId: z.null(), + Id: z.string(), + ImageBlurHashes: imageBlurHashes, + ImageTags: imageTags, + LocationType: z.string(), + Name: z.string(), + ServerId: z.string(), + Type: z.string(), }); const genreList = z.object({ - Items: z.array(genre), + Items: z.array(genre), }); const musicFolder = z.object({ - BackdropImageTags: z.array(z.string()), - ChannelId: z.null(), - CollectionType: z.string(), - Id: z.string(), - ImageBlurHashes: imageBlurHashes, - ImageTags: imageTags, - IsFolder: z.boolean(), - LocationType: z.string(), - Name: z.string(), - ServerId: z.string(), - Type: z.string(), - UserData: userData, + BackdropImageTags: z.array(z.string()), + ChannelId: z.null(), + CollectionType: z.string(), + Id: z.string(), + ImageBlurHashes: imageBlurHashes, + ImageTags: imageTags, + IsFolder: z.boolean(), + LocationType: z.string(), + Name: z.string(), + ServerId: z.string(), + Type: z.string(), + UserData: userData, }); const musicFolderListParameters = z.object({ - UserId: z.string(), + UserId: z.string(), }); const musicFolderList = z.object({ - Items: z.array(musicFolder), + Items: z.array(musicFolder), }); const playlist = z.object({ - BackdropImageTags: z.array(z.string()), - ChannelId: z.null(), - ChildCount: z.number().optional(), - DateCreated: z.string(), - GenreItems: z.array(genreItem), - Genres: z.array(z.string()), - Id: z.string(), - ImageBlurHashes: imageBlurHashes, - ImageTags: imageTags, - IsFolder: z.boolean(), - LocationType: z.string(), - MediaType: z.string(), - Name: z.string(), - Overview: z.string().optional(), - RunTimeTicks: z.number(), - ServerId: z.string(), - Type: z.string(), - UserData: userData, + BackdropImageTags: z.array(z.string()), + ChannelId: z.null(), + ChildCount: z.number().optional(), + DateCreated: z.string(), + GenreItems: z.array(genreItem), + Genres: z.array(z.string()), + Id: z.string(), + ImageBlurHashes: imageBlurHashes, + ImageTags: imageTags, + IsFolder: z.boolean(), + LocationType: z.string(), + MediaType: z.string(), + Name: z.string(), + Overview: z.string().optional(), + RunTimeTicks: z.number(), + ServerId: z.string(), + Type: z.string(), + UserData: userData, }); const jfPlaylistListSort = { - ALBUM_ARTIST: 'AlbumArtist,SortName', - DURATION: 'Runtime', - NAME: 'SortName', - RECENTLY_ADDED: 'DateCreated,SortName', - SONG_COUNT: 'ChildCount', + ALBUM_ARTIST: 'AlbumArtist,SortName', + DURATION: 'Runtime', + NAME: 'SortName', + RECENTLY_ADDED: 'DateCreated,SortName', + SONG_COUNT: 'ChildCount', } as const; const playlistListParameters = paginationParameters.merge( - baseParameters.extend({ - IncludeItemTypes: z.literal('Playlist'), - SortBy: z.nativeEnum(jfPlaylistListSort).optional(), - }), + baseParameters.extend({ + IncludeItemTypes: z.literal('Playlist'), + SortBy: z.nativeEnum(jfPlaylistListSort).optional(), + }), ); const playlistList = pagination.extend({ - Items: z.array(playlist), + Items: z.array(playlist), }); const genericItem = z.object({ - Id: z.string(), - Name: z.string(), + Id: z.string(), + Name: z.string(), }); const song = z.object({ - Album: z.string(), - AlbumArtist: z.string(), - AlbumArtists: z.array(genericItem), - AlbumId: z.string(), - AlbumPrimaryImageTag: z.string(), - ArtistItems: z.array(genericItem), - Artists: z.array(z.string()), - BackdropImageTags: z.array(z.string()), - ChannelId: z.null(), - DateCreated: z.string(), - ExternalUrls: z.array(externalUrl), - GenreItems: z.array(genericItem), - Genres: z.array(z.string()), - Id: z.string(), - ImageBlurHashes: imageBlurHashes, - ImageTags: imageTags, - IndexNumber: z.number(), - IsFolder: z.boolean(), - LocationType: z.string(), - MediaSources: z.array(mediaSources), - MediaType: z.string(), - Name: z.string(), - ParentIndexNumber: z.number(), - PlaylistItemId: z.string().optional(), - PremiereDate: z.string().optional(), - ProductionYear: z.number(), - RunTimeTicks: z.number(), - ServerId: z.string(), - SortName: z.string(), - Type: z.string(), - UserData: userData.optional(), + Album: z.string(), + AlbumArtist: z.string(), + AlbumArtists: z.array(genericItem), + AlbumId: z.string(), + AlbumPrimaryImageTag: z.string(), + ArtistItems: z.array(genericItem), + Artists: z.array(z.string()), + BackdropImageTags: z.array(z.string()), + ChannelId: z.null(), + DateCreated: z.string(), + ExternalUrls: z.array(externalUrl), + GenreItems: z.array(genericItem), + Genres: z.array(z.string()), + Id: z.string(), + ImageBlurHashes: imageBlurHashes, + ImageTags: imageTags, + IndexNumber: z.number(), + IsFolder: z.boolean(), + LocationType: z.string(), + MediaSources: z.array(mediaSources), + MediaType: z.string(), + Name: z.string(), + ParentIndexNumber: z.number(), + PlaylistItemId: z.string().optional(), + PremiereDate: z.string().optional(), + ProductionYear: z.number(), + RunTimeTicks: z.number(), + ServerId: z.string(), + SortName: z.string(), + Type: z.string(), + UserData: userData.optional(), }); const albumArtist = z.object({ - BackdropImageTags: z.array(z.string()), - ChannelId: z.null(), - DateCreated: z.string(), - ExternalUrls: z.array(externalUrl), - GenreItems: z.array(genreItem), - Genres: z.array(z.string()), - Id: z.string(), - ImageBlurHashes: imageBlurHashes, - ImageTags: imageTags, - LocationType: z.string(), - Name: z.string(), - Overview: z.string(), - RunTimeTicks: z.number(), - ServerId: z.string(), - Type: z.string(), - UserData: userData.optional(), + BackdropImageTags: z.array(z.string()), + ChannelId: z.null(), + DateCreated: z.string(), + ExternalUrls: z.array(externalUrl), + GenreItems: z.array(genreItem), + Genres: z.array(z.string()), + Id: z.string(), + ImageBlurHashes: imageBlurHashes, + ImageTags: imageTags, + LocationType: z.string(), + Name: z.string(), + Overview: z.string(), + RunTimeTicks: z.number(), + ServerId: z.string(), + Type: z.string(), + UserData: userData.optional(), }); const albumDetailParameters = baseParameters; const album = z.object({ - AlbumArtist: z.string(), - AlbumArtists: z.array(genericItem), - AlbumPrimaryImageTag: z.string(), - ArtistItems: z.array(genericItem), - Artists: z.array(z.string()), - ChannelId: z.null(), - ChildCount: z.number().optional(), - DateCreated: z.string(), - DateLastMediaAdded: z.string().optional(), - ExternalUrls: z.array(externalUrl), - GenreItems: z.array(genericItem), - Genres: z.array(z.string()), - Id: z.string(), - ImageBlurHashes: imageBlurHashes, - ImageTags: imageTags, - IsFolder: z.boolean(), - LocationType: z.string(), - Name: z.string(), - ParentLogoImageTag: z.string(), - ParentLogoItemId: z.string(), - PremiereDate: z.string().optional(), - ProductionYear: z.number(), - RunTimeTicks: z.number(), - ServerId: z.string(), - Songs: z.array(song).optional(), // This is not a native Jellyfin property -- this is used for combined album detail - Type: z.string(), - UserData: userData.optional(), + AlbumArtist: z.string(), + AlbumArtists: z.array(genericItem), + AlbumPrimaryImageTag: z.string(), + ArtistItems: z.array(genericItem), + Artists: z.array(z.string()), + ChannelId: z.null(), + ChildCount: z.number().optional(), + DateCreated: z.string(), + DateLastMediaAdded: z.string().optional(), + ExternalUrls: z.array(externalUrl), + GenreItems: z.array(genericItem), + Genres: z.array(z.string()), + Id: z.string(), + ImageBlurHashes: imageBlurHashes, + ImageTags: imageTags, + IsFolder: z.boolean(), + LocationType: z.string(), + Name: z.string(), + ParentLogoImageTag: z.string(), + ParentLogoItemId: z.string(), + PremiereDate: z.string().optional(), + ProductionYear: z.number(), + RunTimeTicks: z.number(), + ServerId: z.string(), + Songs: z.array(song).optional(), // This is not a native Jellyfin property -- this is used for combined album detail + Type: z.string(), + UserData: userData.optional(), }); const jfAlbumListSort = { - ALBUM_ARTIST: 'AlbumArtist,SortName', - COMMUNITY_RATING: 'CommunityRating,SortName', - CRITIC_RATING: 'CriticRating,SortName', - NAME: 'SortName', - RANDOM: 'Random,SortName', - RECENTLY_ADDED: 'DateCreated,SortName', - RELEASE_DATE: 'ProductionYear,PremiereDate,SortName', + ALBUM_ARTIST: 'AlbumArtist,SortName', + COMMUNITY_RATING: 'CommunityRating,SortName', + CRITIC_RATING: 'CriticRating,SortName', + NAME: 'SortName', + RANDOM: 'Random,SortName', + RECENTLY_ADDED: 'DateCreated,SortName', + RELEASE_DATE: 'ProductionYear,PremiereDate,SortName', } as const; const albumListParameters = paginationParameters.merge( - baseParameters.extend({ - Filters: z.string().optional(), - GenreIds: z.string().optional(), - Genres: z.string().optional(), - IncludeItemTypes: z.literal('MusicAlbum'), - IsFavorite: z.boolean().optional(), - SearchTerm: z.string().optional(), - SortBy: z.nativeEnum(jfAlbumListSort).optional(), - Tags: z.string().optional(), - Years: z.string().optional(), - }), + baseParameters.extend({ + Filters: z.string().optional(), + GenreIds: z.string().optional(), + Genres: z.string().optional(), + IncludeItemTypes: z.literal('MusicAlbum'), + IsFavorite: z.boolean().optional(), + SearchTerm: z.string().optional(), + SortBy: z.nativeEnum(jfAlbumListSort).optional(), + Tags: z.string().optional(), + Years: z.string().optional(), + }), ); const albumList = pagination.extend({ - Items: z.array(album), + Items: z.array(album), }); const jfAlbumArtistListSort = { - ALBUM: 'Album,SortName', - DURATION: 'Runtime,AlbumArtist,Album,SortName', - NAME: 'Name,SortName', - RANDOM: 'Random,SortName', - RECENTLY_ADDED: 'DateCreated,SortName', - RELEASE_DATE: 'PremiereDate,AlbumArtist,Album,SortName', + ALBUM: 'Album,SortName', + DURATION: 'Runtime,AlbumArtist,Album,SortName', + NAME: 'Name,SortName', + RANDOM: 'Random,SortName', + RECENTLY_ADDED: 'DateCreated,SortName', + RELEASE_DATE: 'PremiereDate,AlbumArtist,Album,SortName', } as const; const albumArtistListParameters = paginationParameters.merge( - baseParameters.extend({ - Filters: z.string().optional(), - Genres: z.string().optional(), - SortBy: z.nativeEnum(jfAlbumArtistListSort).optional(), - Years: z.string().optional(), - }), + baseParameters.extend({ + Filters: z.string().optional(), + Genres: z.string().optional(), + SortBy: z.nativeEnum(jfAlbumArtistListSort).optional(), + Years: z.string().optional(), + }), ); const albumArtistList = pagination.extend({ - Items: z.array(albumArtist), + Items: z.array(albumArtist), }); const similarArtistListParameters = baseParameters.extend({ - Limit: z.number().optional(), + Limit: z.number().optional(), }); const jfSongListSort = { - ALBUM: 'Album,SortName', - ALBUM_ARTIST: 'AlbumArtist,Album,SortName', - ARTIST: 'Artist,Album,SortName', - COMMUNITY_RATING: 'CommunityRating,SortName', - DURATION: 'Runtime,AlbumArtist,Album,SortName', - NAME: 'Name,SortName', - PLAY_COUNT: 'PlayCount,SortName', - RANDOM: 'Random,SortName', - RECENTLY_ADDED: 'DateCreated,SortName', - RECENTLY_PLAYED: 'DatePlayed,SortName', - RELEASE_DATE: 'PremiereDate,AlbumArtist,Album,SortName', + ALBUM: 'Album,SortName', + ALBUM_ARTIST: 'AlbumArtist,Album,SortName', + ARTIST: 'Artist,Album,SortName', + COMMUNITY_RATING: 'CommunityRating,SortName', + DURATION: 'Runtime,AlbumArtist,Album,SortName', + NAME: 'Name,SortName', + PLAY_COUNT: 'PlayCount,SortName', + RANDOM: 'Random,SortName', + RECENTLY_ADDED: 'DateCreated,SortName', + RECENTLY_PLAYED: 'DatePlayed,SortName', + RELEASE_DATE: 'PremiereDate,AlbumArtist,Album,SortName', } as const; const songListParameters = paginationParameters.merge( - baseParameters.extend({ - AlbumArtistIds: z.string().optional(), - AlbumIds: z.string().optional(), - ArtistIds: z.string().optional(), - Filters: z.string().optional(), - GenreIds: z.string().optional(), - Genres: z.string().optional(), - IsFavorite: z.boolean().optional(), - SearchTerm: z.string().optional(), - SortBy: z.nativeEnum(jfSongListSort).optional(), - Tags: z.string().optional(), - Years: z.string().optional(), - }), + baseParameters.extend({ + AlbumArtistIds: z.string().optional(), + AlbumIds: z.string().optional(), + ArtistIds: z.string().optional(), + Filters: z.string().optional(), + GenreIds: z.string().optional(), + Genres: z.string().optional(), + IsFavorite: z.boolean().optional(), + SearchTerm: z.string().optional(), + SortBy: z.nativeEnum(jfSongListSort).optional(), + Tags: z.string().optional(), + Years: z.string().optional(), + }), ); const songList = pagination.extend({ - Items: z.array(song), + Items: z.array(song), }); const playlistSongList = songList; @@ -554,75 +554,75 @@ const playlistSongList = songList; const topSongsList = songList; const playlistDetailParameters = baseParameters.extend({ - Ids: z.string(), + Ids: z.string(), }); const createPlaylistParameters = z.object({ - MediaType: z.literal('Audio'), - Name: z.string(), - Overview: z.string(), - UserId: z.string(), + MediaType: z.literal('Audio'), + Name: z.string(), + Overview: z.string(), + UserId: z.string(), }); const createPlaylist = z.object({ - Id: z.string(), + Id: z.string(), }); const updatePlaylist = z.null(); const updatePlaylistParameters = z.object({ - Genres: z.array(genreItem), - MediaType: z.literal('Audio'), - Name: z.string(), - Overview: z.string(), - PremiereDate: z.null(), - ProviderIds: z.object({}), - Tags: z.array(genericItem), - UserId: z.string(), + Genres: z.array(genreItem), + MediaType: z.literal('Audio'), + Name: z.string(), + Overview: z.string(), + PremiereDate: z.null(), + ProviderIds: z.object({}), + Tags: z.array(genericItem), + UserId: z.string(), }); const addToPlaylist = z.object({ - Added: z.number(), + Added: z.number(), }); const addToPlaylistParameters = z.object({ - Ids: z.array(z.string()), - UserId: z.string(), + Ids: z.array(z.string()), + UserId: z.string(), }); const removeFromPlaylist = z.null(); const removeFromPlaylistParameters = z.object({ - EntryIds: z.array(z.string()), + EntryIds: z.array(z.string()), }); const deletePlaylist = z.null(); const deletePlaylistParameters = z.object({ - Id: z.string(), + Id: z.string(), }); const scrobbleParameters = z.object({ - EventName: z.string().optional(), - IsPaused: z.boolean().optional(), - ItemId: z.string(), - PositionTicks: z.number().optional(), + EventName: z.string().optional(), + IsPaused: z.boolean().optional(), + ItemId: z.string(), + PositionTicks: z.number().optional(), }); const scrobble = z.any(); const favorite = z.object({ - IsFavorite: z.boolean(), - ItemId: z.string(), - Key: z.string(), - LastPlayedDate: z.string(), - Likes: z.boolean(), - PlayCount: z.number(), - PlaybackPositionTicks: z.number(), - Played: z.boolean(), - PlayedPercentage: z.number(), - Rating: z.number(), - UnplayedItemCount: z.number(), + IsFavorite: z.boolean(), + ItemId: z.string(), + Key: z.string(), + LastPlayedDate: z.string(), + Likes: z.boolean(), + PlayCount: z.number(), + PlaybackPositionTicks: z.number(), + Played: z.boolean(), + PlayedPercentage: z.number(), + Rating: z.number(), + UnplayedItemCount: z.number(), }); const favoriteParameters = z.object({}); @@ -632,65 +632,65 @@ const searchParameters = paginationParameters.merge(baseParameters); const search = z.any(); const lyricText = z.object({ - Start: z.number().optional(), - Text: z.string(), + Start: z.number().optional(), + Text: z.string(), }); const lyrics = z.object({ - Lyrics: z.array(lyricText), + Lyrics: z.array(lyricText), }); export const jfType = { - _enum: { - collection: jfCollection, - external: jfExternal, - image: jfImage, - }, - _parameters: { - addToPlaylist: addToPlaylistParameters, - albumArtistDetail: baseParameters, - albumArtistList: albumArtistListParameters, - albumDetail: albumDetailParameters, - albumList: albumListParameters, - authenticate: authenticateParameters, - createPlaylist: createPlaylistParameters, - deletePlaylist: deletePlaylistParameters, - favorite: favoriteParameters, - musicFolderList: musicFolderListParameters, - playlistDetail: playlistDetailParameters, - playlistList: playlistListParameters, - removeFromPlaylist: removeFromPlaylistParameters, - scrobble: scrobbleParameters, - search: searchParameters, - similarArtistList: similarArtistListParameters, - songList: songListParameters, - updatePlaylist: updatePlaylistParameters, - }, - _response: { - addToPlaylist, - album, - albumArtist, - albumArtistList, - albumList, - authenticate, - createPlaylist, - deletePlaylist, - error, - favorite, - genre, - genreList, - lyrics, - musicFolderList, - playlist, - playlistList, - playlistSongList, - removeFromPlaylist, - scrobble, - search, - song, - songList, - topSongsList, - updatePlaylist, - user, - }, + _enum: { + collection: jfCollection, + external: jfExternal, + image: jfImage, + }, + _parameters: { + addToPlaylist: addToPlaylistParameters, + albumArtistDetail: baseParameters, + albumArtistList: albumArtistListParameters, + albumDetail: albumDetailParameters, + albumList: albumListParameters, + authenticate: authenticateParameters, + createPlaylist: createPlaylistParameters, + deletePlaylist: deletePlaylistParameters, + favorite: favoriteParameters, + musicFolderList: musicFolderListParameters, + playlistDetail: playlistDetailParameters, + playlistList: playlistListParameters, + removeFromPlaylist: removeFromPlaylistParameters, + scrobble: scrobbleParameters, + search: searchParameters, + similarArtistList: similarArtistListParameters, + songList: songListParameters, + updatePlaylist: updatePlaylistParameters, + }, + _response: { + addToPlaylist, + album, + albumArtist, + albumArtistList, + albumList, + authenticate, + createPlaylist, + deletePlaylist, + error, + favorite, + genre, + genreList, + lyrics, + musicFolderList, + playlist, + playlistList, + playlistSongList, + removeFromPlaylist, + scrobble, + search, + song, + songList, + topSongsList, + updatePlaylist, + user, + }, }; diff --git a/src/renderer/api/navidrome.types.ts b/src/renderer/api/navidrome.types.ts index de3bff18..8e276125 100644 --- a/src/renderer/api/navidrome.types.ts +++ b/src/renderer/api/navidrome.types.ts @@ -1,143 +1,143 @@ import { SSArtistInfo } from '/@/renderer/api/subsonic.types'; export type NDAuthenticate = { - id: string; - isAdmin: boolean; - name: string; - subsonicSalt: string; - subsonicToken: string; - token: string; - username: string; + id: string; + isAdmin: boolean; + name: string; + subsonicSalt: string; + subsonicToken: string; + token: string; + username: string; }; export type NDUser = { - createdAt: string; - email: string; - id: string; - isAdmin: boolean; - lastAccessAt: string; - lastLoginAt: string; - name: string; - updatedAt: string; - userName: string; + createdAt: string; + email: string; + id: string; + isAdmin: boolean; + lastAccessAt: string; + lastLoginAt: string; + name: string; + updatedAt: string; + userName: string; }; export type NDGenre = { - id: string; - name: string; + id: string; + name: string; }; export type NDAlbum = { - albumArtist: string; - albumArtistId: string; - allArtistIds: string; - artist: string; - artistId: string; - compilation: boolean; - coverArtId?: string; // Removed after v0.48.0 - coverArtPath?: string; // Removed after v0.48.0 - createdAt: string; - duration: number; - fullText: string; - genre: string; - genres: NDGenre[]; - id: string; - maxYear: number; - mbzAlbumArtistId: string; - mbzAlbumId: string; - minYear: number; - name: string; - orderAlbumArtistName: string; - orderAlbumName: string; - playCount: number; - playDate: string; - rating: number; - size: number; - songCount: number; - sortAlbumArtistName: string; - sortArtistName: string; - starred: boolean; - starredAt: string; - updatedAt: string; + albumArtist: string; + albumArtistId: string; + allArtistIds: string; + artist: string; + artistId: string; + compilation: boolean; + coverArtId?: string; // Removed after v0.48.0 + coverArtPath?: string; // Removed after v0.48.0 + createdAt: string; + duration: number; + fullText: string; + genre: string; + genres: NDGenre[]; + id: string; + maxYear: number; + mbzAlbumArtistId: string; + mbzAlbumId: string; + minYear: number; + name: string; + orderAlbumArtistName: string; + orderAlbumName: string; + playCount: number; + playDate: string; + rating: number; + size: number; + songCount: number; + sortAlbumArtistName: string; + sortArtistName: string; + starred: boolean; + starredAt: string; + updatedAt: string; } & { songs?: NDSong[] }; export type NDSong = { - album: string; - albumArtist: string; - albumArtistId: string; - albumId: string; - artist: string; - artistId: string; - bitRate: number; - bookmarkPosition: number; - bpm?: number; - channels?: number; - comment?: string; - compilation: boolean; - createdAt: string; - discNumber: number; - duration: number; - fullText: string; - genre: string; - genres: NDGenre[]; - hasCoverArt: boolean; - id: string; - lyrics?: string; - mbzAlbumArtistId: string; - mbzAlbumId: string; - mbzArtistId: string; - mbzTrackId: string; - orderAlbumArtistName: string; - orderAlbumName: string; - orderArtistName: string; - orderTitle: string; - path: string; - playCount: number; - playDate: string; - rating: number; - size: number; - sortAlbumArtistName: string; - sortArtistName: string; - starred: boolean; - starredAt: string; - suffix: string; - title: string; - trackNumber: number; - updatedAt: string; - year: number; + album: string; + albumArtist: string; + albumArtistId: string; + albumId: string; + artist: string; + artistId: string; + bitRate: number; + bookmarkPosition: number; + bpm?: number; + channels?: number; + comment?: string; + compilation: boolean; + createdAt: string; + discNumber: number; + duration: number; + fullText: string; + genre: string; + genres: NDGenre[]; + hasCoverArt: boolean; + id: string; + lyrics?: string; + mbzAlbumArtistId: string; + mbzAlbumId: string; + mbzArtistId: string; + mbzTrackId: string; + orderAlbumArtistName: string; + orderAlbumName: string; + orderArtistName: string; + orderTitle: string; + path: string; + playCount: number; + playDate: string; + rating: number; + size: number; + sortAlbumArtistName: string; + sortArtistName: string; + starred: boolean; + starredAt: string; + suffix: string; + title: string; + trackNumber: number; + updatedAt: string; + year: number; }; export type NDAlbumArtist = { - albumCount: number; - biography: string; - externalInfoUpdatedAt: string; - externalUrl: string; - fullText: string; - genres: NDGenre[]; - id: string; - largeImageUrl?: string; - mbzArtistId: string; - mediumImageUrl?: string; - name: string; - orderArtistName: string; - playCount: number; - playDate: string; - rating: number; - size: number; - smallImageUrl?: string; - songCount: number; - starred: boolean; - starredAt: string; + albumCount: number; + biography: string; + externalInfoUpdatedAt: string; + externalUrl: string; + fullText: string; + genres: NDGenre[]; + id: string; + largeImageUrl?: string; + mbzArtistId: string; + mediumImageUrl?: string; + name: string; + orderArtistName: string; + playCount: number; + playDate: string; + rating: number; + size: number; + smallImageUrl?: string; + songCount: number; + starred: boolean; + starredAt: string; } & { - similarArtists?: SSArtistInfo['similarArtist']; + similarArtists?: SSArtistInfo['similarArtist']; }; export type NDAuthenticationResponse = NDAuthenticate; export type NDAlbumArtistList = { - items: NDAlbumArtist[]; - startIndex: number; - totalRecordCount: number; + items: NDAlbumArtist[]; + startIndex: number; + totalRecordCount: number; }; export type NDAlbumArtistDetail = NDAlbumArtist; @@ -155,9 +155,9 @@ export type NDAlbumDetail = NDAlbum & { songs?: NDSongListResponse }; export type NDAlbumListResponse = NDAlbum[]; export type NDAlbumList = { - items: NDAlbum[]; - startIndex: number; - totalRecordCount: number; + items: NDAlbum[]; + startIndex: number; + totalRecordCount: number; }; export type NDSongDetail = NDSong; @@ -167,142 +167,142 @@ export type NDSongDetailResponse = NDSong; export type NDSongListResponse = NDSong[]; export type NDSongList = { - items: NDSong[]; - startIndex: number; - totalRecordCount: number; + items: NDSong[]; + startIndex: number; + totalRecordCount: number; }; export type NDArtistListResponse = NDAlbumArtist[]; export type NDPagination = { - _end?: number; - _start?: number; + _end?: number; + _start?: number; }; export enum NDSortOrder { - ASC = 'ASC', - DESC = 'DESC', + ASC = 'ASC', + DESC = 'DESC', } export type NDOrder = { - _order?: NDSortOrder; + _order?: NDSortOrder; }; export enum NDGenreListSort { - NAME = 'name', + NAME = 'name', } export type NDGenreListParams = { - _sort?: NDGenreListSort; - id?: string; + _sort?: NDGenreListSort; + id?: string; } & NDPagination & - NDOrder; + NDOrder; export enum NDAlbumListSort { - ALBUM_ARTIST = 'albumArtist', - ARTIST = 'artist', - DURATION = 'duration', - NAME = 'name', - PLAY_COUNT = 'playCount', - PLAY_DATE = 'play_date', - RANDOM = 'random', - RATING = 'rating', - RECENTLY_ADDED = 'recently_added', - SONG_COUNT = 'songCount', - STARRED = 'starred', - YEAR = 'max_year', + ALBUM_ARTIST = 'albumArtist', + ARTIST = 'artist', + DURATION = 'duration', + NAME = 'name', + PLAY_COUNT = 'playCount', + PLAY_DATE = 'play_date', + RANDOM = 'random', + RATING = 'rating', + RECENTLY_ADDED = 'recently_added', + SONG_COUNT = 'songCount', + STARRED = 'starred', + YEAR = 'max_year', } export type NDAlbumListParams = { - _sort?: NDAlbumListSort; - album_id?: string; - artist_id?: string; - compilation?: boolean; - genre_id?: string; - has_rating?: boolean; - id?: string; - name?: string; - recently_played?: boolean; - starred?: boolean; - year?: number; + _sort?: NDAlbumListSort; + album_id?: string; + artist_id?: string; + compilation?: boolean; + genre_id?: string; + has_rating?: boolean; + id?: string; + name?: string; + recently_played?: boolean; + starred?: boolean; + year?: number; } & NDPagination & - NDOrder; + NDOrder; export enum NDSongListSort { - ALBUM = 'album, order_album_artist_name, disc_number, track_number, title', - ALBUM_ARTIST = 'order_album_artist_name, album, disc_number, track_number, title', - ALBUM_SONGS = 'album, discNumber, trackNumber', - ARTIST = 'artist', - BPM = 'bpm', - CHANNELS = 'channels', - COMMENT = 'comment', - DURATION = 'duration', - FAVORITED = 'starred ASC, starredAt ASC', - GENRE = 'genre', - ID = 'id', - PLAY_COUNT = 'playCount', - PLAY_DATE = 'playDate', - RATING = 'rating', - RECENTLY_ADDED = 'createdAt', - TITLE = 'title', - TRACK = 'track', - YEAR = 'year, album, discNumber, trackNumber', + ALBUM = 'album, order_album_artist_name, disc_number, track_number, title', + ALBUM_ARTIST = 'order_album_artist_name, album, disc_number, track_number, title', + ALBUM_SONGS = 'album, discNumber, trackNumber', + ARTIST = 'artist', + BPM = 'bpm', + CHANNELS = 'channels', + COMMENT = 'comment', + DURATION = 'duration', + FAVORITED = 'starred ASC, starredAt ASC', + GENRE = 'genre', + ID = 'id', + PLAY_COUNT = 'playCount', + PLAY_DATE = 'playDate', + RATING = 'rating', + RECENTLY_ADDED = 'createdAt', + TITLE = 'title', + TRACK = 'track', + YEAR = 'year, album, discNumber, trackNumber', } export type NDSongListParams = { - _sort?: NDSongListSort; - album_id?: string[]; - artist_id?: string[]; - genre_id?: string; - starred?: boolean; + _sort?: NDSongListSort; + album_id?: string[]; + artist_id?: string[]; + genre_id?: string; + starred?: boolean; } & NDPagination & - NDOrder; + NDOrder; export enum NDAlbumArtistListSort { - ALBUM_COUNT = 'albumCount', - FAVORITED = 'starred ASC, starredAt ASC', - NAME = 'name', - PLAY_COUNT = 'playCount', - RATING = 'rating', - SONG_COUNT = 'songCount', + ALBUM_COUNT = 'albumCount', + FAVORITED = 'starred ASC, starredAt ASC', + NAME = 'name', + PLAY_COUNT = 'playCount', + RATING = 'rating', + SONG_COUNT = 'songCount', } export type NDAlbumArtistListParams = { - _sort?: NDAlbumArtistListSort; - genre_id?: string; - starred?: boolean; + _sort?: NDAlbumArtistListSort; + genre_id?: string; + starred?: boolean; } & NDPagination & - NDOrder; + NDOrder; export type NDAddToPlaylistResponse = { - added: number; + added: number; }; export type NDAddToPlaylistBody = { - ids: string[]; + ids: string[]; }; export type NDAddToPlaylist = null; export type NDRemoveFromPlaylistResponse = { - ids: string[]; + ids: string[]; }; export type NDRemoveFromPlaylistParams = { - id: string[]; + id: string[]; }; export type NDRemoveFromPlaylist = null; export type NDCreatePlaylistParams = { - comment?: string; - name: string; - public?: boolean; - rules?: Record | null; + comment?: string; + name: string; + public?: boolean; + rules?: Record | null; }; export type NDCreatePlaylistResponse = { - id: string; + id: string; }; export type NDCreatePlaylist = NDCreatePlaylistResponse; @@ -312,7 +312,7 @@ export type NDUpdatePlaylistParams = Partial; export type NDUpdatePlaylistResponse = NDPlaylist; export type NDDeletePlaylistParams = { - id: string; + id: string; }; export type NDDeletePlaylistResponse = null; @@ -320,21 +320,21 @@ export type NDDeletePlaylistResponse = null; export type NDDeletePlaylist = NDDeletePlaylistResponse; export type NDPlaylist = { - comment: string; - createdAt: string; - duration: number; - evaluatedAt: string; - id: string; - name: string; - ownerId: string; - ownerName: string; - path: string; - public: boolean; - rules: Record | null; - size: number; - songCount: number; - sync: boolean; - updatedAt: string; + comment: string; + createdAt: string; + duration: number; + evaluatedAt: string; + id: string; + name: string; + ownerId: string; + ownerName: string; + path: string; + public: boolean; + rules: Record | null; + size: number; + songCount: number; + sync: boolean; + updatedAt: string; }; export type NDPlaylistDetail = NDPlaylist; @@ -342,125 +342,125 @@ export type NDPlaylistDetail = NDPlaylist; export type NDPlaylistDetailResponse = NDPlaylist; export type NDPlaylistList = { - items: NDPlaylist[]; - startIndex: number; - totalRecordCount: number; + items: NDPlaylist[]; + startIndex: number; + totalRecordCount: number; }; export type NDPlaylistListResponse = NDPlaylist[]; export enum NDPlaylistListSort { - DURATION = 'duration', - NAME = 'name', - OWNER = 'ownerName', - PUBLIC = 'public', - SONG_COUNT = 'songCount', - UPDATED_AT = 'updatedAt', + DURATION = 'duration', + NAME = 'name', + OWNER = 'ownerName', + PUBLIC = 'public', + SONG_COUNT = 'songCount', + UPDATED_AT = 'updatedAt', } export type NDPlaylistListParams = { - _sort?: NDPlaylistListSort; - owner_id?: string; + _sort?: NDPlaylistListSort; + owner_id?: string; } & NDPagination & - NDOrder; + NDOrder; export type NDPlaylistSong = NDSong & { - mediaFileId: string; - playlistId: string; + mediaFileId: string; + playlistId: string; }; export type NDPlaylistSongListResponse = NDPlaylistSong[]; export type NDPlaylistSongList = { - items: NDPlaylistSong[]; - startIndex: number; - totalRecordCount: number; + items: NDPlaylistSong[]; + startIndex: number; + totalRecordCount: number; }; export const NDSongQueryFields = [ - { label: 'Album', type: 'string', value: 'album' }, - { label: 'Album Artist', type: 'string', value: 'albumartist' }, - { label: 'Album Comment', type: 'string', value: 'albumcomment' }, - { label: 'Album Type', type: 'string', value: 'albumtype' }, - { label: 'Artist', type: 'string', value: 'artist' }, - { label: 'Bitrate', type: 'number', value: 'bitrate' }, - { label: 'BPM', type: 'number', value: 'bpm' }, - { label: 'Catalog Number', type: 'string', value: 'catalognumber' }, - { label: 'Channels', type: 'number', value: 'channels' }, - { label: 'Comment', type: 'string', value: 'comment' }, - { label: 'Date Added', type: 'date', value: 'dateadded' }, - { label: 'Date Favorited', type: 'date', value: 'dateloved' }, - { label: 'Date Last Played', type: 'date', value: 'lastplayed' }, - { label: 'Date Modified', type: 'date', value: 'datemodified' }, - { label: 'Disc Subtitle', type: 'string', value: 'discsubtitle' }, - { label: 'Disc Number', type: 'number', value: 'discnumber' }, - { label: 'Duration', type: 'number', value: 'duration' }, - { label: 'File Path', type: 'string', value: 'filepath' }, - { label: 'File Type', type: 'string', value: 'filetype' }, - { label: 'Genre', type: 'string', value: 'genre' }, - { label: 'Has CoverArt', type: 'boolean', value: 'hascoverart' }, - { label: 'Is Compilation', type: 'boolean', value: 'compilation' }, - { label: 'Is Favorite', type: 'boolean', value: 'loved' }, - { label: 'Lyrics', type: 'string', value: 'lyrics' }, - { label: 'Name', type: 'string', value: 'title' }, - { label: 'Play Count', type: 'number', value: 'playcount' }, - { label: 'Rating', type: 'number', value: 'rating' }, - { label: 'Size', type: 'number', value: 'size' }, - { label: 'Sort Album', type: 'string', value: 'sortalbum' }, - { label: 'Sort Album Artist', type: 'string', value: 'sortalbumartist' }, - { label: 'Sort Artist', type: 'string', value: 'sortartist' }, - { label: 'Sort Name', type: 'string', value: 'sorttitle' }, - { label: 'Track Number', type: 'number', value: 'tracknumber' }, - { label: 'Year', type: 'number', value: 'year' }, + { label: 'Album', type: 'string', value: 'album' }, + { label: 'Album Artist', type: 'string', value: 'albumartist' }, + { label: 'Album Comment', type: 'string', value: 'albumcomment' }, + { label: 'Album Type', type: 'string', value: 'albumtype' }, + { label: 'Artist', type: 'string', value: 'artist' }, + { label: 'Bitrate', type: 'number', value: 'bitrate' }, + { label: 'BPM', type: 'number', value: 'bpm' }, + { label: 'Catalog Number', type: 'string', value: 'catalognumber' }, + { label: 'Channels', type: 'number', value: 'channels' }, + { label: 'Comment', type: 'string', value: 'comment' }, + { label: 'Date Added', type: 'date', value: 'dateadded' }, + { label: 'Date Favorited', type: 'date', value: 'dateloved' }, + { label: 'Date Last Played', type: 'date', value: 'lastplayed' }, + { label: 'Date Modified', type: 'date', value: 'datemodified' }, + { label: 'Disc Subtitle', type: 'string', value: 'discsubtitle' }, + { label: 'Disc Number', type: 'number', value: 'discnumber' }, + { label: 'Duration', type: 'number', value: 'duration' }, + { label: 'File Path', type: 'string', value: 'filepath' }, + { label: 'File Type', type: 'string', value: 'filetype' }, + { label: 'Genre', type: 'string', value: 'genre' }, + { label: 'Has CoverArt', type: 'boolean', value: 'hascoverart' }, + { label: 'Is Compilation', type: 'boolean', value: 'compilation' }, + { label: 'Is Favorite', type: 'boolean', value: 'loved' }, + { label: 'Lyrics', type: 'string', value: 'lyrics' }, + { label: 'Name', type: 'string', value: 'title' }, + { label: 'Play Count', type: 'number', value: 'playcount' }, + { label: 'Rating', type: 'number', value: 'rating' }, + { label: 'Size', type: 'number', value: 'size' }, + { label: 'Sort Album', type: 'string', value: 'sortalbum' }, + { label: 'Sort Album Artist', type: 'string', value: 'sortalbumartist' }, + { label: 'Sort Artist', type: 'string', value: 'sortartist' }, + { label: 'Sort Name', type: 'string', value: 'sorttitle' }, + { label: 'Track Number', type: 'number', value: 'tracknumber' }, + { label: 'Year', type: 'number', value: 'year' }, ]; export const NDSongQueryDateOperators = [ - { label: 'is', value: 'is' }, - { label: 'is not', value: 'isNot' }, - { label: 'is before', value: 'before' }, - { label: 'is after', value: 'after' }, - { label: 'is in the last', value: 'inTheLast' }, - { label: 'is not in the last', value: 'notInTheLast' }, - { label: 'is in the range', value: 'inTheRange' }, + { label: 'is', value: 'is' }, + { label: 'is not', value: 'isNot' }, + { label: 'is before', value: 'before' }, + { label: 'is after', value: 'after' }, + { label: 'is in the last', value: 'inTheLast' }, + { label: 'is not in the last', value: 'notInTheLast' }, + { label: 'is in the range', value: 'inTheRange' }, ]; export const NDSongQueryStringOperators = [ - { label: 'is', value: 'is' }, - { label: 'is not', value: 'isNot' }, - { label: 'contains', value: 'contains' }, - { label: 'does not contain', value: 'notContains' }, - { label: 'starts with', value: 'startsWith' }, - { label: 'ends with', value: 'endsWith' }, + { label: 'is', value: 'is' }, + { label: 'is not', value: 'isNot' }, + { label: 'contains', value: 'contains' }, + { label: 'does not contain', value: 'notContains' }, + { label: 'starts with', value: 'startsWith' }, + { label: 'ends with', value: 'endsWith' }, ]; export const NDSongQueryBooleanOperators = [ - { label: 'is', value: 'is' }, - { label: 'is not', value: 'isNot' }, + { label: 'is', value: 'is' }, + { label: 'is not', value: 'isNot' }, ]; export const NDSongQueryNumberOperators = [ - { label: 'is', value: 'is' }, - { label: 'is not', value: 'isNot' }, - { label: 'contains', value: 'contains' }, - { label: 'does not contain', value: 'notContains' }, - { label: 'is greater than', value: 'gt' }, - { label: 'is less than', value: 'lt' }, - { label: 'is in the range', value: 'inTheRange' }, + { label: 'is', value: 'is' }, + { label: 'is not', value: 'isNot' }, + { label: 'contains', value: 'contains' }, + { label: 'does not contain', value: 'notContains' }, + { label: 'is greater than', value: 'gt' }, + { label: 'is less than', value: 'lt' }, + { label: 'is in the range', value: 'inTheRange' }, ]; export type NDUserListParams = { - _sort?: NDUserListSort; + _sort?: NDUserListSort; } & NDPagination & - NDOrder; + NDOrder; export type NDUserListResponse = NDUser[]; export type NDUserList = { - items: NDUser[]; - startIndex: number; - totalRecordCount: number; + items: NDUser[]; + startIndex: number; + totalRecordCount: number; }; export enum NDUserListSort { - NAME = 'name', + NAME = 'name', } diff --git a/src/renderer/api/navidrome/navidrome-api.ts b/src/renderer/api/navidrome/navidrome-api.ts index 17df54c0..9934bb73 100644 --- a/src/renderer/api/navidrome/navidrome-api.ts +++ b/src/renderer/api/navidrome/navidrome-api.ts @@ -15,187 +15,188 @@ const localSettings = isElectron() ? window.electron.localSettings : null; const c = initContract(); export const contract = c.router({ - addToPlaylist: { - body: ndType._parameters.addToPlaylist, - method: 'POST', - path: 'playlist/:id/tracks', - responses: { - 200: resultWithHeaders(ndType._response.addToPlaylist), - 500: resultWithHeaders(ndType._response.error), + addToPlaylist: { + body: ndType._parameters.addToPlaylist, + method: 'POST', + path: 'playlist/:id/tracks', + responses: { + 200: resultWithHeaders(ndType._response.addToPlaylist), + 500: resultWithHeaders(ndType._response.error), + }, }, - }, - authenticate: { - body: ndType._parameters.authenticate, - method: 'POST', - path: 'auth/login', - responses: { - 200: resultWithHeaders(ndType._response.authenticate), - 500: resultWithHeaders(ndType._response.error), + authenticate: { + body: ndType._parameters.authenticate, + method: 'POST', + path: 'auth/login', + responses: { + 200: resultWithHeaders(ndType._response.authenticate), + 500: resultWithHeaders(ndType._response.error), + }, }, - }, - createPlaylist: { - body: ndType._parameters.createPlaylist, - method: 'POST', - path: 'playlist', - responses: { - 200: resultWithHeaders(ndType._response.createPlaylist), - 500: resultWithHeaders(ndType._response.error), + createPlaylist: { + body: ndType._parameters.createPlaylist, + method: 'POST', + path: 'playlist', + responses: { + 200: resultWithHeaders(ndType._response.createPlaylist), + 500: resultWithHeaders(ndType._response.error), + }, }, - }, - deletePlaylist: { - body: null, - method: 'DELETE', - path: 'playlist/:id', - responses: { - 200: resultWithHeaders(ndType._response.deletePlaylist), - 500: resultWithHeaders(ndType._response.error), + deletePlaylist: { + body: null, + method: 'DELETE', + path: 'playlist/:id', + responses: { + 200: resultWithHeaders(ndType._response.deletePlaylist), + 500: resultWithHeaders(ndType._response.error), + }, }, - }, - getAlbumArtistDetail: { - method: 'GET', - path: 'artist/:id', - responses: { - 200: resultWithHeaders(ndType._response.albumArtist), - 500: resultWithHeaders(ndType._response.error), + getAlbumArtistDetail: { + method: 'GET', + path: 'artist/:id', + responses: { + 200: resultWithHeaders(ndType._response.albumArtist), + 500: resultWithHeaders(ndType._response.error), + }, }, - }, - getAlbumArtistList: { - method: 'GET', - path: 'artist', - query: ndType._parameters.albumArtistList, - responses: { - 200: resultWithHeaders(ndType._response.albumArtistList), - 500: resultWithHeaders(ndType._response.error), + getAlbumArtistList: { + method: 'GET', + path: 'artist', + query: ndType._parameters.albumArtistList, + responses: { + 200: resultWithHeaders(ndType._response.albumArtistList), + 500: resultWithHeaders(ndType._response.error), + }, }, - }, - getAlbumDetail: { - method: 'GET', - path: 'album/:id', - responses: { - 200: resultWithHeaders(ndType._response.album), - 500: resultWithHeaders(ndType._response.error), + getAlbumDetail: { + method: 'GET', + path: 'album/:id', + responses: { + 200: resultWithHeaders(ndType._response.album), + 500: resultWithHeaders(ndType._response.error), + }, }, - }, - getAlbumList: { - method: 'GET', - path: 'album', - query: ndType._parameters.albumList, - responses: { - 200: resultWithHeaders(ndType._response.albumList), - 500: resultWithHeaders(ndType._response.error), + getAlbumList: { + method: 'GET', + path: 'album', + query: ndType._parameters.albumList, + responses: { + 200: resultWithHeaders(ndType._response.albumList), + 500: resultWithHeaders(ndType._response.error), + }, }, - }, - getGenreList: { - method: 'GET', - path: 'genre', - responses: { - 200: resultWithHeaders(ndType._response.genreList), - 500: resultWithHeaders(ndType._response.error), + getGenreList: { + method: 'GET', + path: 'genre', + responses: { + 200: resultWithHeaders(ndType._response.genreList), + 500: resultWithHeaders(ndType._response.error), + }, }, - }, - getPlaylistDetail: { - method: 'GET', - path: 'playlist/:id', - responses: { - 200: resultWithHeaders(ndType._response.playlist), - 500: resultWithHeaders(ndType._response.error), + getPlaylistDetail: { + method: 'GET', + path: 'playlist/:id', + responses: { + 200: resultWithHeaders(ndType._response.playlist), + 500: resultWithHeaders(ndType._response.error), + }, }, - }, - getPlaylistList: { - method: 'GET', - path: 'playlist', - query: ndType._parameters.playlistList, - responses: { - 200: resultWithHeaders(ndType._response.playlistList), - 500: resultWithHeaders(ndType._response.error), + getPlaylistList: { + method: 'GET', + path: 'playlist', + query: ndType._parameters.playlistList, + responses: { + 200: resultWithHeaders(ndType._response.playlistList), + 500: resultWithHeaders(ndType._response.error), + }, }, - }, - getPlaylistSongList: { - method: 'GET', - path: 'playlist/:id/tracks', - query: ndType._parameters.songList, - responses: { - 200: resultWithHeaders(ndType._response.playlistSongList), - 500: resultWithHeaders(ndType._response.error), + getPlaylistSongList: { + method: 'GET', + path: 'playlist/:id/tracks', + query: ndType._parameters.songList, + responses: { + 200: resultWithHeaders(ndType._response.playlistSongList), + 500: resultWithHeaders(ndType._response.error), + }, }, - }, - getSongDetail: { - method: 'GET', - path: 'song/:id', - responses: { - 200: resultWithHeaders(ndType._response.song), - 500: resultWithHeaders(ndType._response.error), + getSongDetail: { + method: 'GET', + path: 'song/:id', + responses: { + 200: resultWithHeaders(ndType._response.song), + 500: resultWithHeaders(ndType._response.error), + }, }, - }, - getSongList: { - method: 'GET', - path: 'song', - query: ndType._parameters.songList, - responses: { - 200: resultWithHeaders(ndType._response.songList), - 500: resultWithHeaders(ndType._response.error), + getSongList: { + method: 'GET', + path: 'song', + query: ndType._parameters.songList, + responses: { + 200: resultWithHeaders(ndType._response.songList), + 500: resultWithHeaders(ndType._response.error), + }, }, - }, - getUserList: { - method: 'GET', - path: 'user', - query: ndType._parameters.userList, - responses: { - 200: resultWithHeaders(ndType._response.userList), - 500: resultWithHeaders(ndType._response.error), + getUserList: { + method: 'GET', + path: 'user', + query: ndType._parameters.userList, + responses: { + 200: resultWithHeaders(ndType._response.userList), + 500: resultWithHeaders(ndType._response.error), + }, }, - }, - removeFromPlaylist: { - body: null, - method: 'DELETE', - path: 'playlist/:id/tracks', - query: ndType._parameters.removeFromPlaylist, - responses: { - 200: resultWithHeaders(ndType._response.removeFromPlaylist), - 500: resultWithHeaders(ndType._response.error), + removeFromPlaylist: { + body: null, + method: 'DELETE', + path: 'playlist/:id/tracks', + query: ndType._parameters.removeFromPlaylist, + responses: { + 200: resultWithHeaders(ndType._response.removeFromPlaylist), + 500: resultWithHeaders(ndType._response.error), + }, }, - }, - updatePlaylist: { - body: ndType._parameters.updatePlaylist, - method: 'PUT', - path: 'playlist/:id', - responses: { - 200: resultWithHeaders(ndType._response.updatePlaylist), - 500: resultWithHeaders(ndType._response.error), + updatePlaylist: { + body: ndType._parameters.updatePlaylist, + method: 'PUT', + path: 'playlist/:id', + responses: { + 200: resultWithHeaders(ndType._response.updatePlaylist), + 500: resultWithHeaders(ndType._response.error), + }, }, - }, }); const axiosClient = axios.create({}); axiosClient.defaults.paramsSerializer = (params) => { - return qs.stringify(params, { arrayFormat: 'repeat' }); + return qs.stringify(params, { arrayFormat: 'repeat' }); }; const parsePath = (fullPath: string) => { - const [path, params] = fullPath.split('?'); + const [path, params] = fullPath.split('?'); - const parsedParams = qs.parse(params); + const parsedParams = qs.parse(params); - // Convert indexed object to array - const newParams: Record = {}; - Object.keys(parsedParams).forEach((key) => { - const isIndexedArrayObject = - typeof parsedParams[key] === 'object' && Object.keys(parsedParams[key] || {}).includes('0'); + // Convert indexed object to array + const newParams: Record = {}; + Object.keys(parsedParams).forEach((key) => { + const isIndexedArrayObject = + typeof parsedParams[key] === 'object' && + Object.keys(parsedParams[key] || {}).includes('0'); - if (!isIndexedArrayObject) { - newParams[key] = parsedParams[key]; - } else { - newParams[key] = Object.values(parsedParams[key] || {}); - } - }); + if (!isIndexedArrayObject) { + newParams[key] = parsedParams[key]; + } else { + newParams[key] = Object.values(parsedParams[key] || {}); + } + }); - const notNilParams = omitBy(newParams, (value) => value === 'undefined' || value === 'null'); + const notNilParams = omitBy(newParams, (value) => value === 'undefined' || value === 'null'); - return { - params: notNilParams, - path, - }; + return { + params: notNilParams, + path, + }; }; let authSuccess = true; @@ -205,184 +206,186 @@ const RETRY_DELAY_MS = 1000; const MAX_RETRIES = 5; const waitForResult = async (count = 0): Promise => { - return new Promise((resolve) => { - if (count === MAX_RETRIES || !shouldDelay) resolve(); + return new Promise((resolve) => { + if (count === MAX_RETRIES || !shouldDelay) resolve(); - setTimeout(() => { - waitForResult(count + 1) - .then(resolve) - .catch(resolve); - }, RETRY_DELAY_MS); - }); + setTimeout(() => { + waitForResult(count + 1) + .then(resolve) + .catch(resolve); + }, RETRY_DELAY_MS); + }); }; const limitedFail = debounce(authenticationFailure, RETRY_DELAY_MS); const TIMEOUT_ERROR = Error(); axiosClient.interceptors.response.use( - (response) => { - const serverId = useAuthStore.getState().currentServer?.id; + (response) => { + const serverId = useAuthStore.getState().currentServer?.id; - if (serverId) { - const headerCredential = response.headers['x-nd-authorization'] as string | undefined; + if (serverId) { + const headerCredential = response.headers['x-nd-authorization'] as string | undefined; - if (headerCredential) { - useAuthStore.getState().actions.updateServer(serverId, { - ndCredential: headerCredential, - }); - } - } + if (headerCredential) { + useAuthStore.getState().actions.updateServer(serverId, { + ndCredential: headerCredential, + }); + } + } - authSuccess = true; + authSuccess = true; - return response; - }, - (error) => { - if (error.response && error.response.status === 401) { - const currentServer = useAuthStore.getState().currentServer; + return response; + }, + (error) => { + if (error.response && error.response.status === 401) { + const currentServer = useAuthStore.getState().currentServer; - if (localSettings && currentServer?.savePassword) { - // eslint-disable-next-line promise/no-promise-in-callback - return localSettings - .passwordGet(currentServer.id) - .then(async (password: string | null) => { - authSuccess = false; + if (localSettings && currentServer?.savePassword) { + // eslint-disable-next-line promise/no-promise-in-callback + return localSettings + .passwordGet(currentServer.id) + .then(async (password: string | null) => { + authSuccess = false; - if (password === null) { - throw error; + if (password === null) { + throw error; + } + + if (shouldDelay) { + await waitForResult(); + + // Hopefully the delay was sufficient for authentication. + // Otherwise, it will require manual intervention + if (authSuccess) { + return axiosClient.request(error.config); + } + + throw error; + } + + shouldDelay = true; + + // Do not use axiosClient. Instead, manually make a post + const res = await axios.post(`${currentServer.url}/auth/login`, { + password, + username: currentServer.username, + }); + + if (res.status === 429) { + toast.error({ + message: + 'you have exceeded the number of allowed login requests. Please wait before logging, or consider tweaking AuthRequestLimit', + title: 'Your session has expired.', + }); + + const serverId = currentServer.id; + useAuthStore + .getState() + .actions.updateServer(serverId, { ndCredential: undefined }); + useAuthStore.getState().actions.setCurrentServer(null); + + // special error to prevent sending a second message, and stop other messages that could be enqueued + limitedFail.cancel(); + throw TIMEOUT_ERROR; + } + if (res.status !== 200) { + throw new Error('Failed to authenticate'); + } + + const newCredential = res.data.token; + const subsonicCredential = `u=${currentServer.username}&s=${res.data.subsonicSalt}&t=${res.data.subsonicToken}`; + + useAuthStore.getState().actions.updateServer(currentServer.id, { + credential: subsonicCredential, + ndCredential: newCredential, + }); + + error.config.headers['x-nd-authorization'] = `Bearer ${newCredential}`; + + authSuccess = true; + + return axiosClient.request(error.config); + }) + .catch((newError: any) => { + if (newError !== TIMEOUT_ERROR) { + console.error('Error when trying to reauthenticate: ', newError); + limitedFail(currentServer); + } + + // make sure to pass the error so axios will error later on + throw newError; + }) + .finally(() => { + shouldDelay = false; + }); } - if (shouldDelay) { - await waitForResult(); + limitedFail(currentServer); + } - // Hopefully the delay was sufficient for authentication. - // Otherwise, it will require manual intervention - if (authSuccess) { - return axiosClient.request(error.config); - } - - throw error; - } - - shouldDelay = true; - - // Do not use axiosClient. Instead, manually make a post - const res = await axios.post(`${currentServer.url}/auth/login`, { - password, - username: currentServer.username, - }); - - if (res.status === 429) { - toast.error({ - message: - 'you have exceeded the number of allowed login requests. Please wait before logging, or consider tweaking AuthRequestLimit', - title: 'Your session has expired.', - }); - - const serverId = currentServer.id; - useAuthStore.getState().actions.updateServer(serverId, { ndCredential: undefined }); - useAuthStore.getState().actions.setCurrentServer(null); - - // special error to prevent sending a second message, and stop other messages that could be enqueued - limitedFail.cancel(); - throw TIMEOUT_ERROR; - } - if (res.status !== 200) { - throw new Error('Failed to authenticate'); - } - - const newCredential = res.data.token; - const subsonicCredential = `u=${currentServer.username}&s=${res.data.subsonicSalt}&t=${res.data.subsonicToken}`; - - useAuthStore.getState().actions.updateServer(currentServer.id, { - credential: subsonicCredential, - ndCredential: newCredential, - }); - - error.config.headers['x-nd-authorization'] = `Bearer ${newCredential}`; - - authSuccess = true; - - return axiosClient.request(error.config); - }) - .catch((newError: any) => { - if (newError !== TIMEOUT_ERROR) { - console.error('Error when trying to reauthenticate: ', newError); - limitedFail(currentServer); - } - - // make sure to pass the error so axios will error later on - throw newError; - }) - .finally(() => { - shouldDelay = false; - }); - } - - limitedFail(currentServer); - } - - return Promise.reject(error); - }, + return Promise.reject(error); + }, ); export const ndApiClient = (args: { - server: ServerListItem | null; - signal?: AbortSignal; - url?: string; + server: ServerListItem | null; + signal?: AbortSignal; + url?: string; }) => { - const { server, url, signal } = args; + const { server, url, signal } = args; - return initClient(contract, { - api: async ({ path, method, headers, body }) => { - let baseUrl: string | undefined; - let token: string | undefined; + return initClient(contract, { + api: async ({ path, method, headers, body }) => { + let baseUrl: string | undefined; + let token: string | undefined; - const { params, path: api } = parsePath(path); + const { params, path: api } = parsePath(path); - if (server) { - baseUrl = `${server?.url}/api`; - token = server?.ndCredential; - } else { - baseUrl = url; - } + if (server) { + baseUrl = `${server?.url}/api`; + token = server?.ndCredential; + } else { + baseUrl = url; + } - try { - if (shouldDelay) await waitForResult(); + try { + if (shouldDelay) await waitForResult(); - const result = await axiosClient.request({ - data: body, - headers: { - ...headers, - ...(token && { 'x-nd-authorization': `Bearer ${token}` }), - }, - method: method as Method, - params, - signal, - url: `${baseUrl}/${api}`, - }); - return { - body: { data: result.data, headers: result.headers }, - headers: result.headers as any, - status: result.status, - }; - } catch (e: Error | AxiosError | any) { - if (isAxiosError(e)) { - const error = e as AxiosError; - const response = error.response as AxiosResponse; - return { - body: { data: response.data, headers: response.headers }, - headers: response.headers as any, - status: response.status, - }; - } - throw e; - } - }, - baseHeaders: { - 'Content-Type': 'application/json', - }, - baseUrl: '', - jsonQuery: false, - }); + const result = await axiosClient.request({ + data: body, + headers: { + ...headers, + ...(token && { 'x-nd-authorization': `Bearer ${token}` }), + }, + method: method as Method, + params, + signal, + url: `${baseUrl}/${api}`, + }); + return { + body: { data: result.data, headers: result.headers }, + headers: result.headers as any, + status: result.status, + }; + } catch (e: Error | AxiosError | any) { + if (isAxiosError(e)) { + const error = e as AxiosError; + const response = error.response as AxiosResponse; + return { + body: { data: response.data, headers: response.headers }, + headers: response.headers as any, + status: response.status, + }; + } + throw e; + } + }, + baseHeaders: { + 'Content-Type': 'application/json', + }, + baseUrl: '', + jsonQuery: false, + }); }; diff --git a/src/renderer/api/navidrome/navidrome-controller.ts b/src/renderer/api/navidrome/navidrome-controller.ts index 66ffc367..a3bf4dc5 100644 --- a/src/renderer/api/navidrome/navidrome-controller.ts +++ b/src/renderer/api/navidrome/navidrome-controller.ts @@ -1,43 +1,43 @@ import { - AlbumArtistDetailArgs, - AlbumArtistDetailResponse, - AddToPlaylistArgs, - AddToPlaylistResponse, - CreatePlaylistResponse, - CreatePlaylistArgs, - DeletePlaylistArgs, - DeletePlaylistResponse, - AlbumArtistListResponse, - AlbumArtistListArgs, - albumArtistListSortMap, - sortOrderMap, - AuthenticationResponse, - UserListResponse, - UserListArgs, - userListSortMap, - GenreListArgs, - GenreListResponse, - AlbumDetailResponse, - AlbumDetailArgs, - AlbumListArgs, - albumListSortMap, - AlbumListResponse, - SongListResponse, - SongListArgs, - songListSortMap, - SongDetailResponse, - SongDetailArgs, - UpdatePlaylistArgs, - UpdatePlaylistResponse, - PlaylistListResponse, - PlaylistDetailArgs, - PlaylistListArgs, - playlistListSortMap, - PlaylistDetailResponse, - PlaylistSongListArgs, - PlaylistSongListResponse, - RemoveFromPlaylistResponse, - RemoveFromPlaylistArgs, + AlbumArtistDetailArgs, + AlbumArtistDetailResponse, + AddToPlaylistArgs, + AddToPlaylistResponse, + CreatePlaylistResponse, + CreatePlaylistArgs, + DeletePlaylistArgs, + DeletePlaylistResponse, + AlbumArtistListResponse, + AlbumArtistListArgs, + albumArtistListSortMap, + sortOrderMap, + AuthenticationResponse, + UserListResponse, + UserListArgs, + userListSortMap, + GenreListArgs, + GenreListResponse, + AlbumDetailResponse, + AlbumDetailArgs, + AlbumListArgs, + albumListSortMap, + AlbumListResponse, + SongListResponse, + SongListArgs, + songListSortMap, + SongDetailResponse, + SongDetailArgs, + UpdatePlaylistArgs, + UpdatePlaylistResponse, + PlaylistListResponse, + PlaylistDetailArgs, + PlaylistListArgs, + playlistListSortMap, + PlaylistDetailResponse, + PlaylistSongListArgs, + PlaylistSongListResponse, + RemoveFromPlaylistResponse, + RemoveFromPlaylistArgs, } from '../types'; import { ndApiClient } from '/@/renderer/api/navidrome/navidrome-api'; import { ndNormalize } from '/@/renderer/api/navidrome/navidrome-normalize'; @@ -45,428 +45,430 @@ import { ndType } from '/@/renderer/api/navidrome/navidrome-types'; import { ssApiClient } from '/@/renderer/api/subsonic/subsonic-api'; const authenticate = async ( - url: string, - body: { password: string; username: string }, + url: string, + body: { password: string; username: string }, ): Promise => { - const cleanServerUrl = url.replace(/\/$/, ''); + const cleanServerUrl = url.replace(/\/$/, ''); - const res = await ndApiClient({ server: null, url: cleanServerUrl }).authenticate({ - body: { - password: body.password, - username: body.username, - }, - }); + const res = await ndApiClient({ server: null, url: cleanServerUrl }).authenticate({ + body: { + password: body.password, + username: body.username, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to authenticate'); - } + if (res.status !== 200) { + throw new Error('Failed to authenticate'); + } - return { - credential: `u=${body.username}&s=${res.body.data.subsonicSalt}&t=${res.body.data.subsonicToken}`, - ndCredential: res.body.data.token, - userId: res.body.data.id, - username: res.body.data.username, - }; + return { + credential: `u=${body.username}&s=${res.body.data.subsonicSalt}&t=${res.body.data.subsonicToken}`, + ndCredential: res.body.data.token, + userId: res.body.data.id, + username: res.body.data.username, + }; }; const getUserList = async (args: UserListArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const res = await ndApiClient(apiClientProps).getUserList({ - query: { - _end: query.startIndex + (query.limit || 0), - _order: sortOrderMap.navidrome[query.sortOrder], - _sort: userListSortMap.navidrome[query.sortBy], - _start: query.startIndex, - ...query._custom?.navidrome, - }, - }); + const res = await ndApiClient(apiClientProps).getUserList({ + query: { + _end: query.startIndex + (query.limit || 0), + _order: sortOrderMap.navidrome[query.sortOrder], + _sort: userListSortMap.navidrome[query.sortBy], + _start: query.startIndex, + ...query._custom?.navidrome, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to get user list'); - } + if (res.status !== 200) { + throw new Error('Failed to get user list'); + } - return { - items: res.body.data.map((user) => ndNormalize.user(user)), - startIndex: query?.startIndex || 0, - totalRecordCount: Number(res.body.headers.get('x-total-count') || 0), - }; + return { + items: res.body.data.map((user) => ndNormalize.user(user)), + startIndex: query?.startIndex || 0, + totalRecordCount: Number(res.body.headers.get('x-total-count') || 0), + }; }; const getGenreList = async (args: GenreListArgs): Promise => { - const { apiClientProps } = args; + const { apiClientProps } = args; - const res = await ndApiClient(apiClientProps).getGenreList({}); + const res = await ndApiClient(apiClientProps).getGenreList({}); - if (res.status !== 200) { - throw new Error('Failed to get genre list'); - } + if (res.status !== 200) { + throw new Error('Failed to get genre list'); + } - return { - items: res.body.data, - startIndex: 0, - totalRecordCount: Number(res.body.headers.get('x-total-count') || 0), - }; + return { + items: res.body.data, + startIndex: 0, + totalRecordCount: Number(res.body.headers.get('x-total-count') || 0), + }; }; const getAlbumArtistDetail = async ( - args: AlbumArtistDetailArgs, + args: AlbumArtistDetailArgs, ): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const res = await ndApiClient(apiClientProps).getAlbumArtistDetail({ - params: { - id: query.id, - }, - }); + const res = await ndApiClient(apiClientProps).getAlbumArtistDetail({ + params: { + id: query.id, + }, + }); - const artistInfoRes = await ssApiClient(apiClientProps).getArtistInfo({ - query: { - count: 10, - id: query.id, - }, - }); + const artistInfoRes = await ssApiClient(apiClientProps).getArtistInfo({ + query: { + count: 10, + id: query.id, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to get album artist detail'); - } + if (res.status !== 200) { + throw new Error('Failed to get album artist detail'); + } - if (!apiClientProps.server) { - throw new Error('Server is required'); - } + if (!apiClientProps.server) { + throw new Error('Server is required'); + } - return ndNormalize.albumArtist( - { - ...res.body.data, - ...(artistInfoRes.status === 200 && { - similarArtists: artistInfoRes.body.artistInfo.similarArtist, - ...(!res.body.data.largeImageUrl && { - largeImageUrl: artistInfoRes.body.artistInfo.largeImageUrl, - }), - ...(!res.body.data.mediumImageUrl && { - largeImageUrl: artistInfoRes.body.artistInfo.mediumImageUrl, - }), - ...(!res.body.data.smallImageUrl && { - largeImageUrl: artistInfoRes.body.artistInfo.smallImageUrl, - }), - }), - }, - apiClientProps.server, - ); + return ndNormalize.albumArtist( + { + ...res.body.data, + ...(artistInfoRes.status === 200 && { + similarArtists: artistInfoRes.body.artistInfo.similarArtist, + ...(!res.body.data.largeImageUrl && { + largeImageUrl: artistInfoRes.body.artistInfo.largeImageUrl, + }), + ...(!res.body.data.mediumImageUrl && { + largeImageUrl: artistInfoRes.body.artistInfo.mediumImageUrl, + }), + ...(!res.body.data.smallImageUrl && { + largeImageUrl: artistInfoRes.body.artistInfo.smallImageUrl, + }), + }), + }, + apiClientProps.server, + ); }; const getAlbumArtistList = async (args: AlbumArtistListArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const res = await ndApiClient(apiClientProps).getAlbumArtistList({ - query: { - _end: query.startIndex + (query.limit || 0), - _order: sortOrderMap.navidrome[query.sortOrder], - _sort: albumArtistListSortMap.navidrome[query.sortBy], - _start: query.startIndex, - name: query.searchTerm, - ...query._custom?.navidrome, - }, - }); + const res = await ndApiClient(apiClientProps).getAlbumArtistList({ + query: { + _end: query.startIndex + (query.limit || 0), + _order: sortOrderMap.navidrome[query.sortOrder], + _sort: albumArtistListSortMap.navidrome[query.sortBy], + _start: query.startIndex, + name: query.searchTerm, + ...query._custom?.navidrome, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to get album artist list'); - } + if (res.status !== 200) { + throw new Error('Failed to get album artist list'); + } - return { - items: res.body.data.map((albumArtist) => - ndNormalize.albumArtist(albumArtist, apiClientProps.server), - ), - startIndex: query.startIndex, - totalRecordCount: Number(res.body.headers.get('x-total-count') || 0), - }; + return { + items: res.body.data.map((albumArtist) => + ndNormalize.albumArtist(albumArtist, apiClientProps.server), + ), + startIndex: query.startIndex, + totalRecordCount: Number(res.body.headers.get('x-total-count') || 0), + }; }; const getAlbumDetail = async (args: AlbumDetailArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const albumRes = await ndApiClient(apiClientProps).getAlbumDetail({ - params: { - id: query.id, - }, - }); + const albumRes = await ndApiClient(apiClientProps).getAlbumDetail({ + params: { + id: query.id, + }, + }); - const songsData = await ndApiClient(apiClientProps).getSongList({ - query: { - _end: 0, - _order: 'ASC', - _sort: 'album', - _start: 0, - album_id: [query.id], - }, - }); + const songsData = await ndApiClient(apiClientProps).getSongList({ + query: { + _end: 0, + _order: 'ASC', + _sort: 'album', + _start: 0, + album_id: [query.id], + }, + }); - if (albumRes.status !== 200 || songsData.status !== 200) { - throw new Error('Failed to get album detail'); - } + if (albumRes.status !== 200 || songsData.status !== 200) { + throw new Error('Failed to get album detail'); + } - return ndNormalize.album( - { ...albumRes.body.data, songs: songsData.body.data }, - apiClientProps.server, - ); + return ndNormalize.album( + { ...albumRes.body.data, songs: songsData.body.data }, + apiClientProps.server, + ); }; const getAlbumList = async (args: AlbumListArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const res = await ndApiClient(apiClientProps).getAlbumList({ - query: { - _end: query.startIndex + (query.limit || 0), - _order: sortOrderMap.navidrome[query.sortOrder], - _sort: albumListSortMap.navidrome[query.sortBy], - _start: query.startIndex, - artist_id: query.artistIds?.[0], - name: query.searchTerm, - ...query._custom?.navidrome, - }, - }); + const res = await ndApiClient(apiClientProps).getAlbumList({ + query: { + _end: query.startIndex + (query.limit || 0), + _order: sortOrderMap.navidrome[query.sortOrder], + _sort: albumListSortMap.navidrome[query.sortBy], + _start: query.startIndex, + artist_id: query.artistIds?.[0], + name: query.searchTerm, + ...query._custom?.navidrome, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to get album list'); - } + if (res.status !== 200) { + throw new Error('Failed to get album list'); + } - return { - items: res.body.data.map((album) => ndNormalize.album(album, apiClientProps.server)), - startIndex: query?.startIndex || 0, - totalRecordCount: Number(res.body.headers.get('x-total-count') || 0), - }; + return { + items: res.body.data.map((album) => ndNormalize.album(album, apiClientProps.server)), + startIndex: query?.startIndex || 0, + totalRecordCount: Number(res.body.headers.get('x-total-count') || 0), + }; }; const getSongList = async (args: SongListArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const res = await ndApiClient(apiClientProps).getSongList({ - query: { - _end: query.startIndex + (query.limit || -1), - _order: sortOrderMap.navidrome[query.sortOrder], - _sort: songListSortMap.navidrome[query.sortBy], - _start: query.startIndex, - album_artist_id: query.artistIds, - album_id: query.albumIds, - title: query.searchTerm, - ...query._custom?.navidrome, - }, - }); + const res = await ndApiClient(apiClientProps).getSongList({ + query: { + _end: query.startIndex + (query.limit || -1), + _order: sortOrderMap.navidrome[query.sortOrder], + _sort: songListSortMap.navidrome[query.sortBy], + _start: query.startIndex, + album_artist_id: query.artistIds, + album_id: query.albumIds, + title: query.searchTerm, + ...query._custom?.navidrome, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to get song list'); - } + if (res.status !== 200) { + throw new Error('Failed to get song list'); + } - return { - items: res.body.data.map((song) => ndNormalize.song(song, apiClientProps.server, '')), - startIndex: query?.startIndex || 0, - totalRecordCount: Number(res.body.headers.get('x-total-count') || 0), - }; + return { + items: res.body.data.map((song) => ndNormalize.song(song, apiClientProps.server, '')), + startIndex: query?.startIndex || 0, + totalRecordCount: Number(res.body.headers.get('x-total-count') || 0), + }; }; const getSongDetail = async (args: SongDetailArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const res = await ndApiClient(apiClientProps).getSongDetail({ - params: { - id: query.id, - }, - }); + const res = await ndApiClient(apiClientProps).getSongDetail({ + params: { + id: query.id, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to get song detail'); - } + if (res.status !== 200) { + throw new Error('Failed to get song detail'); + } - return ndNormalize.song(res.body.data, apiClientProps.server, ''); + return ndNormalize.song(res.body.data, apiClientProps.server, ''); }; const createPlaylist = async (args: CreatePlaylistArgs): Promise => { - const { body, apiClientProps } = args; + const { body, apiClientProps } = args; - const res = await ndApiClient(apiClientProps).createPlaylist({ - body: { - comment: body.comment, - name: body.name, - public: body._custom?.navidrome?.public, - rules: body._custom?.navidrome?.rules, - sync: body._custom?.navidrome?.sync, - }, - }); + const res = await ndApiClient(apiClientProps).createPlaylist({ + body: { + comment: body.comment, + name: body.name, + public: body._custom?.navidrome?.public, + rules: body._custom?.navidrome?.rules, + sync: body._custom?.navidrome?.sync, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to create playlist'); - } + if (res.status !== 200) { + throw new Error('Failed to create playlist'); + } - return { - id: res.body.data.id, - }; + return { + id: res.body.data.id, + }; }; const updatePlaylist = async (args: UpdatePlaylistArgs): Promise => { - const { query, body, apiClientProps } = args; + const { query, body, apiClientProps } = args; - const res = await ndApiClient(apiClientProps).updatePlaylist({ - body: { - comment: body.comment || '', - name: body.name, - public: body._custom?.navidrome?.public || false, - rules: body._custom?.navidrome?.rules ? body._custom.navidrome.rules : undefined, - sync: body._custom?.navidrome?.sync || undefined, - }, - params: { - id: query.id, - }, - }); + const res = await ndApiClient(apiClientProps).updatePlaylist({ + body: { + comment: body.comment || '', + name: body.name, + public: body._custom?.navidrome?.public || false, + rules: body._custom?.navidrome?.rules ? body._custom.navidrome.rules : undefined, + sync: body._custom?.navidrome?.sync || undefined, + }, + params: { + id: query.id, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to update playlist'); - } + if (res.status !== 200) { + throw new Error('Failed to update playlist'); + } - return null; + return null; }; const deletePlaylist = async (args: DeletePlaylistArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const res = await ndApiClient(apiClientProps).deletePlaylist({ - body: null, - params: { - id: query.id, - }, - }); + const res = await ndApiClient(apiClientProps).deletePlaylist({ + body: null, + params: { + id: query.id, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to delete playlist'); - } + if (res.status !== 200) { + throw new Error('Failed to delete playlist'); + } - return null; + return null; }; const getPlaylistList = async (args: PlaylistListArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const res = await ndApiClient(apiClientProps).getPlaylistList({ - query: { - _end: query.startIndex + (query.limit || 0), - _order: sortOrderMap.navidrome[query.sortOrder], - _sort: query.sortBy ? playlistListSortMap.navidrome[query.sortBy] : undefined, - _start: query.startIndex, - ...query._custom?.navidrome, - }, - }); + const res = await ndApiClient(apiClientProps).getPlaylistList({ + query: { + _end: query.startIndex + (query.limit || 0), + _order: sortOrderMap.navidrome[query.sortOrder], + _sort: query.sortBy ? playlistListSortMap.navidrome[query.sortBy] : undefined, + _start: query.startIndex, + ...query._custom?.navidrome, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to get playlist list'); - } + if (res.status !== 200) { + throw new Error('Failed to get playlist list'); + } - return { - items: res.body.data.map((item) => ndNormalize.playlist(item, apiClientProps.server)), - startIndex: query?.startIndex || 0, - totalRecordCount: Number(res.body.headers.get('x-total-count') || 0), - }; + return { + items: res.body.data.map((item) => ndNormalize.playlist(item, apiClientProps.server)), + startIndex: query?.startIndex || 0, + totalRecordCount: Number(res.body.headers.get('x-total-count') || 0), + }; }; const getPlaylistDetail = async (args: PlaylistDetailArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const res = await ndApiClient(apiClientProps).getPlaylistDetail({ - params: { - id: query.id, - }, - }); + const res = await ndApiClient(apiClientProps).getPlaylistDetail({ + params: { + id: query.id, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to get playlist detail'); - } + if (res.status !== 200) { + throw new Error('Failed to get playlist detail'); + } - return ndNormalize.playlist(res.body.data, apiClientProps.server); + return ndNormalize.playlist(res.body.data, apiClientProps.server); }; const getPlaylistSongList = async ( - args: PlaylistSongListArgs, + args: PlaylistSongListArgs, ): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const res = await ndApiClient(apiClientProps).getPlaylistSongList({ - params: { - id: query.id, - }, - query: { - _end: query.startIndex + (query.limit || 0), - _order: query.sortOrder ? sortOrderMap.navidrome[query.sortOrder] : 'ASC', - _sort: query.sortBy ? songListSortMap.navidrome[query.sortBy] : ndType._enum.songList.ID, - _start: query.startIndex, - }, - }); + const res = await ndApiClient(apiClientProps).getPlaylistSongList({ + params: { + id: query.id, + }, + query: { + _end: query.startIndex + (query.limit || 0), + _order: query.sortOrder ? sortOrderMap.navidrome[query.sortOrder] : 'ASC', + _sort: query.sortBy + ? songListSortMap.navidrome[query.sortBy] + : ndType._enum.songList.ID, + _start: query.startIndex, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to get playlist song list'); - } + if (res.status !== 200) { + throw new Error('Failed to get playlist song list'); + } - return { - items: res.body.data.map((item) => ndNormalize.song(item, apiClientProps.server, '')), - startIndex: query?.startIndex || 0, - totalRecordCount: Number(res.body.headers.get('x-total-count') || 0), - }; + return { + items: res.body.data.map((item) => ndNormalize.song(item, apiClientProps.server, '')), + startIndex: query?.startIndex || 0, + totalRecordCount: Number(res.body.headers.get('x-total-count') || 0), + }; }; const addToPlaylist = async (args: AddToPlaylistArgs): Promise => { - const { body, query, apiClientProps } = args; + const { body, query, apiClientProps } = args; - const res = await ndApiClient(apiClientProps).addToPlaylist({ - body: { - ids: body.songId, - }, - params: { - id: query.id, - }, - }); + const res = await ndApiClient(apiClientProps).addToPlaylist({ + body: { + ids: body.songId, + }, + params: { + id: query.id, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to add to playlist'); - } + if (res.status !== 200) { + throw new Error('Failed to add to playlist'); + } - return null; + return null; }; const removeFromPlaylist = async ( - args: RemoveFromPlaylistArgs, + args: RemoveFromPlaylistArgs, ): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const res = await ndApiClient(apiClientProps).removeFromPlaylist({ - body: null, - params: { - id: query.id, - }, - query: { - id: query.songId, - }, - }); + const res = await ndApiClient(apiClientProps).removeFromPlaylist({ + body: null, + params: { + id: query.id, + }, + query: { + id: query.songId, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to remove from playlist'); - } + if (res.status !== 200) { + throw new Error('Failed to remove from playlist'); + } - return null; + return null; }; export const ndController = { - addToPlaylist, - authenticate, - createPlaylist, - deletePlaylist, - getAlbumArtistDetail, - getAlbumArtistList, - getAlbumDetail, - getAlbumList, - getGenreList, - getPlaylistDetail, - getPlaylistList, - getPlaylistSongList, - getSongDetail, - getSongList, - getUserList, - removeFromPlaylist, - updatePlaylist, + addToPlaylist, + authenticate, + createPlaylist, + deletePlaylist, + getAlbumArtistDetail, + getAlbumArtistList, + getAlbumDetail, + getAlbumList, + getGenreList, + getPlaylistDetail, + getPlaylistList, + getPlaylistSongList, + getSongDetail, + getSongList, + getUserList, + removeFromPlaylist, + updatePlaylist, }; diff --git a/src/renderer/api/navidrome/navidrome-normalize.ts b/src/renderer/api/navidrome/navidrome-normalize.ts index ea6e0b25..50842fa2 100644 --- a/src/renderer/api/navidrome/navidrome-normalize.ts +++ b/src/renderer/api/navidrome/navidrome-normalize.ts @@ -6,226 +6,226 @@ import { ndType } from './navidrome-types'; import { ssType } from '/@/renderer/api/subsonic/subsonic-types'; const getCoverArtUrl = (args: { - baseUrl: string | undefined; - coverArtId: string; - credential: string | undefined; - size: number; + baseUrl: string | undefined; + coverArtId: string; + credential: string | undefined; + size: number; }) => { - const size = args.size ? args.size : 250; + const size = args.size ? args.size : 250; - if (!args.coverArtId || args.coverArtId.match('2a96cbd8b46e442fc41c2b86b821562f')) { - return null; - } + if (!args.coverArtId || args.coverArtId.match('2a96cbd8b46e442fc41c2b86b821562f')) { + return null; + } - return ( - `${args.baseUrl}/rest/getCoverArt.view` + - `?id=${args.coverArtId}` + - `&${args.credential}` + - '&v=1.13.0' + - '&c=feishin' + - `&size=${size}` - ); + return ( + `${args.baseUrl}/rest/getCoverArt.view` + + `?id=${args.coverArtId}` + + `&${args.credential}` + + '&v=1.13.0' + + '&c=feishin' + + `&size=${size}` + ); }; const normalizeSong = ( - item: z.infer | z.infer, - server: ServerListItem | null, - deviceId: string, - imageSize?: number, + item: z.infer | z.infer, + server: ServerListItem | null, + deviceId: string, + imageSize?: number, ): Song => { - let id; - let playlistItemId; + let id; + let playlistItemId; - // Dynamically determine the id field based on whether or not the item is a playlist song - if ('mediaFileId' in item) { - id = item.mediaFileId; - playlistItemId = item.id; - } else { - id = item.id; - } + // Dynamically determine the id field based on whether or not the item is a playlist song + if ('mediaFileId' in item) { + id = item.mediaFileId; + playlistItemId = item.id; + } else { + id = item.id; + } - const imageUrl = getCoverArtUrl({ - baseUrl: server?.url, - coverArtId: id, - credential: server?.credential, - size: imageSize || 100, - }); + const imageUrl = getCoverArtUrl({ + baseUrl: server?.url, + coverArtId: id, + credential: server?.credential, + size: imageSize || 100, + }); - const imagePlaceholderUrl = null; + const imagePlaceholderUrl = null; - return { - album: item.album, - albumArtists: [{ id: item.artistId, imageUrl: null, name: item.artist }], - albumId: item.albumId, - artistName: item.artist, - artists: [{ id: item.artistId, imageUrl: null, name: item.artist }], - bitRate: item.bitRate, - bpm: item.bpm ? item.bpm : null, - channels: item.channels ? item.channels : null, - comment: item.comment ? item.comment : null, - compilation: item.compilation, - container: item.suffix, - createdAt: item.createdAt.split('T')[0], - discNumber: item.discNumber, - duration: item.duration, - genres: item.genres, - id, - imagePlaceholderUrl, - imageUrl, - itemType: LibraryItem.SONG, - lastPlayedAt: item.playDate.includes('0001-') ? null : item.playDate, - lyrics: item.lyrics ? item.lyrics : null, - name: item.title, - path: item.path, - playCount: item.playCount, - playlistItemId, - releaseDate: new Date(item.year, 0, 1).toISOString(), - releaseYear: String(item.year), - serverId: server?.id || 'unknown', - serverType: ServerType.NAVIDROME, - size: item.size, - streamUrl: `${server?.url}/rest/stream.view?id=${id}&v=1.13.0&c=feishin_${deviceId}&${server?.credential}`, - trackNumber: item.trackNumber, - uniqueId: nanoid(), - updatedAt: item.updatedAt, - userFavorite: item.starred || false, - userRating: item.rating || null, - }; + return { + album: item.album, + albumArtists: [{ id: item.artistId, imageUrl: null, name: item.artist }], + albumId: item.albumId, + artistName: item.artist, + artists: [{ id: item.artistId, imageUrl: null, name: item.artist }], + bitRate: item.bitRate, + bpm: item.bpm ? item.bpm : null, + channels: item.channels ? item.channels : null, + comment: item.comment ? item.comment : null, + compilation: item.compilation, + container: item.suffix, + createdAt: item.createdAt.split('T')[0], + discNumber: item.discNumber, + duration: item.duration, + genres: item.genres, + id, + imagePlaceholderUrl, + imageUrl, + itemType: LibraryItem.SONG, + lastPlayedAt: item.playDate.includes('0001-') ? null : item.playDate, + lyrics: item.lyrics ? item.lyrics : null, + name: item.title, + path: item.path, + playCount: item.playCount, + playlistItemId, + releaseDate: new Date(item.year, 0, 1).toISOString(), + releaseYear: String(item.year), + serverId: server?.id || 'unknown', + serverType: ServerType.NAVIDROME, + size: item.size, + streamUrl: `${server?.url}/rest/stream.view?id=${id}&v=1.13.0&c=feishin_${deviceId}&${server?.credential}`, + trackNumber: item.trackNumber, + uniqueId: nanoid(), + updatedAt: item.updatedAt, + userFavorite: item.starred || false, + userRating: item.rating || null, + }; }; const normalizeAlbum = ( - item: z.infer & { - songs?: z.infer; - }, - server: ServerListItem | null, - imageSize?: number, + item: z.infer & { + songs?: z.infer; + }, + server: ServerListItem | null, + imageSize?: number, ): Album => { - const imageUrl = getCoverArtUrl({ - baseUrl: server?.url, - coverArtId: item.coverArtId || item.id, - credential: server?.credential, - size: imageSize || 300, - }); + const imageUrl = getCoverArtUrl({ + baseUrl: server?.url, + coverArtId: item.coverArtId || item.id, + credential: server?.credential, + size: imageSize || 300, + }); - const imagePlaceholderUrl = null; + const imagePlaceholderUrl = null; - const imageBackdropUrl = imageUrl?.replace(/size=\d+/, 'size=1000') || null; + const imageBackdropUrl = imageUrl?.replace(/size=\d+/, 'size=1000') || null; - return { - albumArtists: [{ id: item.albumArtistId, imageUrl: null, name: item.albumArtist }], - artists: [{ id: item.artistId, imageUrl: null, name: item.artist }], - backdropImageUrl: imageBackdropUrl, - createdAt: item.createdAt.split('T')[0], - duration: item.duration * 1000 || null, - genres: item.genres, - id: item.id, - imagePlaceholderUrl, - imageUrl, - isCompilation: item.compilation, - itemType: LibraryItem.ALBUM, - lastPlayedAt: item.playDate.includes('0001-') ? null : item.playDate, - name: item.name, - playCount: item.playCount, - releaseDate: new Date(item.minYear, 0, 1).toISOString(), - releaseYear: item.minYear, - serverId: server?.id || 'unknown', - serverType: ServerType.NAVIDROME, - size: item.size, - songCount: item.songCount, - songs: item.songs ? item.songs.map((song) => normalizeSong(song, server, '')) : undefined, - uniqueId: nanoid(), - updatedAt: item.updatedAt, - userFavorite: item.starred, - userRating: item.rating || null, - }; + return { + albumArtists: [{ id: item.albumArtistId, imageUrl: null, name: item.albumArtist }], + artists: [{ id: item.artistId, imageUrl: null, name: item.artist }], + backdropImageUrl: imageBackdropUrl, + createdAt: item.createdAt.split('T')[0], + duration: item.duration * 1000 || null, + genres: item.genres, + id: item.id, + imagePlaceholderUrl, + imageUrl, + isCompilation: item.compilation, + itemType: LibraryItem.ALBUM, + lastPlayedAt: item.playDate.includes('0001-') ? null : item.playDate, + name: item.name, + playCount: item.playCount, + releaseDate: new Date(item.minYear, 0, 1).toISOString(), + releaseYear: item.minYear, + serverId: server?.id || 'unknown', + serverType: ServerType.NAVIDROME, + size: item.size, + songCount: item.songCount, + songs: item.songs ? item.songs.map((song) => normalizeSong(song, server, '')) : undefined, + uniqueId: nanoid(), + updatedAt: item.updatedAt, + userFavorite: item.starred, + userRating: item.rating || null, + }; }; const normalizeAlbumArtist = ( - item: z.infer & { - similarArtists?: z.infer['artistInfo']['similarArtist']; - }, - server: ServerListItem | null, + item: z.infer & { + similarArtists?: z.infer['artistInfo']['similarArtist']; + }, + server: ServerListItem | null, ): AlbumArtist => { - const imageUrl = - item.largeImageUrl === '/app/artist-placeholder.webp' ? null : item.largeImageUrl; + const imageUrl = + item.largeImageUrl === '/app/artist-placeholder.webp' ? null : item.largeImageUrl; - return { - albumCount: item.albumCount, - backgroundImageUrl: null, - biography: item.biography || null, - duration: null, - genres: item.genres, - id: item.id, - imageUrl: imageUrl || null, - itemType: LibraryItem.ALBUM_ARTIST, - lastPlayedAt: item.playDate.includes('0001-') ? null : item.playDate, - name: item.name, - playCount: item.playCount, - serverId: server?.id || 'unknown', - serverType: ServerType.NAVIDROME, - similarArtists: - item.similarArtists?.map((artist) => ({ - id: artist.id, - imageUrl: artist?.artistImageUrl || null, - name: artist.name, - })) || null, - songCount: item.songCount, - userFavorite: item.starred, - userRating: item.rating, - }; + return { + albumCount: item.albumCount, + backgroundImageUrl: null, + biography: item.biography || null, + duration: null, + genres: item.genres, + id: item.id, + imageUrl: imageUrl || null, + itemType: LibraryItem.ALBUM_ARTIST, + lastPlayedAt: item.playDate.includes('0001-') ? null : item.playDate, + name: item.name, + playCount: item.playCount, + serverId: server?.id || 'unknown', + serverType: ServerType.NAVIDROME, + similarArtists: + item.similarArtists?.map((artist) => ({ + id: artist.id, + imageUrl: artist?.artistImageUrl || null, + name: artist.name, + })) || null, + songCount: item.songCount, + userFavorite: item.starred, + userRating: item.rating, + }; }; const normalizePlaylist = ( - item: z.infer, - server: ServerListItem | null, - imageSize?: number, + item: z.infer, + server: ServerListItem | null, + imageSize?: number, ): Playlist => { - const imageUrl = getCoverArtUrl({ - baseUrl: server?.url, - coverArtId: item.id, - credential: server?.credential, - size: imageSize || 300, - }); + const imageUrl = getCoverArtUrl({ + baseUrl: server?.url, + coverArtId: item.id, + credential: server?.credential, + size: imageSize || 300, + }); - const imagePlaceholderUrl = null; + const imagePlaceholderUrl = null; - return { - description: item.comment, - duration: item.duration * 1000, - genres: [], - id: item.id, - imagePlaceholderUrl, - imageUrl, - itemType: LibraryItem.PLAYLIST, - name: item.name, - owner: item.ownerName, - ownerId: item.ownerId, - public: item.public, - rules: item?.rules || null, - serverId: server?.id || 'unknown', - serverType: ServerType.NAVIDROME, - size: item.size, - songCount: item.songCount, - sync: item.sync, - }; + return { + description: item.comment, + duration: item.duration * 1000, + genres: [], + id: item.id, + imagePlaceholderUrl, + imageUrl, + itemType: LibraryItem.PLAYLIST, + name: item.name, + owner: item.ownerName, + ownerId: item.ownerId, + public: item.public, + rules: item?.rules || null, + serverId: server?.id || 'unknown', + serverType: ServerType.NAVIDROME, + size: item.size, + songCount: item.songCount, + sync: item.sync, + }; }; const normalizeUser = (item: z.infer): User => { - return { - createdAt: item.createdAt, - email: item.email || null, - id: item.id, - isAdmin: item.isAdmin, - lastLoginAt: item.lastLoginAt, - name: item.userName, - updatedAt: item.updatedAt, - }; + return { + createdAt: item.createdAt, + email: item.email || null, + id: item.id, + isAdmin: item.isAdmin, + lastLoginAt: item.lastLoginAt, + name: item.userName, + updatedAt: item.updatedAt, + }; }; export const ndNormalize = { - album: normalizeAlbum, - albumArtist: normalizeAlbumArtist, - playlist: normalizePlaylist, - song: normalizeSong, - user: normalizeUser, + album: normalizeAlbum, + albumArtist: normalizeAlbumArtist, + playlist: normalizePlaylist, + song: normalizeSong, + user: normalizeUser, }; diff --git a/src/renderer/api/navidrome/navidrome-types.ts b/src/renderer/api/navidrome/navidrome-types.ts index adc194bc..90006e7d 100644 --- a/src/renderer/api/navidrome/navidrome-types.ts +++ b/src/renderer/api/navidrome/navidrome-types.ts @@ -5,294 +5,294 @@ const sortOrderValues = ['ASC', 'DESC'] as const; const error = z.string(); const paginationParameters = z.object({ - _end: z.number().optional(), - _order: z.enum(sortOrderValues), - _start: z.number().optional(), + _end: z.number().optional(), + _order: z.enum(sortOrderValues), + _start: z.number().optional(), }); const authenticate = z.object({ - id: z.string(), - isAdmin: z.boolean(), - name: z.string(), - subsonicSalt: z.string(), - subsonicToken: z.string(), - token: z.string(), - username: z.string(), + id: z.string(), + isAdmin: z.boolean(), + name: z.string(), + subsonicSalt: z.string(), + subsonicToken: z.string(), + token: z.string(), + username: z.string(), }); const authenticateParameters = z.object({ - password: z.string(), - username: z.string(), + password: z.string(), + username: z.string(), }); const user = z.object({ - createdAt: z.string(), - email: z.string().optional(), - id: z.string(), - isAdmin: z.boolean(), - lastAccessAt: z.string(), - lastLoginAt: z.string(), - name: z.string(), - updatedAt: z.string(), - userName: z.string(), + createdAt: z.string(), + email: z.string().optional(), + id: z.string(), + isAdmin: z.boolean(), + lastAccessAt: z.string(), + lastLoginAt: z.string(), + name: z.string(), + updatedAt: z.string(), + userName: z.string(), }); const userList = z.array(user); const ndUserListSort = { - NAME: 'name', + NAME: 'name', } as const; const userListParameters = paginationParameters.extend({ - _sort: z.nativeEnum(ndUserListSort).optional(), + _sort: z.nativeEnum(ndUserListSort).optional(), }); const genre = z.object({ - id: z.string(), - name: z.string(), + id: z.string(), + name: z.string(), }); const genreList = z.array(genre); const albumArtist = z.object({ - albumCount: z.number(), - biography: z.string(), - externalInfoUpdatedAt: z.string(), - externalUrl: z.string(), - fullText: z.string(), - genres: z.array(genre), - id: z.string(), - largeImageUrl: z.string().optional(), - mbzArtistId: z.string().optional(), - mediumImageUrl: z.string().optional(), - name: z.string(), - orderArtistName: z.string(), - playCount: z.number(), - playDate: z.string(), - rating: z.number(), - size: z.number(), - smallImageUrl: z.string().optional(), - songCount: z.number(), - starred: z.boolean(), - starredAt: z.string(), + albumCount: z.number(), + biography: z.string(), + externalInfoUpdatedAt: z.string(), + externalUrl: z.string(), + fullText: z.string(), + genres: z.array(genre), + id: z.string(), + largeImageUrl: z.string().optional(), + mbzArtistId: z.string().optional(), + mediumImageUrl: z.string().optional(), + name: z.string(), + orderArtistName: z.string(), + playCount: z.number(), + playDate: z.string(), + rating: z.number(), + size: z.number(), + smallImageUrl: z.string().optional(), + songCount: z.number(), + starred: z.boolean(), + starredAt: z.string(), }); const albumArtistList = z.array(albumArtist); const ndAlbumArtistListSort = { - ALBUM_COUNT: 'albumCount', - FAVORITED: 'starred ASC, starredAt ASC', - NAME: 'name', - PLAY_COUNT: 'playCount', - RATING: 'rating', - SONG_COUNT: 'songCount', + ALBUM_COUNT: 'albumCount', + FAVORITED: 'starred ASC, starredAt ASC', + NAME: 'name', + PLAY_COUNT: 'playCount', + RATING: 'rating', + SONG_COUNT: 'songCount', } as const; const albumArtistListParameters = paginationParameters.extend({ - _sort: z.nativeEnum(ndAlbumArtistListSort).optional(), - genre_id: z.string().optional(), - name: z.string().optional(), - starred: z.boolean().optional(), + _sort: z.nativeEnum(ndAlbumArtistListSort).optional(), + genre_id: z.string().optional(), + name: z.string().optional(), + starred: z.boolean().optional(), }); const album = z.object({ - albumArtist: z.string(), - albumArtistId: z.string(), - allArtistIds: z.string(), - artist: z.string(), - artistId: z.string(), - compilation: z.boolean(), - coverArtId: z.string().optional(), // Removed after v0.48.0 - coverArtPath: z.string().optional(), // Removed after v0.48.0 - createdAt: z.string(), - duration: z.number(), - fullText: z.string(), - genre: z.string(), - genres: z.array(genre), - id: z.string(), - maxYear: z.number(), - mbzAlbumArtistId: z.string().optional(), - mbzAlbumId: z.string().optional(), - minYear: z.number(), - name: z.string(), - orderAlbumArtistName: z.string(), - orderAlbumName: z.string(), - playCount: z.number(), - playDate: z.string(), - rating: z.number().optional(), - size: z.number(), - songCount: z.number(), - sortAlbumArtistName: z.string(), - sortArtistName: z.string(), - starred: z.boolean(), - starredAt: z.string().optional(), - updatedAt: z.string(), + albumArtist: z.string(), + albumArtistId: z.string(), + allArtistIds: z.string(), + artist: z.string(), + artistId: z.string(), + compilation: z.boolean(), + coverArtId: z.string().optional(), // Removed after v0.48.0 + coverArtPath: z.string().optional(), // Removed after v0.48.0 + createdAt: z.string(), + duration: z.number(), + fullText: z.string(), + genre: z.string(), + genres: z.array(genre), + id: z.string(), + maxYear: z.number(), + mbzAlbumArtistId: z.string().optional(), + mbzAlbumId: z.string().optional(), + minYear: z.number(), + name: z.string(), + orderAlbumArtistName: z.string(), + orderAlbumName: z.string(), + playCount: z.number(), + playDate: z.string(), + rating: z.number().optional(), + size: z.number(), + songCount: z.number(), + sortAlbumArtistName: z.string(), + sortArtistName: z.string(), + starred: z.boolean(), + starredAt: z.string().optional(), + updatedAt: z.string(), }); const albumList = z.array(album); const ndAlbumListSort = { - ALBUM_ARTIST: 'albumArtist', - ARTIST: 'artist', - DURATION: 'duration', - NAME: 'name', - PLAY_COUNT: 'playCount', - PLAY_DATE: 'play_date', - RANDOM: 'random', - RATING: 'rating', - RECENTLY_ADDED: 'recently_added', - SONG_COUNT: 'songCount', - STARRED: 'starred', - YEAR: 'max_year', + ALBUM_ARTIST: 'albumArtist', + ARTIST: 'artist', + DURATION: 'duration', + NAME: 'name', + PLAY_COUNT: 'playCount', + PLAY_DATE: 'play_date', + RANDOM: 'random', + RATING: 'rating', + RECENTLY_ADDED: 'recently_added', + SONG_COUNT: 'songCount', + STARRED: 'starred', + YEAR: 'max_year', } as const; const albumListParameters = paginationParameters.extend({ - _sort: z.nativeEnum(ndAlbumListSort).optional(), - album_id: z.string().optional(), - artist_id: z.string().optional(), - compilation: z.boolean().optional(), - genre_id: z.string().optional(), - has_rating: z.boolean().optional(), - id: z.string().optional(), - name: z.string().optional(), - recently_added: z.boolean().optional(), - recently_played: z.boolean().optional(), - starred: z.boolean().optional(), - year: z.number().optional(), + _sort: z.nativeEnum(ndAlbumListSort).optional(), + album_id: z.string().optional(), + artist_id: z.string().optional(), + compilation: z.boolean().optional(), + genre_id: z.string().optional(), + has_rating: z.boolean().optional(), + id: z.string().optional(), + name: z.string().optional(), + recently_added: z.boolean().optional(), + recently_played: z.boolean().optional(), + starred: z.boolean().optional(), + year: z.number().optional(), }); const song = z.object({ - album: z.string(), - albumArtist: z.string(), - albumArtistId: z.string(), - albumId: z.string(), - artist: z.string(), - artistId: z.string(), - bitRate: z.number(), - bookmarkPosition: z.number(), - bpm: z.number().optional(), - channels: z.number().optional(), - comment: z.string().optional(), - compilation: z.boolean(), - createdAt: z.string(), - discNumber: z.number(), - duration: z.number(), - fullText: z.string(), - genre: z.string(), - genres: z.array(genre), - hasCoverArt: z.boolean(), - id: z.string(), - lyrics: z.string().optional(), - mbzAlbumArtistId: z.string().optional(), - mbzAlbumId: z.string().optional(), - mbzArtistId: z.string().optional(), - mbzTrackId: z.string().optional(), - orderAlbumArtistName: z.string(), - orderAlbumName: z.string(), - orderArtistName: z.string(), - orderTitle: z.string(), - path: z.string(), - playCount: z.number(), - playDate: z.string(), - rating: z.number().optional(), - size: z.number(), - sortAlbumArtistName: z.string(), - sortArtistName: z.string(), - starred: z.boolean(), - starredAt: z.string().optional(), - suffix: z.string(), - title: z.string(), - trackNumber: z.number(), - updatedAt: z.string(), - year: z.number(), + album: z.string(), + albumArtist: z.string(), + albumArtistId: z.string(), + albumId: z.string(), + artist: z.string(), + artistId: z.string(), + bitRate: z.number(), + bookmarkPosition: z.number(), + bpm: z.number().optional(), + channels: z.number().optional(), + comment: z.string().optional(), + compilation: z.boolean(), + createdAt: z.string(), + discNumber: z.number(), + duration: z.number(), + fullText: z.string(), + genre: z.string(), + genres: z.array(genre), + hasCoverArt: z.boolean(), + id: z.string(), + lyrics: z.string().optional(), + mbzAlbumArtistId: z.string().optional(), + mbzAlbumId: z.string().optional(), + mbzArtistId: z.string().optional(), + mbzTrackId: z.string().optional(), + orderAlbumArtistName: z.string(), + orderAlbumName: z.string(), + orderArtistName: z.string(), + orderTitle: z.string(), + path: z.string(), + playCount: z.number(), + playDate: z.string(), + rating: z.number().optional(), + size: z.number(), + sortAlbumArtistName: z.string(), + sortArtistName: z.string(), + starred: z.boolean(), + starredAt: z.string().optional(), + suffix: z.string(), + title: z.string(), + trackNumber: z.number(), + updatedAt: z.string(), + year: z.number(), }); const songList = z.array(song); const ndSongListSort = { - ALBUM: 'album, order_album_artist_name, disc_number, track_number, title', - ALBUM_ARTIST: 'order_album_artist_name, album, disc_number, track_number, title', - ALBUM_SONGS: 'album, discNumber, trackNumber', - ARTIST: 'artist', - BPM: 'bpm', - CHANNELS: 'channels', - COMMENT: 'comment', - DURATION: 'duration', - FAVORITED: 'starred ASC, starredAt ASC', - GENRE: 'genre', - ID: 'id', - PLAY_COUNT: 'playCount', - PLAY_DATE: 'playDate', - RATING: 'rating', - RECENTLY_ADDED: 'createdAt', - TITLE: 'title', - TRACK: 'track', - YEAR: 'year, album, discNumber, trackNumber', + ALBUM: 'album, order_album_artist_name, disc_number, track_number, title', + ALBUM_ARTIST: 'order_album_artist_name, album, disc_number, track_number, title', + ALBUM_SONGS: 'album, discNumber, trackNumber', + ARTIST: 'artist', + BPM: 'bpm', + CHANNELS: 'channels', + COMMENT: 'comment', + DURATION: 'duration', + FAVORITED: 'starred ASC, starredAt ASC', + GENRE: 'genre', + ID: 'id', + PLAY_COUNT: 'playCount', + PLAY_DATE: 'playDate', + RATING: 'rating', + RECENTLY_ADDED: 'createdAt', + TITLE: 'title', + TRACK: 'track', + YEAR: 'year, album, discNumber, trackNumber', }; const songListParameters = paginationParameters.extend({ - _sort: z.nativeEnum(ndSongListSort).optional(), - album_artist_id: z.array(z.string()).optional(), - album_id: z.array(z.string()).optional(), - artist_id: z.array(z.string()).optional(), - genre_id: z.string().optional(), - starred: z.boolean().optional(), - title: z.string().optional(), - year: z.number().optional(), + _sort: z.nativeEnum(ndSongListSort).optional(), + album_artist_id: z.array(z.string()).optional(), + album_id: z.array(z.string()).optional(), + artist_id: z.array(z.string()).optional(), + genre_id: z.string().optional(), + starred: z.boolean().optional(), + title: z.string().optional(), + year: z.number().optional(), }); const playlist = z.object({ - comment: z.string(), - createdAt: z.string(), - duration: z.number(), - evaluatedAt: z.string(), - id: z.string(), - name: z.string(), - ownerId: z.string(), - ownerName: z.string(), - path: z.string(), - public: z.boolean(), - rules: z.record(z.string(), z.any()), - size: z.number(), - songCount: z.number(), - sync: z.boolean(), - updatedAt: z.string(), + comment: z.string(), + createdAt: z.string(), + duration: z.number(), + evaluatedAt: z.string(), + id: z.string(), + name: z.string(), + ownerId: z.string(), + ownerName: z.string(), + path: z.string(), + public: z.boolean(), + rules: z.record(z.string(), z.any()), + size: z.number(), + songCount: z.number(), + sync: z.boolean(), + updatedAt: z.string(), }); const playlistList = z.array(playlist); const ndPlaylistListSort = { - DURATION: 'duration', - NAME: 'name', - OWNER: 'ownerName', - PUBLIC: 'public', - SONG_COUNT: 'songCount', - UPDATED_AT: 'updatedAt', + DURATION: 'duration', + NAME: 'name', + OWNER: 'ownerName', + PUBLIC: 'public', + SONG_COUNT: 'songCount', + UPDATED_AT: 'updatedAt', } as const; const playlistListParameters = paginationParameters.extend({ - _sort: z.nativeEnum(ndPlaylistListSort).optional(), - owner_id: z.string().optional(), - smart: z.boolean().optional(), + _sort: z.nativeEnum(ndPlaylistListSort).optional(), + owner_id: z.string().optional(), + smart: z.boolean().optional(), }); const playlistSong = song.extend({ - mediaFileId: z.string(), - playlistId: z.string(), + mediaFileId: z.string(), + playlistId: z.string(), }); const playlistSongList = z.array(playlistSong); const createPlaylist = playlist.pick({ - id: true, + id: true, }); const createPlaylistParameters = z.object({ - comment: z.string().optional(), - name: z.string(), - public: z.boolean().optional(), - rules: z.record(z.any()).optional(), - sync: z.boolean().optional(), + comment: z.string().optional(), + name: z.string(), + public: z.boolean().optional(), + rules: z.record(z.any()).optional(), + sync: z.boolean().optional(), }); const updatePlaylist = playlist; @@ -302,62 +302,62 @@ const updatePlaylistParameters = createPlaylistParameters.partial(); const deletePlaylist = z.null(); const addToPlaylist = z.object({ - added: z.number(), + added: z.number(), }); const addToPlaylistParameters = z.object({ - ids: z.array(z.string()), + ids: z.array(z.string()), }); const removeFromPlaylist = z.object({ - ids: z.array(z.string()), + ids: z.array(z.string()), }); const removeFromPlaylistParameters = z.object({ - id: z.array(z.string()), + id: z.array(z.string()), }); export const ndType = { - _enum: { - albumArtistList: ndAlbumArtistListSort, - albumList: ndAlbumListSort, - playlistList: ndPlaylistListSort, - songList: ndSongListSort, - userList: ndUserListSort, - }, - _parameters: { - addToPlaylist: addToPlaylistParameters, - albumArtistList: albumArtistListParameters, - albumList: albumListParameters, - authenticate: authenticateParameters, - createPlaylist: createPlaylistParameters, - playlistList: playlistListParameters, - removeFromPlaylist: removeFromPlaylistParameters, - songList: songListParameters, - updatePlaylist: updatePlaylistParameters, - userList: userListParameters, - }, - _response: { - addToPlaylist, - album, - albumArtist, - albumArtistList, - albumList, - authenticate, - createPlaylist, - deletePlaylist, - error, - genre, - genreList, - playlist, - playlistList, - playlistSong, - playlistSongList, - removeFromPlaylist, - song, - songList, - updatePlaylist, - user, - userList, - }, + _enum: { + albumArtistList: ndAlbumArtistListSort, + albumList: ndAlbumListSort, + playlistList: ndPlaylistListSort, + songList: ndSongListSort, + userList: ndUserListSort, + }, + _parameters: { + addToPlaylist: addToPlaylistParameters, + albumArtistList: albumArtistListParameters, + albumList: albumListParameters, + authenticate: authenticateParameters, + createPlaylist: createPlaylistParameters, + playlistList: playlistListParameters, + removeFromPlaylist: removeFromPlaylistParameters, + songList: songListParameters, + updatePlaylist: updatePlaylistParameters, + userList: userListParameters, + }, + _response: { + addToPlaylist, + album, + albumArtist, + albumArtistList, + albumList, + authenticate, + createPlaylist, + deletePlaylist, + error, + genre, + genreList, + playlist, + playlistList, + playlistSong, + playlistSongList, + removeFromPlaylist, + song, + songList, + updatePlaylist, + user, + userList, + }, }; diff --git a/src/renderer/api/query-keys.ts b/src/renderer/api/query-keys.ts index ad96655a..98633b31 100644 --- a/src/renderer/api/query-keys.ts +++ b/src/renderer/api/query-keys.ts @@ -1,132 +1,132 @@ import { QueryFunctionContext } from '@tanstack/react-query'; import { LyricSource } from './types'; import type { - AlbumListQuery, - SongListQuery, - AlbumDetailQuery, - AlbumArtistListQuery, - ArtistListQuery, - PlaylistListQuery, - PlaylistDetailQuery, - PlaylistSongListQuery, - UserListQuery, - AlbumArtistDetailQuery, - TopSongListQuery, - SearchQuery, - SongDetailQuery, - RandomSongListQuery, - LyricsQuery, - LyricSearchQuery, + AlbumListQuery, + SongListQuery, + AlbumDetailQuery, + AlbumArtistListQuery, + ArtistListQuery, + PlaylistListQuery, + PlaylistDetailQuery, + PlaylistSongListQuery, + UserListQuery, + AlbumArtistDetailQuery, + TopSongListQuery, + SearchQuery, + SongDetailQuery, + RandomSongListQuery, + LyricsQuery, + LyricSearchQuery, } from './types'; export const queryKeys: Record< - string, - Record QueryFunctionContext['queryKey']> + string, + Record QueryFunctionContext['queryKey']> > = { - albumArtists: { - detail: (serverId: string, query?: AlbumArtistDetailQuery) => { - if (query) return [serverId, 'albumArtists', 'detail', query] as const; - return [serverId, 'albumArtists', 'detail'] as const; + albumArtists: { + detail: (serverId: string, query?: AlbumArtistDetailQuery) => { + if (query) return [serverId, 'albumArtists', 'detail', query] as const; + return [serverId, 'albumArtists', 'detail'] as const; + }, + list: (serverId: string, query?: AlbumArtistListQuery) => { + if (query) return [serverId, 'albumArtists', 'list', query] as const; + return [serverId, 'albumArtists', 'list'] as const; + }, + root: (serverId: string) => [serverId, 'albumArtists'] as const, + topSongs: (serverId: string, query?: TopSongListQuery) => { + if (query) return [serverId, 'albumArtists', 'topSongs', query] as const; + return [serverId, 'albumArtists', 'topSongs'] as const; + }, }, - list: (serverId: string, query?: AlbumArtistListQuery) => { - if (query) return [serverId, 'albumArtists', 'list', query] as const; - return [serverId, 'albumArtists', 'list'] as const; + albums: { + detail: (serverId: string, query?: AlbumDetailQuery) => + [serverId, 'albums', 'detail', query] as const, + list: (serverId: string, query?: AlbumListQuery) => { + if (query) return [serverId, 'albums', 'list', query] as const; + return [serverId, 'albums', 'list'] as const; + }, + root: (serverId: string) => [serverId, 'albums'], + serverRoot: (serverId: string) => [serverId, 'albums'], + songs: (serverId: string, query: SongListQuery) => + [serverId, 'albums', 'songs', query] as const, }, - root: (serverId: string) => [serverId, 'albumArtists'] as const, - topSongs: (serverId: string, query?: TopSongListQuery) => { - if (query) return [serverId, 'albumArtists', 'topSongs', query] as const; - return [serverId, 'albumArtists', 'topSongs'] as const; + artists: { + list: (serverId: string, query?: ArtistListQuery) => { + if (query) return [serverId, 'artists', 'list', query] as const; + return [serverId, 'artists', 'list'] as const; + }, + root: (serverId: string) => [serverId, 'artists'] as const, }, - }, - albums: { - detail: (serverId: string, query?: AlbumDetailQuery) => - [serverId, 'albums', 'detail', query] as const, - list: (serverId: string, query?: AlbumListQuery) => { - if (query) return [serverId, 'albums', 'list', query] as const; - return [serverId, 'albums', 'list'] as const; + genres: { + list: (serverId: string) => [serverId, 'genres', 'list'] as const, + root: (serverId: string) => [serverId, 'genres'] as const, }, - root: (serverId: string) => [serverId, 'albums'], - serverRoot: (serverId: string) => [serverId, 'albums'], - songs: (serverId: string, query: SongListQuery) => - [serverId, 'albums', 'songs', query] as const, - }, - artists: { - list: (serverId: string, query?: ArtistListQuery) => { - if (query) return [serverId, 'artists', 'list', query] as const; - return [serverId, 'artists', 'list'] as const; + musicFolders: { + list: (serverId: string) => [serverId, 'musicFolders', 'list'] as const, }, - root: (serverId: string) => [serverId, 'artists'] as const, - }, - genres: { - list: (serverId: string) => [serverId, 'genres', 'list'] as const, - root: (serverId: string) => [serverId, 'genres'] as const, - }, - musicFolders: { - list: (serverId: string) => [serverId, 'musicFolders', 'list'] as const, - }, - playlists: { - detail: (serverId: string, id?: string, query?: PlaylistDetailQuery) => { - if (query) return [serverId, 'playlists', id, 'detail', query] as const; - if (id) return [serverId, 'playlists', id, 'detail'] as const; - return [serverId, 'playlists', 'detail'] as const; + playlists: { + detail: (serverId: string, id?: string, query?: PlaylistDetailQuery) => { + if (query) return [serverId, 'playlists', id, 'detail', query] as const; + if (id) return [serverId, 'playlists', id, 'detail'] as const; + return [serverId, 'playlists', 'detail'] as const; + }, + detailSongList: (serverId: string, id: string, query?: PlaylistSongListQuery) => { + if (query) return [serverId, 'playlists', id, 'detailSongList', query] as const; + if (id) return [serverId, 'playlists', id, 'detailSongList'] as const; + return [serverId, 'playlists', 'detailSongList'] as const; + }, + list: (serverId: string, query?: PlaylistListQuery) => { + if (query) return [serverId, 'playlists', 'list', query] as const; + return [serverId, 'playlists', 'list'] as const; + }, + root: (serverId: string) => [serverId, 'playlists'] as const, + songList: (serverId: string, id?: string, query?: PlaylistSongListQuery) => { + if (query && id) return [serverId, 'playlists', id, 'songList', query] as const; + if (id) return [serverId, 'playlists', id, 'songList'] as const; + return [serverId, 'playlists', 'songList'] as const; + }, }, - detailSongList: (serverId: string, id: string, query?: PlaylistSongListQuery) => { - if (query) return [serverId, 'playlists', id, 'detailSongList', query] as const; - if (id) return [serverId, 'playlists', id, 'detailSongList'] as const; - return [serverId, 'playlists', 'detailSongList'] as const; + search: { + list: (serverId: string, query?: SearchQuery) => { + if (query) return [serverId, 'search', 'list', query] as const; + return [serverId, 'search', 'list'] as const; + }, + root: (serverId: string) => [serverId, 'search'] as const, }, - list: (serverId: string, query?: PlaylistListQuery) => { - if (query) return [serverId, 'playlists', 'list', query] as const; - return [serverId, 'playlists', 'list'] as const; + server: { + root: (serverId: string) => [serverId] as const, }, - root: (serverId: string) => [serverId, 'playlists'] as const, - songList: (serverId: string, id?: string, query?: PlaylistSongListQuery) => { - if (query && id) return [serverId, 'playlists', id, 'songList', query] as const; - if (id) return [serverId, 'playlists', id, 'songList'] as const; - return [serverId, 'playlists', 'songList'] as const; + songs: { + detail: (serverId: string, query?: SongDetailQuery) => { + if (query) return [serverId, 'songs', 'detail', query] as const; + return [serverId, 'songs', 'detail'] as const; + }, + list: (serverId: string, query?: SongListQuery) => { + if (query) return [serverId, 'songs', 'list', query] as const; + return [serverId, 'songs', 'list'] as const; + }, + lyrics: (serverId: string, query?: LyricsQuery) => { + if (query) return [serverId, 'song', 'lyrics', query] as const; + return [serverId, 'song', 'lyrics'] as const; + }, + lyricsByRemoteId: (searchQuery: { remoteSongId: string; remoteSource: LyricSource }) => { + return ['song', 'lyrics', 'remote', searchQuery] as const; + }, + lyricsSearch: (query?: LyricSearchQuery) => { + if (query) return ['lyrics', 'search', query] as const; + return ['lyrics', 'search'] as const; + }, + randomSongList: (serverId: string, query?: RandomSongListQuery) => { + if (query) return [serverId, 'songs', 'randomSongList', query] as const; + return [serverId, 'songs', 'randomSongList'] as const; + }, + root: (serverId: string) => [serverId, 'songs'] as const, }, - }, - search: { - list: (serverId: string, query?: SearchQuery) => { - if (query) return [serverId, 'search', 'list', query] as const; - return [serverId, 'search', 'list'] as const; + users: { + list: (serverId: string, query?: UserListQuery) => { + if (query) return [serverId, 'users', 'list', query] as const; + return [serverId, 'users', 'list'] as const; + }, + root: (serverId: string) => [serverId, 'users'] as const, }, - root: (serverId: string) => [serverId, 'search'] as const, - }, - server: { - root: (serverId: string) => [serverId] as const, - }, - songs: { - detail: (serverId: string, query?: SongDetailQuery) => { - if (query) return [serverId, 'songs', 'detail', query] as const; - return [serverId, 'songs', 'detail'] as const; - }, - list: (serverId: string, query?: SongListQuery) => { - if (query) return [serverId, 'songs', 'list', query] as const; - return [serverId, 'songs', 'list'] as const; - }, - lyrics: (serverId: string, query?: LyricsQuery) => { - if (query) return [serverId, 'song', 'lyrics', query] as const; - return [serverId, 'song', 'lyrics'] as const; - }, - lyricsByRemoteId: (searchQuery: { remoteSongId: string; remoteSource: LyricSource }) => { - return ['song', 'lyrics', 'remote', searchQuery] as const; - }, - lyricsSearch: (query?: LyricSearchQuery) => { - if (query) return ['lyrics', 'search', query] as const; - return ['lyrics', 'search'] as const; - }, - randomSongList: (serverId: string, query?: RandomSongListQuery) => { - if (query) return [serverId, 'songs', 'randomSongList', query] as const; - return [serverId, 'songs', 'randomSongList'] as const; - }, - root: (serverId: string) => [serverId, 'songs'] as const, - }, - users: { - list: (serverId: string, query?: UserListQuery) => { - if (query) return [serverId, 'users', 'list', query] as const; - return [serverId, 'users', 'list'] as const; - }, - root: (serverId: string) => [serverId, 'users'] as const, - }, }; diff --git a/src/renderer/api/subsonic.types.ts b/src/renderer/api/subsonic.types.ts index 7f6c0bd3..89d103f3 100644 --- a/src/renderer/api/subsonic.types.ts +++ b/src/renderer/api/subsonic.types.ts @@ -1,190 +1,190 @@ export type SSBaseResponse = { - serverVersion?: 'string'; - status: 'string'; - type?: 'string'; - version: 'string'; + serverVersion?: 'string'; + status: 'string'; + type?: 'string'; + version: 'string'; }; export type SSMusicFolderList = SSMusicFolder[]; export type SSMusicFolderListResponse = { - musicFolders: { - musicFolder: SSMusicFolder[]; - }; + musicFolders: { + musicFolder: SSMusicFolder[]; + }; }; export type SSGenreList = SSGenre[]; export type SSGenreListResponse = { - genres: { - genre: SSGenre[]; - }; + genres: { + genre: SSGenre[]; + }; }; export type SSAlbumArtistDetailParams = { - id: string; + id: string; }; export type SSAlbumArtistDetail = SSAlbumArtistListEntry & { album: SSAlbumListEntry[] }; export type SSAlbumArtistDetailResponse = { - artist: SSAlbumArtistListEntry & { - album: SSAlbumListEntry[]; - }; + artist: SSAlbumArtistListEntry & { + album: SSAlbumListEntry[]; + }; }; export type SSAlbumArtistList = { - items: SSAlbumArtistListEntry[]; - startIndex: number; - totalRecordCount: number | null; + items: SSAlbumArtistListEntry[]; + startIndex: number; + totalRecordCount: number | null; }; export type SSAlbumArtistListResponse = { - artists: { - ignoredArticles: string; - index: SSArtistIndex[]; - lastModified: number; - }; + artists: { + ignoredArticles: string; + index: SSArtistIndex[]; + lastModified: number; + }; }; export type SSAlbumList = { - items: SSAlbumListEntry[]; - startIndex: number; - totalRecordCount: number | null; + items: SSAlbumListEntry[]; + startIndex: number; + totalRecordCount: number | null; }; export type SSAlbumListResponse = { - albumList2: { - album: SSAlbumListEntry[]; - }; + albumList2: { + album: SSAlbumListEntry[]; + }; }; export type SSAlbumDetail = Omit & { songs: SSSong[] }; export type SSAlbumDetailResponse = { - album: SSAlbum; + album: SSAlbum; }; export type SSArtistInfoParams = { - count?: number; - id: string; - includeNotPresent?: boolean; + count?: number; + id: string; + includeNotPresent?: boolean; }; export type SSArtistInfoResponse = { - artistInfo2: SSArtistInfo; + artistInfo2: SSArtistInfo; }; export type SSArtistInfo = { - biography: string; - largeImageUrl?: string; - lastFmUrl?: string; - mediumImageUrl?: string; - musicBrainzId?: string; - similarArtist?: { + biography: string; + largeImageUrl?: string; + lastFmUrl?: string; + mediumImageUrl?: string; + musicBrainzId?: string; + similarArtist?: { + albumCount: string; + artistImageUrl?: string; + coverArt?: string; + id: string; + name: string; + }[]; + smallImageUrl?: string; +}; + +export type SSMusicFolder = { + id: number; + name: string; +}; + +export type SSGenre = { + albumCount?: number; + songCount?: number; + value: string; +}; + +export type SSArtistIndex = { + artist: SSAlbumArtistListEntry[]; + name: string; +}; + +export type SSAlbumArtistListEntry = { albumCount: string; artistImageUrl?: string; coverArt?: string; id: string; name: string; - }[]; - smallImageUrl?: string; -}; - -export type SSMusicFolder = { - id: number; - name: string; -}; - -export type SSGenre = { - albumCount?: number; - songCount?: number; - value: string; -}; - -export type SSArtistIndex = { - artist: SSAlbumArtistListEntry[]; - name: string; -}; - -export type SSAlbumArtistListEntry = { - albumCount: string; - artistImageUrl?: string; - coverArt?: string; - id: string; - name: string; }; export type SSAlbumListEntry = { - album: string; - artist: string; - artistId: string; - coverArt: string; - created: string; - duration: number; - genre?: string; - id: string; - isDir: boolean; - isVideo: boolean; - name: string; - parent: string; - songCount: number; - starred?: boolean; - title: string; - userRating?: number; - year: number; + album: string; + artist: string; + artistId: string; + coverArt: string; + created: string; + duration: number; + genre?: string; + id: string; + isDir: boolean; + isVideo: boolean; + name: string; + parent: string; + songCount: number; + starred?: boolean; + title: string; + userRating?: number; + year: number; }; export type SSAlbum = { - song: SSSong[]; + song: SSSong[]; } & SSAlbumListEntry; export type SSSong = { - album: string; - albumId: string; - artist: string; - artistId?: string; - bitRate: number; - contentType: string; - coverArt: string; - created: string; - discNumber?: number; - duration: number; - genre: string; - id: string; - isDir: boolean; - isVideo: boolean; - parent: string; - path: string; - playCount: number; - size: number; - starred?: boolean; - suffix: string; - title: string; - track: number; - type: string; - userRating?: number; - year: number; + album: string; + albumId: string; + artist: string; + artistId?: string; + bitRate: number; + contentType: string; + coverArt: string; + created: string; + discNumber?: number; + duration: number; + genre: string; + id: string; + isDir: boolean; + isVideo: boolean; + parent: string; + path: string; + playCount: number; + size: number; + starred?: boolean; + suffix: string; + title: string; + track: number; + type: string; + userRating?: number; + year: number; }; export type SSAlbumListParams = { - fromYear?: number; - genre?: string; - musicFolderId?: string; - offset?: number; - size?: number; - toYear?: number; - type: string; + fromYear?: number; + genre?: string; + musicFolderId?: string; + offset?: number; + size?: number; + toYear?: number; + type: string; }; export type SSAlbumArtistListParams = { - musicFolderId?: string; + musicFolderId?: string; }; export type SSFavoriteParams = { - albumId?: string; - artistId?: string; - id?: string; + albumId?: string; + artistId?: string; + id?: string; }; export type SSFavorite = null; @@ -192,8 +192,8 @@ export type SSFavorite = null; export type SSFavoriteResponse = null; export type SSRatingParams = { - id: string; - rating: number; + id: string; + rating: number; }; export type SSRating = null; @@ -201,24 +201,24 @@ export type SSRating = null; export type SSRatingResponse = null; export type SSTopSongListParams = { - artist: string; - count?: number; + artist: string; + count?: number; }; export type SSTopSongListResponse = { - topSongs: { - song: SSSong[]; - }; + topSongs: { + song: SSSong[]; + }; }; export type SSTopSongList = { - items: SSSong[]; - startIndex: number; - totalRecordCount: number | null; + items: SSSong[]; + startIndex: number; + totalRecordCount: number | null; }; export type SSScrobbleParams = { - id: string; - submission?: boolean; - time?: number; + id: string; + submission?: boolean; + time?: number; }; diff --git a/src/renderer/api/subsonic/subsonic-api.ts b/src/renderer/api/subsonic/subsonic-api.ts index 05855161..edd7ee3b 100644 --- a/src/renderer/api/subsonic/subsonic-api.ts +++ b/src/renderer/api/subsonic/subsonic-api.ts @@ -10,196 +10,198 @@ import { toast } from '/@/renderer/components/toast/index'; const c = initContract(); export const contract = c.router({ - authenticate: { - method: 'GET', - path: 'ping.view', - query: ssType._parameters.authenticate, - responses: { - 200: ssType._response.authenticate, + authenticate: { + method: 'GET', + path: 'ping.view', + query: ssType._parameters.authenticate, + responses: { + 200: ssType._response.authenticate, + }, }, - }, - createFavorite: { - method: 'GET', - path: 'star.view', - query: ssType._parameters.createFavorite, - responses: { - 200: ssType._response.createFavorite, + createFavorite: { + method: 'GET', + path: 'star.view', + query: ssType._parameters.createFavorite, + responses: { + 200: ssType._response.createFavorite, + }, }, - }, - getArtistInfo: { - method: 'GET', - path: 'getArtistInfo.view', - query: ssType._parameters.artistInfo, - responses: { - 200: ssType._response.artistInfo, + getArtistInfo: { + method: 'GET', + path: 'getArtistInfo.view', + query: ssType._parameters.artistInfo, + responses: { + 200: ssType._response.artistInfo, + }, }, - }, - getMusicFolderList: { - method: 'GET', - path: 'getMusicFolders.view', - responses: { - 200: ssType._response.musicFolderList, + getMusicFolderList: { + method: 'GET', + path: 'getMusicFolders.view', + responses: { + 200: ssType._response.musicFolderList, + }, }, - }, - getRandomSongList: { - method: 'GET', - path: 'getRandomSongs.view', - query: ssType._parameters.randomSongList, - responses: { - 200: ssType._response.randomSongList, + getRandomSongList: { + method: 'GET', + path: 'getRandomSongs.view', + query: ssType._parameters.randomSongList, + responses: { + 200: ssType._response.randomSongList, + }, }, - }, - getTopSongsList: { - method: 'GET', - path: 'getTopSongs.view', - query: ssType._parameters.topSongsList, - responses: { - 200: ssType._response.topSongsList, + getTopSongsList: { + method: 'GET', + path: 'getTopSongs.view', + query: ssType._parameters.topSongsList, + responses: { + 200: ssType._response.topSongsList, + }, }, - }, - removeFavorite: { - method: 'GET', - path: 'unstar.view', - query: ssType._parameters.removeFavorite, - responses: { - 200: ssType._response.removeFavorite, + removeFavorite: { + method: 'GET', + path: 'unstar.view', + query: ssType._parameters.removeFavorite, + responses: { + 200: ssType._response.removeFavorite, + }, }, - }, - scrobble: { - method: 'GET', - path: 'scrobble.view', - query: ssType._parameters.scrobble, - responses: { - 200: ssType._response.scrobble, + scrobble: { + method: 'GET', + path: 'scrobble.view', + query: ssType._parameters.scrobble, + responses: { + 200: ssType._response.scrobble, + }, }, - }, - search3: { - method: 'GET', - path: 'search3.view', - query: ssType._parameters.search3, - responses: { - 200: ssType._response.search3, + search3: { + method: 'GET', + path: 'search3.view', + query: ssType._parameters.search3, + responses: { + 200: ssType._response.search3, + }, }, - }, - setRating: { - method: 'GET', - path: 'setRating.view', - query: ssType._parameters.setRating, - responses: { - 200: ssType._response.setRating, + setRating: { + method: 'GET', + path: 'setRating.view', + query: ssType._parameters.setRating, + responses: { + 200: ssType._response.setRating, + }, }, - }, }); const axiosClient = axios.create({}); axiosClient.defaults.paramsSerializer = (params) => { - return qs.stringify(params, { arrayFormat: 'repeat' }); + return qs.stringify(params, { arrayFormat: 'repeat' }); }; axiosClient.interceptors.response.use( - (response) => { - const data = response.data; + (response) => { + const data = response.data; - if (data['subsonic-response'].status !== 'ok') { - // Suppress code related to non-linked lastfm or spotify from Navidrome - if (data['subsonic-response'].error.code !== 0) { - toast.error({ - message: data['subsonic-response'].error.message, - title: 'Issue from Subsonic API', - }); - } - } + if (data['subsonic-response'].status !== 'ok') { + // Suppress code related to non-linked lastfm or spotify from Navidrome + if (data['subsonic-response'].error.code !== 0) { + toast.error({ + message: data['subsonic-response'].error.message, + title: 'Issue from Subsonic API', + }); + } + } - return response; - }, - (error) => { - return Promise.reject(error); - }, + return response; + }, + (error) => { + return Promise.reject(error); + }, ); const parsePath = (fullPath: string) => { - const [path, params] = fullPath.split('?'); + const [path, params] = fullPath.split('?'); - const parsedParams = qs.parse(params); - const notNilParams = omitBy(parsedParams, (value) => value === 'undefined' || value === 'null'); + const parsedParams = qs.parse(params); + const notNilParams = omitBy(parsedParams, (value) => value === 'undefined' || value === 'null'); - return { - params: notNilParams, - path, - }; + return { + params: notNilParams, + path, + }; }; export const ssApiClient = (args: { - server: ServerListItem | null; - signal?: AbortSignal; - url?: string; + server: ServerListItem | null; + signal?: AbortSignal; + url?: string; }) => { - const { server, url, signal } = args; + const { server, url, signal } = args; - return initClient(contract, { - api: async ({ path, method, headers, body }) => { - let baseUrl: string | undefined; - const authParams: Record = {}; + return initClient(contract, { + api: async ({ path, method, headers, body }) => { + let baseUrl: string | undefined; + const authParams: Record = {}; - const { params, path: api } = parsePath(path); + const { params, path: api } = parsePath(path); - if (server) { - baseUrl = `${server.url}/rest`; - const token = server.credential; - const params = token.split(/&?\w=/gm); + if (server) { + baseUrl = `${server.url}/rest`; + const token = server.credential; + const params = token.split(/&?\w=/gm); - authParams.u = server.username; - if (params?.length === 4) { - authParams.s = params[2]; - authParams.t = params[3]; - } else if (params?.length === 3) { - authParams.p = params[2]; - } - } else { - baseUrl = url; - } + authParams.u = server.username; + if (params?.length === 4) { + authParams.s = params[2]; + authParams.t = params[3]; + } else if (params?.length === 3) { + authParams.p = params[2]; + } + } else { + baseUrl = url; + } - try { - const result = await axiosClient.request>({ - data: body, - headers, - method: method as Method, - params: { - c: 'Feishin', - f: 'json', - v: '1.13.0', - ...authParams, - ...params, - }, - signal, - url: `${baseUrl}/${api}`, - }); + try { + const result = await axiosClient.request< + z.infer + >({ + data: body, + headers, + method: method as Method, + params: { + c: 'Feishin', + f: 'json', + v: '1.13.0', + ...authParams, + ...params, + }, + signal, + url: `${baseUrl}/${api}`, + }); - return { - body: result.data['subsonic-response'], - headers: result.headers as any, - status: result.status, - }; - } catch (e: Error | AxiosError | any) { - console.log('CATCH ERR'); + return { + body: result.data['subsonic-response'], + headers: result.headers as any, + status: result.status, + }; + } catch (e: Error | AxiosError | any) { + console.log('CATCH ERR'); - if (isAxiosError(e)) { - const error = e as AxiosError; - const response = error.response as AxiosResponse; + if (isAxiosError(e)) { + const error = e as AxiosError; + const response = error.response as AxiosResponse; - return { - body: response?.data, - headers: response.headers as any, - status: response?.status, - }; - } - throw e; - } - }, - baseHeaders: { - 'Content-Type': 'application/json', - }, - baseUrl: '', - }); + return { + body: response?.data, + headers: response.headers as any, + status: response?.status, + }; + } + throw e; + } + }, + baseHeaders: { + 'Content-Type': 'application/json', + }, + baseUrl: '', + }); }; diff --git a/src/renderer/api/subsonic/subsonic-controller.ts b/src/renderer/api/subsonic/subsonic-controller.ts index 1fc4d815..32c0de17 100644 --- a/src/renderer/api/subsonic/subsonic-controller.ts +++ b/src/renderer/api/subsonic/subsonic-controller.ts @@ -4,91 +4,91 @@ import { ssApiClient } from '/@/renderer/api/subsonic/subsonic-api'; import { ssNormalize } from '/@/renderer/api/subsonic/subsonic-normalize'; import { ssType } from '/@/renderer/api/subsonic/subsonic-types'; import { - ArtistInfoArgs, - AuthenticationResponse, - FavoriteArgs, - FavoriteResponse, - LibraryItem, - MusicFolderListArgs, - MusicFolderListResponse, - SetRatingArgs, - RatingResponse, - ScrobbleArgs, - ScrobbleResponse, - SongListResponse, - TopSongListArgs, - SearchArgs, - SearchResponse, - RandomSongListResponse, - RandomSongListArgs, + ArtistInfoArgs, + AuthenticationResponse, + FavoriteArgs, + FavoriteResponse, + LibraryItem, + MusicFolderListArgs, + MusicFolderListResponse, + SetRatingArgs, + RatingResponse, + ScrobbleArgs, + ScrobbleResponse, + SongListResponse, + TopSongListArgs, + SearchArgs, + SearchResponse, + RandomSongListResponse, + RandomSongListArgs, } from '/@/renderer/api/types'; import { randomString } from '/@/renderer/utils'; const authenticate = async ( - url: string, - body: { - legacy?: boolean; - password: string; - username: string; - }, -): Promise => { - let credential: string; - let credentialParams: { - p?: string; - s?: string; - t?: string; - u: string; - }; - - const cleanServerUrl = url.replace(/\/$/, ''); - - if (body.legacy) { - credential = `u=${body.username}&p=${body.password}`; - credentialParams = { - p: body.password, - u: body.username, - }; - } else { - const salt = randomString(12); - const hash = md5(body.password + salt); - credential = `u=${body.username}&s=${salt}&t=${hash}`; - credentialParams = { - s: salt, - t: hash, - u: body.username, - }; - } - - await ssApiClient({ server: null, url: cleanServerUrl }).authenticate({ - query: { - c: 'Feishin', - f: 'json', - v: '1.13.0', - ...credentialParams, + url: string, + body: { + legacy?: boolean; + password: string; + username: string; }, - }); +): Promise => { + let credential: string; + let credentialParams: { + p?: string; + s?: string; + t?: string; + u: string; + }; - return { - credential, - userId: null, - username: body.username, - }; + const cleanServerUrl = url.replace(/\/$/, ''); + + if (body.legacy) { + credential = `u=${body.username}&p=${body.password}`; + credentialParams = { + p: body.password, + u: body.username, + }; + } else { + const salt = randomString(12); + const hash = md5(body.password + salt); + credential = `u=${body.username}&s=${salt}&t=${hash}`; + credentialParams = { + s: salt, + t: hash, + u: body.username, + }; + } + + await ssApiClient({ server: null, url: cleanServerUrl }).authenticate({ + query: { + c: 'Feishin', + f: 'json', + v: '1.13.0', + ...credentialParams, + }, + }); + + return { + credential, + userId: null, + username: body.username, + }; }; const getMusicFolderList = async (args: MusicFolderListArgs): Promise => { - const { apiClientProps } = args; + const { apiClientProps } = args; - const res = await ssApiClient(apiClientProps).getMusicFolderList({}); + const res = await ssApiClient(apiClientProps).getMusicFolderList({}); - if (res.status !== 200) { - throw new Error('Failed to get music folder list'); - } + if (res.status !== 200) { + throw new Error('Failed to get music folder list'); + } - return { - items: res.body.musicFolders.musicFolder, - startIndex: 0, - totalRecordCount: res.body.musicFolders.musicFolder.length, - }; + return { + items: res.body.musicFolders.musicFolder, + startIndex: 0, + totalRecordCount: res.body.musicFolders.musicFolder.length, + }; }; // export const getAlbumArtistDetail = async ( @@ -198,184 +198,185 @@ const getMusicFolderList = async (args: MusicFolderListArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const res = await ssApiClient(apiClientProps).createFavorite({ - query: { - albumId: query.type === LibraryItem.ALBUM ? query.id : undefined, - artistId: query.type === LibraryItem.ALBUM_ARTIST ? query.id : undefined, - id: query.type === LibraryItem.SONG ? query.id : undefined, - }, - }); + const res = await ssApiClient(apiClientProps).createFavorite({ + query: { + albumId: query.type === LibraryItem.ALBUM ? query.id : undefined, + artistId: query.type === LibraryItem.ALBUM_ARTIST ? query.id : undefined, + id: query.type === LibraryItem.SONG ? query.id : undefined, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to create favorite'); - } + if (res.status !== 200) { + throw new Error('Failed to create favorite'); + } - return null; + return null; }; const removeFavorite = async (args: FavoriteArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const res = await ssApiClient(apiClientProps).removeFavorite({ - query: { - albumId: query.type === LibraryItem.ALBUM ? query.id : undefined, - artistId: query.type === LibraryItem.ALBUM_ARTIST ? query.id : undefined, - id: query.type === LibraryItem.SONG ? query.id : undefined, - }, - }); + const res = await ssApiClient(apiClientProps).removeFavorite({ + query: { + albumId: query.type === LibraryItem.ALBUM ? query.id : undefined, + artistId: query.type === LibraryItem.ALBUM_ARTIST ? query.id : undefined, + id: query.type === LibraryItem.SONG ? query.id : undefined, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to delete favorite'); - } + if (res.status !== 200) { + throw new Error('Failed to delete favorite'); + } - return null; + return null; }; const setRating = async (args: SetRatingArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const itemIds = query.item.map((item) => item.id); + const itemIds = query.item.map((item) => item.id); - for (const id of itemIds) { - await ssApiClient(apiClientProps).setRating({ - query: { - id, - rating: query.rating, - }, - }); - } + for (const id of itemIds) { + await ssApiClient(apiClientProps).setRating({ + query: { + id, + rating: query.rating, + }, + }); + } - return null; + return null; }; const getTopSongList = async (args: TopSongListArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const res = await ssApiClient(apiClientProps).getTopSongsList({ - query: { - artist: query.artist, - count: query.limit, - }, - }); + const res = await ssApiClient(apiClientProps).getTopSongsList({ + query: { + artist: query.artist, + count: query.limit, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to get top songs'); - } + if (res.status !== 200) { + throw new Error('Failed to get top songs'); + } - return { - items: - res.body.topSongs?.song?.map((song) => ssNormalize.song(song, apiClientProps.server, '')) || - [], - startIndex: 0, - totalRecordCount: res.body.topSongs?.song?.length || 0, - }; + return { + items: + res.body.topSongs?.song?.map((song) => + ssNormalize.song(song, apiClientProps.server, ''), + ) || [], + startIndex: 0, + totalRecordCount: res.body.topSongs?.song?.length || 0, + }; }; const getArtistInfo = async ( - args: ArtistInfoArgs, + args: ArtistInfoArgs, ): Promise> => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const res = await ssApiClient(apiClientProps).getArtistInfo({ - query: { - count: query.limit, - id: query.artistId, - }, - }); + const res = await ssApiClient(apiClientProps).getArtistInfo({ + query: { + count: query.limit, + id: query.artistId, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to get artist info'); - } + if (res.status !== 200) { + throw new Error('Failed to get artist info'); + } - return res.body; + return res.body; }; const scrobble = async (args: ScrobbleArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const res = await ssApiClient(apiClientProps).scrobble({ - query: { - id: query.id, - submission: query.submission, - }, - }); + const res = await ssApiClient(apiClientProps).scrobble({ + query: { + id: query.id, + submission: query.submission, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to scrobble'); - } + if (res.status !== 200) { + throw new Error('Failed to scrobble'); + } - return null; + return null; }; const search3 = async (args: SearchArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const res = await ssApiClient(apiClientProps).search3({ - query: { - albumCount: query.albumLimit, - albumOffset: query.albumStartIndex, - artistCount: query.albumArtistLimit, - artistOffset: query.albumArtistStartIndex, - query: query.query, - songCount: query.songLimit, - songOffset: query.songStartIndex, - }, - }); + const res = await ssApiClient(apiClientProps).search3({ + query: { + albumCount: query.albumLimit, + albumOffset: query.albumStartIndex, + artistCount: query.albumArtistLimit, + artistOffset: query.albumArtistStartIndex, + query: query.query, + songCount: query.songLimit, + songOffset: query.songStartIndex, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to search'); - } + if (res.status !== 200) { + throw new Error('Failed to search'); + } - return { - albumArtists: res.body.searchResult3?.artist?.map((artist) => - ssNormalize.albumArtist(artist, apiClientProps.server), - ), - albums: res.body.searchResult3?.album?.map((album) => - ssNormalize.album(album, apiClientProps.server), - ), - songs: res.body.searchResult3?.song?.map((song) => - ssNormalize.song(song, apiClientProps.server, ''), - ), - }; + return { + albumArtists: res.body.searchResult3?.artist?.map((artist) => + ssNormalize.albumArtist(artist, apiClientProps.server), + ), + albums: res.body.searchResult3?.album?.map((album) => + ssNormalize.album(album, apiClientProps.server), + ), + songs: res.body.searchResult3?.song?.map((song) => + ssNormalize.song(song, apiClientProps.server, ''), + ), + }; }; const getRandomSongList = async (args: RandomSongListArgs): Promise => { - const { query, apiClientProps } = args; + const { query, apiClientProps } = args; - const res = await ssApiClient(apiClientProps).getRandomSongList({ - query: { - fromYear: query.minYear, - genre: query.genre, - musicFolderId: query.musicFolderId, - size: query.limit, - toYear: query.maxYear, - }, - }); + const res = await ssApiClient(apiClientProps).getRandomSongList({ + query: { + fromYear: query.minYear, + genre: query.genre, + musicFolderId: query.musicFolderId, + size: query.limit, + toYear: query.maxYear, + }, + }); - if (res.status !== 200) { - throw new Error('Failed to get random songs'); - } + if (res.status !== 200) { + throw new Error('Failed to get random songs'); + } - return { - items: res.body.randomSongs?.song?.map((song) => - ssNormalize.song(song, apiClientProps.server, ''), - ), - startIndex: 0, - totalRecordCount: res.body.randomSongs?.song?.length || 0, - }; + return { + items: res.body.randomSongs?.song?.map((song) => + ssNormalize.song(song, apiClientProps.server, ''), + ), + startIndex: 0, + totalRecordCount: res.body.randomSongs?.song?.length || 0, + }; }; export const ssController = { - authenticate, - createFavorite, - getArtistInfo, - getMusicFolderList, - getRandomSongList, - getTopSongList, - removeFavorite, - scrobble, - search3, - setRating, + authenticate, + createFavorite, + getArtistInfo, + getMusicFolderList, + getRandomSongList, + getTopSongList, + removeFavorite, + scrobble, + search3, + setRating, }; diff --git a/src/renderer/api/subsonic/subsonic-normalize.ts b/src/renderer/api/subsonic/subsonic-normalize.ts index d2e54d54..a55769fd 100644 --- a/src/renderer/api/subsonic/subsonic-normalize.ts +++ b/src/renderer/api/subsonic/subsonic-normalize.ts @@ -5,176 +5,178 @@ import { QueueSong, LibraryItem, AlbumArtist, Album } from '/@/renderer/api/type import { ServerListItem, ServerType } from '/@/renderer/types'; const getCoverArtUrl = (args: { - baseUrl: string | undefined; - coverArtId?: string; - credential: string | undefined; - size: number; + baseUrl: string | undefined; + coverArtId?: string; + credential: string | undefined; + size: number; }) => { - const size = args.size ? args.size : 250; + const size = args.size ? args.size : 250; - if (!args.coverArtId || args.coverArtId.match('2a96cbd8b46e442fc41c2b86b821562f')) { - return null; - } + if (!args.coverArtId || args.coverArtId.match('2a96cbd8b46e442fc41c2b86b821562f')) { + return null; + } - return ( - `${args.baseUrl}/rest/getCoverArt.view` + - `?id=${args.coverArtId}` + - `&${args.credential}` + - '&v=1.13.0' + - '&c=feishin' + - `&size=${size}` - ); + return ( + `${args.baseUrl}/rest/getCoverArt.view` + + `?id=${args.coverArtId}` + + `&${args.credential}` + + '&v=1.13.0' + + '&c=feishin' + + `&size=${size}` + ); }; const normalizeSong = ( - item: z.infer, - server: ServerListItem | null, - deviceId: string, + item: z.infer, + server: ServerListItem | null, + deviceId: string, ): QueueSong => { - const imageUrl = - getCoverArtUrl({ - baseUrl: server?.url, - coverArtId: item.coverArt, - credential: server?.credential, - size: 100, - }) || null; + const imageUrl = + getCoverArtUrl({ + baseUrl: server?.url, + coverArtId: item.coverArt, + credential: server?.credential, + size: 100, + }) || null; - const streamUrl = `${server?.url}/rest/stream.view?id=${item.id}&v=1.13.0&c=feishin_${deviceId}&${server?.credential}`; + const streamUrl = `${server?.url}/rest/stream.view?id=${item.id}&v=1.13.0&c=feishin_${deviceId}&${server?.credential}`; - return { - album: item.album || '', - albumArtists: [ - { - id: item.artistId || '', - imageUrl: null, - name: item.artist || '', - }, - ], - albumId: item.albumId || '', - artistName: item.artist || '', - artists: [ - { - id: item.artistId || '', - imageUrl: null, - name: item.artist || '', - }, - ], - bitRate: item.bitRate || 0, - bpm: null, - channels: null, - comment: null, - compilation: null, - container: item.contentType, - createdAt: item.created, - discNumber: item.discNumber || 1, - duration: item.duration || 0, - genres: item.genre - ? [ - { - id: item.genre, - name: item.genre, - }, - ] - : [], - id: item.id, - imagePlaceholderUrl: null, - imageUrl, - itemType: LibraryItem.SONG, - lastPlayedAt: null, - lyrics: null, - name: item.title, - path: item.path, - playCount: item?.playCount || 0, - releaseDate: null, - releaseYear: item.year ? String(item.year) : null, - serverId: server?.id || 'unknown', - serverType: ServerType.SUBSONIC, - size: item.size, - streamUrl, - trackNumber: item.track || 1, - uniqueId: nanoid(), - updatedAt: '', - userFavorite: item.starred || false, - userRating: item.userRating || null, - }; + return { + album: item.album || '', + albumArtists: [ + { + id: item.artistId || '', + imageUrl: null, + name: item.artist || '', + }, + ], + albumId: item.albumId || '', + artistName: item.artist || '', + artists: [ + { + id: item.artistId || '', + imageUrl: null, + name: item.artist || '', + }, + ], + bitRate: item.bitRate || 0, + bpm: null, + channels: null, + comment: null, + compilation: null, + container: item.contentType, + createdAt: item.created, + discNumber: item.discNumber || 1, + duration: item.duration || 0, + genres: item.genre + ? [ + { + id: item.genre, + name: item.genre, + }, + ] + : [], + id: item.id, + imagePlaceholderUrl: null, + imageUrl, + itemType: LibraryItem.SONG, + lastPlayedAt: null, + lyrics: null, + name: item.title, + path: item.path, + playCount: item?.playCount || 0, + releaseDate: null, + releaseYear: item.year ? String(item.year) : null, + serverId: server?.id || 'unknown', + serverType: ServerType.SUBSONIC, + size: item.size, + streamUrl, + trackNumber: item.track || 1, + uniqueId: nanoid(), + updatedAt: '', + userFavorite: item.starred || false, + userRating: item.userRating || null, + }; }; const normalizeAlbumArtist = ( - item: z.infer, - server: ServerListItem | null, + item: z.infer, + server: ServerListItem | null, ): AlbumArtist => { - const imageUrl = - getCoverArtUrl({ - baseUrl: server?.url, - coverArtId: item.coverArt, - credential: server?.credential, - size: 100, - }) || null; + const imageUrl = + getCoverArtUrl({ + baseUrl: server?.url, + coverArtId: item.coverArt, + credential: server?.credential, + size: 100, + }) || null; - return { - albumCount: item.albumCount ? Number(item.albumCount) : 0, - backgroundImageUrl: null, - biography: null, - duration: null, - genres: [], - id: item.id, - imageUrl, - itemType: LibraryItem.ALBUM_ARTIST, - lastPlayedAt: null, - name: item.name, - playCount: null, - serverId: server?.id || 'unknown', - serverType: ServerType.SUBSONIC, - similarArtists: [], - songCount: null, - userFavorite: false, - userRating: null, - }; + return { + albumCount: item.albumCount ? Number(item.albumCount) : 0, + backgroundImageUrl: null, + biography: null, + duration: null, + genres: [], + id: item.id, + imageUrl, + itemType: LibraryItem.ALBUM_ARTIST, + lastPlayedAt: null, + name: item.name, + playCount: null, + serverId: server?.id || 'unknown', + serverType: ServerType.SUBSONIC, + similarArtists: [], + songCount: null, + userFavorite: false, + userRating: null, + }; }; const normalizeAlbum = ( - item: z.infer, - server: ServerListItem | null, + item: z.infer, + server: ServerListItem | null, ): Album => { - const imageUrl = - getCoverArtUrl({ - baseUrl: server?.url, - coverArtId: item.coverArt, - credential: server?.credential, - size: 300, - }) || null; + const imageUrl = + getCoverArtUrl({ + baseUrl: server?.url, + coverArtId: item.coverArt, + credential: server?.credential, + size: 300, + }) || null; - return { - albumArtists: item.artistId ? [{ id: item.artistId, imageUrl: null, name: item.artist }] : [], - artists: item.artistId ? [{ id: item.artistId, imageUrl: null, name: item.artist }] : [], - backdropImageUrl: null, - createdAt: item.created, - duration: item.duration, - genres: item.genre ? [{ id: item.genre, name: item.genre }] : [], - id: item.id, - imagePlaceholderUrl: null, - imageUrl, - isCompilation: null, - itemType: LibraryItem.ALBUM, - lastPlayedAt: null, - name: item.name, - playCount: null, - releaseDate: item.year ? new Date(item.year, 0, 1).toISOString() : null, - releaseYear: item.year ? Number(item.year) : null, - serverId: server?.id || 'unknown', - serverType: ServerType.SUBSONIC, - size: null, - songCount: item.songCount, - songs: [], - uniqueId: nanoid(), - updatedAt: item.created, - userFavorite: item.starred || false, - userRating: item.userRating || null, - }; + return { + albumArtists: item.artistId + ? [{ id: item.artistId, imageUrl: null, name: item.artist }] + : [], + artists: item.artistId ? [{ id: item.artistId, imageUrl: null, name: item.artist }] : [], + backdropImageUrl: null, + createdAt: item.created, + duration: item.duration, + genres: item.genre ? [{ id: item.genre, name: item.genre }] : [], + id: item.id, + imagePlaceholderUrl: null, + imageUrl, + isCompilation: null, + itemType: LibraryItem.ALBUM, + lastPlayedAt: null, + name: item.name, + playCount: null, + releaseDate: item.year ? new Date(item.year, 0, 1).toISOString() : null, + releaseYear: item.year ? Number(item.year) : null, + serverId: server?.id || 'unknown', + serverType: ServerType.SUBSONIC, + size: null, + songCount: item.songCount, + songs: [], + uniqueId: nanoid(), + updatedAt: item.created, + userFavorite: item.starred || false, + userRating: item.userRating || null, + }; }; export const ssNormalize = { - album: normalizeAlbum, - albumArtist: normalizeAlbumArtist, - song: normalizeSong, + album: normalizeAlbum, + albumArtist: normalizeAlbumArtist, + song: normalizeSong, }; diff --git a/src/renderer/api/subsonic/subsonic-types.ts b/src/renderer/api/subsonic/subsonic-types.ts index 1c8dd7f7..3360081b 100644 --- a/src/renderer/api/subsonic/subsonic-types.ts +++ b/src/renderer/api/subsonic/subsonic-types.ts @@ -1,240 +1,240 @@ import { z } from 'zod'; const baseResponse = z.object({ - 'subsonic-response': z.object({ - status: z.string(), - version: z.string(), - }), + 'subsonic-response': z.object({ + status: z.string(), + version: z.string(), + }), }); const authenticate = z.null(); const authenticateParameters = z.object({ - c: z.string(), - f: z.string(), - p: z.string().optional(), - s: z.string().optional(), - t: z.string().optional(), - u: z.string(), - v: z.string(), + c: z.string(), + f: z.string(), + p: z.string().optional(), + s: z.string().optional(), + t: z.string().optional(), + u: z.string(), + v: z.string(), }); const createFavoriteParameters = z.object({ - albumId: z.array(z.string()).optional(), - artistId: z.array(z.string()).optional(), - id: z.array(z.string()).optional(), + albumId: z.array(z.string()).optional(), + artistId: z.array(z.string()).optional(), + id: z.array(z.string()).optional(), }); const createFavorite = z.null(); const removeFavoriteParameters = z.object({ - albumId: z.array(z.string()).optional(), - artistId: z.array(z.string()).optional(), - id: z.array(z.string()).optional(), + albumId: z.array(z.string()).optional(), + artistId: z.array(z.string()).optional(), + id: z.array(z.string()).optional(), }); const removeFavorite = z.null(); const setRatingParameters = z.object({ - id: z.string(), - rating: z.number(), + id: z.string(), + rating: z.number(), }); const setRating = z.null(); const musicFolder = z.object({ - id: z.string(), - name: z.string(), + id: z.string(), + name: z.string(), }); const musicFolderList = z.object({ - musicFolders: z.object({ - musicFolder: z.array(musicFolder), - }), + musicFolders: z.object({ + musicFolder: z.array(musicFolder), + }), }); const song = z.object({ - album: z.string().optional(), - albumId: z.string().optional(), - artist: z.string().optional(), - artistId: z.string().optional(), - averageRating: z.number().optional(), - bitRate: z.number().optional(), - contentType: z.string(), - coverArt: z.string().optional(), - created: z.string(), - discNumber: z.number(), - duration: z.number().optional(), - genre: z.string().optional(), - id: z.string(), - isDir: z.boolean(), - isVideo: z.boolean(), - parent: z.string(), - path: z.string(), - playCount: z.number().optional(), - size: z.number(), - starred: z.boolean().optional(), - suffix: z.string(), - title: z.string(), - track: z.number().optional(), - type: z.string(), - userRating: z.number().optional(), - year: z.number().optional(), + album: z.string().optional(), + albumId: z.string().optional(), + artist: z.string().optional(), + artistId: z.string().optional(), + averageRating: z.number().optional(), + bitRate: z.number().optional(), + contentType: z.string(), + coverArt: z.string().optional(), + created: z.string(), + discNumber: z.number(), + duration: z.number().optional(), + genre: z.string().optional(), + id: z.string(), + isDir: z.boolean(), + isVideo: z.boolean(), + parent: z.string(), + path: z.string(), + playCount: z.number().optional(), + size: z.number(), + starred: z.boolean().optional(), + suffix: z.string(), + title: z.string(), + track: z.number().optional(), + type: z.string(), + userRating: z.number().optional(), + year: z.number().optional(), }); const album = z.object({ - album: z.string(), - artist: z.string(), - artistId: z.string(), - coverArt: z.string(), - created: z.string(), - duration: z.number(), - genre: z.string().optional(), - id: z.string(), - isDir: z.boolean(), - isVideo: z.boolean(), - name: z.string(), - parent: z.string(), - song: z.array(song), - songCount: z.number(), - starred: z.boolean().optional(), - title: z.string(), - userRating: z.number().optional(), - year: z.number().optional(), + album: z.string(), + artist: z.string(), + artistId: z.string(), + coverArt: z.string(), + created: z.string(), + duration: z.number(), + genre: z.string().optional(), + id: z.string(), + isDir: z.boolean(), + isVideo: z.boolean(), + name: z.string(), + parent: z.string(), + song: z.array(song), + songCount: z.number(), + starred: z.boolean().optional(), + title: z.string(), + userRating: z.number().optional(), + year: z.number().optional(), }); const albumListParameters = z.object({ - fromYear: z.number().optional(), - genre: z.string().optional(), - musicFolderId: z.string().optional(), - offset: z.number().optional(), - size: z.number().optional(), - toYear: z.number().optional(), - type: z.string().optional(), + fromYear: z.number().optional(), + genre: z.string().optional(), + musicFolderId: z.string().optional(), + offset: z.number().optional(), + size: z.number().optional(), + toYear: z.number().optional(), + type: z.string().optional(), }); const albumList = z.array(album.omit({ song: true })); const albumArtist = z.object({ - albumCount: z.string(), - artistImageUrl: z.string().optional(), - coverArt: z.string().optional(), - id: z.string(), - name: z.string(), + albumCount: z.string(), + artistImageUrl: z.string().optional(), + coverArt: z.string().optional(), + id: z.string(), + name: z.string(), }); const albumArtistList = z.object({ - artist: z.array(albumArtist), - name: z.string(), + artist: z.array(albumArtist), + name: z.string(), }); const artistInfoParameters = z.object({ - count: z.number().optional(), - id: z.string(), - includeNotPresent: z.boolean().optional(), + count: z.number().optional(), + id: z.string(), + includeNotPresent: z.boolean().optional(), }); const artistInfo = z.object({ - artistInfo: z.object({ - biography: z.string().optional(), - largeImageUrl: z.string().optional(), - lastFmUrl: z.string().optional(), - mediumImageUrl: z.string().optional(), - musicBrainzId: z.string().optional(), - similarArtist: z.array( - z.object({ - albumCount: z.string(), - artistImageUrl: z.string().optional(), - coverArt: z.string().optional(), - id: z.string(), - name: z.string(), - }), - ), - smallImageUrl: z.string().optional(), - }), + artistInfo: z.object({ + biography: z.string().optional(), + largeImageUrl: z.string().optional(), + lastFmUrl: z.string().optional(), + mediumImageUrl: z.string().optional(), + musicBrainzId: z.string().optional(), + similarArtist: z.array( + z.object({ + albumCount: z.string(), + artistImageUrl: z.string().optional(), + coverArt: z.string().optional(), + id: z.string(), + name: z.string(), + }), + ), + smallImageUrl: z.string().optional(), + }), }); const topSongsListParameters = z.object({ - artist: z.string(), // The name of the artist, not the artist ID - count: z.number().optional(), + artist: z.string(), // The name of the artist, not the artist ID + count: z.number().optional(), }); const topSongsList = z.object({ - topSongs: z.object({ - song: z.array(song), - }), + topSongs: z.object({ + song: z.array(song), + }), }); const scrobbleParameters = z.object({ - id: z.string(), - submission: z.boolean().optional(), - time: z.number().optional(), // The time (in milliseconds since 1 Jan 1970) at which the song was listened to. + id: z.string(), + submission: z.boolean().optional(), + time: z.number().optional(), // The time (in milliseconds since 1 Jan 1970) at which the song was listened to. }); const scrobble = z.null(); const search3 = z.object({ - searchResult3: z.object({ - album: z.array(album), - artist: z.array(albumArtist), - song: z.array(song), - }), + searchResult3: z.object({ + album: z.array(album), + artist: z.array(albumArtist), + song: z.array(song), + }), }); const search3Parameters = z.object({ - albumCount: z.number().optional(), - albumOffset: z.number().optional(), - artistCount: z.number().optional(), - artistOffset: z.number().optional(), - musicFolderId: z.string().optional(), - query: z.string().optional(), - songCount: z.number().optional(), - songOffset: z.number().optional(), + albumCount: z.number().optional(), + albumOffset: z.number().optional(), + artistCount: z.number().optional(), + artistOffset: z.number().optional(), + musicFolderId: z.string().optional(), + query: z.string().optional(), + songCount: z.number().optional(), + songOffset: z.number().optional(), }); const randomSongListParameters = z.object({ - fromYear: z.number().optional(), - genre: z.string().optional(), - musicFolderId: z.string().optional(), - size: z.number().optional(), - toYear: z.number().optional(), + fromYear: z.number().optional(), + genre: z.string().optional(), + musicFolderId: z.string().optional(), + size: z.number().optional(), + toYear: z.number().optional(), }); const randomSongList = z.object({ - randomSongs: z.object({ - song: z.array(song), - }), + randomSongs: z.object({ + song: z.array(song), + }), }); export const ssType = { - _parameters: { - albumList: albumListParameters, - artistInfo: artistInfoParameters, - authenticate: authenticateParameters, - createFavorite: createFavoriteParameters, - randomSongList: randomSongListParameters, - removeFavorite: removeFavoriteParameters, - scrobble: scrobbleParameters, - search3: search3Parameters, - setRating: setRatingParameters, - topSongsList: topSongsListParameters, - }, - _response: { - album, - albumArtist, - albumArtistList, - albumList, - artistInfo, - authenticate, - baseResponse, - createFavorite, - musicFolderList, - randomSongList, - removeFavorite, - scrobble, - search3, - setRating, - song, - topSongsList, - }, + _parameters: { + albumList: albumListParameters, + artistInfo: artistInfoParameters, + authenticate: authenticateParameters, + createFavorite: createFavoriteParameters, + randomSongList: randomSongListParameters, + removeFavorite: removeFavoriteParameters, + scrobble: scrobbleParameters, + search3: search3Parameters, + setRating: setRatingParameters, + topSongsList: topSongsListParameters, + }, + _response: { + album, + albumArtist, + albumArtistList, + albumList, + artistInfo, + authenticate, + baseResponse, + createFavorite, + musicFolderList, + randomSongList, + removeFavorite, + scrobble, + search3, + setRating, + song, + topSongsList, + }, }; diff --git a/src/renderer/api/types.ts b/src/renderer/api/types.ts index 06b7c353..95a4b675 100644 --- a/src/renderer/api/types.ts +++ b/src/renderer/api/types.ts @@ -1,277 +1,277 @@ import { z } from 'zod'; import { - JFSortOrder, - JFAlbumListSort, - JFSongListSort, - JFAlbumArtistListSort, - JFArtistListSort, - JFPlaylistListSort, + JFSortOrder, + JFAlbumListSort, + JFSongListSort, + JFAlbumArtistListSort, + JFArtistListSort, + JFPlaylistListSort, } from './jellyfin.types'; import { jfType } from './jellyfin/jellyfin-types'; import { - NDSortOrder, - NDOrder, - NDAlbumListSort, - NDAlbumArtistListSort, - NDPlaylistListSort, - NDSongListSort, - NDUserListSort, + NDSortOrder, + NDOrder, + NDAlbumListSort, + NDAlbumArtistListSort, + NDPlaylistListSort, + NDSongListSort, + NDUserListSort, } from './navidrome.types'; import { ndType } from './navidrome/navidrome-types'; export enum LibraryItem { - ALBUM = 'album', - ALBUM_ARTIST = 'albumArtist', - ARTIST = 'artist', - PLAYLIST = 'playlist', - SONG = 'song', + ALBUM = 'album', + ALBUM_ARTIST = 'albumArtist', + ARTIST = 'artist', + PLAYLIST = 'playlist', + SONG = 'song', } export type AnyLibraryItem = Album | AlbumArtist | Artist | Playlist | Song | QueueSong; export type AnyLibraryItems = - | Album[] - | AlbumArtist[] - | Artist[] - | Playlist[] - | Song[] - | QueueSong[]; + | Album[] + | AlbumArtist[] + | Artist[] + | Playlist[] + | Song[] + | QueueSong[]; export enum SortOrder { - ASC = 'ASC', - DESC = 'DESC', + ASC = 'ASC', + DESC = 'DESC', } export type User = { - createdAt: string | null; - email: string | null; - id: string; - isAdmin: boolean | null; - lastLoginAt: string | null; - name: string; - updatedAt: string | null; + createdAt: string | null; + email: string | null; + id: string; + isAdmin: boolean | null; + lastLoginAt: string | null; + name: string; + updatedAt: string | null; }; export type ServerListItem = { - credential: string; - id: string; - name: string; - ndCredential?: string; - type: ServerType; - url: string; - userId: string | null; - username: string; + credential: string; + id: string; + name: string; + ndCredential?: string; + type: ServerType; + url: string; + userId: string | null; + username: string; }; export enum ServerType { - JELLYFIN = 'jellyfin', - NAVIDROME = 'navidrome', - SUBSONIC = 'subsonic', + JELLYFIN = 'jellyfin', + NAVIDROME = 'navidrome', + SUBSONIC = 'subsonic', } export type QueueSong = Song & { - uniqueId: string; + uniqueId: string; }; type SortOrderMap = { - jellyfin: Record; - navidrome: Record; - subsonic: Record; + jellyfin: Record; + navidrome: Record; + subsonic: Record; }; export const sortOrderMap: SortOrderMap = { - jellyfin: { - ASC: JFSortOrder.ASC, - DESC: JFSortOrder.DESC, - }, - navidrome: { - ASC: NDSortOrder.ASC, - DESC: NDSortOrder.DESC, - }, - subsonic: { - ASC: undefined, - DESC: undefined, - }, + jellyfin: { + ASC: JFSortOrder.ASC, + DESC: JFSortOrder.DESC, + }, + navidrome: { + ASC: NDSortOrder.ASC, + DESC: NDSortOrder.DESC, + }, + subsonic: { + ASC: undefined, + DESC: undefined, + }, }; export enum ExternalSource { - LASTFM = 'LASTFM', - MUSICBRAINZ = 'MUSICBRAINZ', - SPOTIFY = 'SPOTIFY', - THEAUDIODB = 'THEAUDIODB', + LASTFM = 'LASTFM', + MUSICBRAINZ = 'MUSICBRAINZ', + SPOTIFY = 'SPOTIFY', + THEAUDIODB = 'THEAUDIODB', } export enum ExternalType { - ID = 'ID', - LINK = 'LINK', + ID = 'ID', + LINK = 'LINK', } export enum ImageType { - BACKDROP = 'BACKDROP', - LOGO = 'LOGO', - PRIMARY = 'PRIMARY', - SCREENSHOT = 'SCREENSHOT', + BACKDROP = 'BACKDROP', + LOGO = 'LOGO', + PRIMARY = 'PRIMARY', + SCREENSHOT = 'SCREENSHOT', } export type EndpointDetails = { - server: ServerListItem; + server: ServerListItem; }; export interface BasePaginatedResponse { - error?: string | any; - items: T; - startIndex: number; - totalRecordCount: number; + error?: string | any; + items: T; + startIndex: number; + totalRecordCount: number; } export type AuthenticationResponse = { - credential: string; - ndCredential?: string; - userId: string | null; - username: string; + credential: string; + ndCredential?: string; + userId: string | null; + username: string; }; export type Genre = { - albumCount?: number; - id: string; - name: string; - songCount?: number; + albumCount?: number; + id: string; + name: string; + songCount?: number; }; export type Album = { - albumArtists: RelatedArtist[]; - artists: RelatedArtist[]; - backdropImageUrl: string | null; - createdAt: string; - duration: number | null; - genres: Genre[]; - id: string; - imagePlaceholderUrl: string | null; - imageUrl: string | null; - isCompilation: boolean | null; - itemType: LibraryItem.ALBUM; - lastPlayedAt: string | null; - name: string; - playCount: number | null; - releaseDate: string | null; - releaseYear: number | null; - serverId: string; - serverType: ServerType; - size: number | null; - songCount: number | null; - songs?: Song[]; - uniqueId: string; - updatedAt: string; - userFavorite: boolean; - userRating: number | null; + albumArtists: RelatedArtist[]; + artists: RelatedArtist[]; + backdropImageUrl: string | null; + createdAt: string; + duration: number | null; + genres: Genre[]; + id: string; + imagePlaceholderUrl: string | null; + imageUrl: string | null; + isCompilation: boolean | null; + itemType: LibraryItem.ALBUM; + lastPlayedAt: string | null; + name: string; + playCount: number | null; + releaseDate: string | null; + releaseYear: number | null; + serverId: string; + serverType: ServerType; + size: number | null; + songCount: number | null; + songs?: Song[]; + uniqueId: string; + updatedAt: string; + userFavorite: boolean; + userRating: number | null; } & { songs?: Song[] }; export type Song = { - album: string | null; - albumArtists: RelatedArtist[]; - albumId: string; - artistName: string; - artists: RelatedArtist[]; - bitRate: number; - bpm: number | null; - channels: number | null; - comment: string | null; - compilation: boolean | null; - container: string | null; - createdAt: string; - discNumber: number; - duration: number; - genres: Genre[]; - id: string; - imagePlaceholderUrl: string | null; - imageUrl: string | null; - itemType: LibraryItem.SONG; - lastPlayedAt: string | null; - lyrics: string | null; - name: string; - path: string | null; - playCount: number; - playlistItemId?: string; - releaseDate: string | null; - releaseYear: string | null; - serverId: string; - serverType: ServerType; - size: number; - streamUrl: string; - trackNumber: number; - uniqueId: string; - updatedAt: string; - userFavorite: boolean; - userRating: number | null; + album: string | null; + albumArtists: RelatedArtist[]; + albumId: string; + artistName: string; + artists: RelatedArtist[]; + bitRate: number; + bpm: number | null; + channels: number | null; + comment: string | null; + compilation: boolean | null; + container: string | null; + createdAt: string; + discNumber: number; + duration: number; + genres: Genre[]; + id: string; + imagePlaceholderUrl: string | null; + imageUrl: string | null; + itemType: LibraryItem.SONG; + lastPlayedAt: string | null; + lyrics: string | null; + name: string; + path: string | null; + playCount: number; + playlistItemId?: string; + releaseDate: string | null; + releaseYear: string | null; + serverId: string; + serverType: ServerType; + size: number; + streamUrl: string; + trackNumber: number; + uniqueId: string; + updatedAt: string; + userFavorite: boolean; + userRating: number | null; }; export type AlbumArtist = { - albumCount: number | null; - backgroundImageUrl: string | null; - biography: string | null; - duration: number | null; - genres: Genre[]; - id: string; - imageUrl: string | null; - itemType: LibraryItem.ALBUM_ARTIST; - lastPlayedAt: string | null; - name: string; - playCount: number | null; - serverId: string; - serverType: ServerType; - similarArtists: RelatedArtist[] | null; - songCount: number | null; - userFavorite: boolean; - userRating: number | null; + albumCount: number | null; + backgroundImageUrl: string | null; + biography: string | null; + duration: number | null; + genres: Genre[]; + id: string; + imageUrl: string | null; + itemType: LibraryItem.ALBUM_ARTIST; + lastPlayedAt: string | null; + name: string; + playCount: number | null; + serverId: string; + serverType: ServerType; + similarArtists: RelatedArtist[] | null; + songCount: number | null; + userFavorite: boolean; + userRating: number | null; }; export type RelatedAlbumArtist = { - id: string; - name: string; + id: string; + name: string; }; export type Artist = { - biography: string | null; - createdAt: string; - id: string; - itemType: LibraryItem.ARTIST; - name: string; - remoteCreatedAt: string | null; - serverFolderId: string; - serverId: string; - serverType: ServerType; - updatedAt: string; + biography: string | null; + createdAt: string; + id: string; + itemType: LibraryItem.ARTIST; + name: string; + remoteCreatedAt: string | null; + serverFolderId: string; + serverId: string; + serverType: ServerType; + updatedAt: string; }; export type RelatedArtist = { - id: string; - imageUrl: string | null; - name: string; + id: string; + imageUrl: string | null; + name: string; }; export type MusicFolder = { - id: string; - name: string; + id: string; + name: string; }; export type Playlist = { - description: string | null; - duration: number | null; - genres: Genre[]; - id: string; - imagePlaceholderUrl: string | null; - imageUrl: string | null; - itemType: LibraryItem.PLAYLIST; - name: string; - owner: string | null; - ownerId: string | null; - public: boolean | null; - rules?: Record | null; - serverId: string; - serverType: ServerType; - size: number | null; - songCount: number | null; - sync?: boolean | null; + description: string | null; + duration: number | null; + genres: Genre[]; + id: string; + imagePlaceholderUrl: string | null; + imageUrl: string | null; + itemType: LibraryItem.PLAYLIST; + name: string; + owner: string | null; + ownerId: string | null; + public: boolean | null; + rules?: Record | null; + serverId: string; + serverType: ServerType; + size: number | null; + songCount: number | null; + sync?: boolean | null; }; export type GenresResponse = Genre[]; @@ -281,10 +281,10 @@ export type MusicFoldersResponse = MusicFolder[]; export type ListSortOrder = NDOrder | JFSortOrder; type BaseEndpointArgs = { - apiClientProps: { - server: ServerListItem | null; - signal?: AbortSignal; - }; + apiClientProps: { + server: ServerListItem | null; + signal?: AbortSignal; + }; }; // Genre List @@ -298,100 +298,100 @@ export type GenreListQuery = null; export type AlbumListResponse = BasePaginatedResponse | null | undefined; export enum AlbumListSort { - ALBUM_ARTIST = 'albumArtist', - ARTIST = 'artist', - COMMUNITY_RATING = 'communityRating', - CRITIC_RATING = 'criticRating', - DURATION = 'duration', - FAVORITED = 'favorited', - NAME = 'name', - PLAY_COUNT = 'playCount', - RANDOM = 'random', - RATING = 'rating', - RECENTLY_ADDED = 'recentlyAdded', - RECENTLY_PLAYED = 'recentlyPlayed', - RELEASE_DATE = 'releaseDate', - SONG_COUNT = 'songCount', - YEAR = 'year', + ALBUM_ARTIST = 'albumArtist', + ARTIST = 'artist', + COMMUNITY_RATING = 'communityRating', + CRITIC_RATING = 'criticRating', + DURATION = 'duration', + FAVORITED = 'favorited', + NAME = 'name', + PLAY_COUNT = 'playCount', + RANDOM = 'random', + RATING = 'rating', + RECENTLY_ADDED = 'recentlyAdded', + RECENTLY_PLAYED = 'recentlyPlayed', + RELEASE_DATE = 'releaseDate', + SONG_COUNT = 'songCount', + YEAR = 'year', } export type AlbumListQuery = { - _custom?: { - jellyfin?: Partial> & { - maxYear?: number; - minYear?: number; + _custom?: { + jellyfin?: Partial> & { + maxYear?: number; + minYear?: number; + }; + navidrome?: Partial>; }; - navidrome?: Partial>; - }; - artistIds?: string[]; - limit?: number; - musicFolderId?: string; - searchTerm?: string; - sortBy: AlbumListSort; - sortOrder: SortOrder; - startIndex: number; + artistIds?: string[]; + limit?: number; + musicFolderId?: string; + searchTerm?: string; + sortBy: AlbumListSort; + sortOrder: SortOrder; + startIndex: number; }; export type AlbumListArgs = { query: AlbumListQuery } & BaseEndpointArgs; type AlbumListSortMap = { - jellyfin: Record; - navidrome: Record; - subsonic: Record; + jellyfin: Record; + navidrome: Record; + subsonic: Record; }; export const albumListSortMap: AlbumListSortMap = { - jellyfin: { - albumArtist: JFAlbumListSort.ALBUM_ARTIST, - artist: undefined, - communityRating: JFAlbumListSort.COMMUNITY_RATING, - criticRating: JFAlbumListSort.CRITIC_RATING, - duration: undefined, - favorited: undefined, - name: JFAlbumListSort.NAME, - playCount: undefined, - random: JFAlbumListSort.RANDOM, - rating: undefined, - recentlyAdded: JFAlbumListSort.RECENTLY_ADDED, - recentlyPlayed: undefined, - releaseDate: JFAlbumListSort.RELEASE_DATE, - songCount: undefined, - year: undefined, - }, - navidrome: { - albumArtist: NDAlbumListSort.ALBUM_ARTIST, - artist: NDAlbumListSort.ARTIST, - communityRating: undefined, - criticRating: undefined, - duration: NDAlbumListSort.DURATION, - favorited: NDAlbumListSort.STARRED, - name: NDAlbumListSort.NAME, - playCount: NDAlbumListSort.PLAY_COUNT, - random: NDAlbumListSort.RANDOM, - rating: NDAlbumListSort.RATING, - recentlyAdded: NDAlbumListSort.RECENTLY_ADDED, - recentlyPlayed: NDAlbumListSort.PLAY_DATE, - releaseDate: undefined, - songCount: NDAlbumListSort.SONG_COUNT, - year: NDAlbumListSort.YEAR, - }, - subsonic: { - albumArtist: undefined, - artist: undefined, - communityRating: undefined, - criticRating: undefined, - duration: undefined, - favorited: undefined, - name: undefined, - playCount: undefined, - random: undefined, - rating: undefined, - recentlyAdded: undefined, - recentlyPlayed: undefined, - releaseDate: undefined, - songCount: undefined, - year: undefined, - }, + jellyfin: { + albumArtist: JFAlbumListSort.ALBUM_ARTIST, + artist: undefined, + communityRating: JFAlbumListSort.COMMUNITY_RATING, + criticRating: JFAlbumListSort.CRITIC_RATING, + duration: undefined, + favorited: undefined, + name: JFAlbumListSort.NAME, + playCount: undefined, + random: JFAlbumListSort.RANDOM, + rating: undefined, + recentlyAdded: JFAlbumListSort.RECENTLY_ADDED, + recentlyPlayed: undefined, + releaseDate: JFAlbumListSort.RELEASE_DATE, + songCount: undefined, + year: undefined, + }, + navidrome: { + albumArtist: NDAlbumListSort.ALBUM_ARTIST, + artist: NDAlbumListSort.ARTIST, + communityRating: undefined, + criticRating: undefined, + duration: NDAlbumListSort.DURATION, + favorited: NDAlbumListSort.STARRED, + name: NDAlbumListSort.NAME, + playCount: NDAlbumListSort.PLAY_COUNT, + random: NDAlbumListSort.RANDOM, + rating: NDAlbumListSort.RATING, + recentlyAdded: NDAlbumListSort.RECENTLY_ADDED, + recentlyPlayed: NDAlbumListSort.PLAY_DATE, + releaseDate: undefined, + songCount: NDAlbumListSort.SONG_COUNT, + year: NDAlbumListSort.YEAR, + }, + subsonic: { + albumArtist: undefined, + artist: undefined, + communityRating: undefined, + criticRating: undefined, + duration: undefined, + favorited: undefined, + name: undefined, + playCount: undefined, + random: undefined, + rating: undefined, + recentlyAdded: undefined, + recentlyPlayed: undefined, + releaseDate: undefined, + songCount: undefined, + year: undefined, + }, }; // Album Detail @@ -405,113 +405,113 @@ export type AlbumDetailArgs = { query: AlbumDetailQuery } & BaseEndpointArgs; export type SongListResponse = BasePaginatedResponse; export enum SongListSort { - ALBUM = 'album', - ALBUM_ARTIST = 'albumArtist', - ARTIST = 'artist', - BPM = 'bpm', - CHANNELS = 'channels', - COMMENT = 'comment', - DURATION = 'duration', - FAVORITED = 'favorited', - GENRE = 'genre', - ID = 'id', - NAME = 'name', - PLAY_COUNT = 'playCount', - RANDOM = 'random', - RATING = 'rating', - RECENTLY_ADDED = 'recentlyAdded', - RECENTLY_PLAYED = 'recentlyPlayed', - RELEASE_DATE = 'releaseDate', - YEAR = 'year', + ALBUM = 'album', + ALBUM_ARTIST = 'albumArtist', + ARTIST = 'artist', + BPM = 'bpm', + CHANNELS = 'channels', + COMMENT = 'comment', + DURATION = 'duration', + FAVORITED = 'favorited', + GENRE = 'genre', + ID = 'id', + NAME = 'name', + PLAY_COUNT = 'playCount', + RANDOM = 'random', + RATING = 'rating', + RECENTLY_ADDED = 'recentlyAdded', + RECENTLY_PLAYED = 'recentlyPlayed', + RELEASE_DATE = 'releaseDate', + YEAR = 'year', } export type SongListQuery = { - _custom?: { - jellyfin?: Partial> & { - maxYear?: number; - minYear?: number; + _custom?: { + jellyfin?: Partial> & { + maxYear?: number; + minYear?: number; + }; + navidrome?: Partial>; }; - navidrome?: Partial>; - }; - albumIds?: string[]; - artistIds?: string[]; - limit?: number; - musicFolderId?: string; - searchTerm?: string; - sortBy: SongListSort; - sortOrder: SortOrder; - startIndex: number; + albumIds?: string[]; + artistIds?: string[]; + limit?: number; + musicFolderId?: string; + searchTerm?: string; + sortBy: SongListSort; + sortOrder: SortOrder; + startIndex: number; }; export type SongListArgs = { query: SongListQuery } & BaseEndpointArgs; type SongListSortMap = { - jellyfin: Record; - navidrome: Record; - subsonic: Record; + jellyfin: Record; + navidrome: Record; + subsonic: Record; }; export const songListSortMap: SongListSortMap = { - jellyfin: { - album: JFSongListSort.ALBUM, - albumArtist: JFSongListSort.ALBUM_ARTIST, - artist: JFSongListSort.ARTIST, - bpm: undefined, - channels: undefined, - comment: undefined, - duration: JFSongListSort.DURATION, - favorited: undefined, - genre: undefined, - id: undefined, - name: JFSongListSort.NAME, - playCount: JFSongListSort.PLAY_COUNT, - random: JFSongListSort.RANDOM, - rating: undefined, - recentlyAdded: JFSongListSort.RECENTLY_ADDED, - recentlyPlayed: JFSongListSort.RECENTLY_PLAYED, - releaseDate: JFSongListSort.RELEASE_DATE, - year: undefined, - }, - navidrome: { - album: NDSongListSort.ALBUM_SONGS, - albumArtist: NDSongListSort.ALBUM_ARTIST, - artist: NDSongListSort.ARTIST, - bpm: NDSongListSort.BPM, - channels: NDSongListSort.CHANNELS, - comment: NDSongListSort.COMMENT, - duration: NDSongListSort.DURATION, - favorited: NDSongListSort.FAVORITED, - genre: NDSongListSort.GENRE, - id: NDSongListSort.ID, - name: NDSongListSort.TITLE, - playCount: NDSongListSort.PLAY_COUNT, - random: undefined, - rating: NDSongListSort.RATING, - recentlyAdded: NDSongListSort.RECENTLY_ADDED, - recentlyPlayed: NDSongListSort.PLAY_DATE, - releaseDate: undefined, - year: NDSongListSort.YEAR, - }, - subsonic: { - album: undefined, - albumArtist: undefined, - artist: undefined, - bpm: undefined, - channels: undefined, - comment: undefined, - duration: undefined, - favorited: undefined, - genre: undefined, - id: undefined, - name: undefined, - playCount: undefined, - random: undefined, - rating: undefined, - recentlyAdded: undefined, - recentlyPlayed: undefined, - releaseDate: undefined, - year: undefined, - }, + jellyfin: { + album: JFSongListSort.ALBUM, + albumArtist: JFSongListSort.ALBUM_ARTIST, + artist: JFSongListSort.ARTIST, + bpm: undefined, + channels: undefined, + comment: undefined, + duration: JFSongListSort.DURATION, + favorited: undefined, + genre: undefined, + id: undefined, + name: JFSongListSort.NAME, + playCount: JFSongListSort.PLAY_COUNT, + random: JFSongListSort.RANDOM, + rating: undefined, + recentlyAdded: JFSongListSort.RECENTLY_ADDED, + recentlyPlayed: JFSongListSort.RECENTLY_PLAYED, + releaseDate: JFSongListSort.RELEASE_DATE, + year: undefined, + }, + navidrome: { + album: NDSongListSort.ALBUM_SONGS, + albumArtist: NDSongListSort.ALBUM_ARTIST, + artist: NDSongListSort.ARTIST, + bpm: NDSongListSort.BPM, + channels: NDSongListSort.CHANNELS, + comment: NDSongListSort.COMMENT, + duration: NDSongListSort.DURATION, + favorited: NDSongListSort.FAVORITED, + genre: NDSongListSort.GENRE, + id: NDSongListSort.ID, + name: NDSongListSort.TITLE, + playCount: NDSongListSort.PLAY_COUNT, + random: undefined, + rating: NDSongListSort.RATING, + recentlyAdded: NDSongListSort.RECENTLY_ADDED, + recentlyPlayed: NDSongListSort.PLAY_DATE, + releaseDate: undefined, + year: NDSongListSort.YEAR, + }, + subsonic: { + album: undefined, + albumArtist: undefined, + artist: undefined, + bpm: undefined, + channels: undefined, + comment: undefined, + duration: undefined, + favorited: undefined, + genre: undefined, + id: undefined, + name: undefined, + playCount: undefined, + random: undefined, + rating: undefined, + recentlyAdded: undefined, + recentlyPlayed: undefined, + releaseDate: undefined, + year: undefined, + }, }; // Song Detail @@ -525,80 +525,80 @@ export type SongDetailArgs = { query: SongDetailQuery } & BaseEndpointArgs; export type AlbumArtistListResponse = BasePaginatedResponse | null; export enum AlbumArtistListSort { - ALBUM = 'album', - ALBUM_COUNT = 'albumCount', - DURATION = 'duration', - FAVORITED = 'favorited', - NAME = 'name', - PLAY_COUNT = 'playCount', - RANDOM = 'random', - RATING = 'rating', - RECENTLY_ADDED = 'recentlyAdded', - RELEASE_DATE = 'releaseDate', - SONG_COUNT = 'songCount', + ALBUM = 'album', + ALBUM_COUNT = 'albumCount', + DURATION = 'duration', + FAVORITED = 'favorited', + NAME = 'name', + PLAY_COUNT = 'playCount', + RANDOM = 'random', + RATING = 'rating', + RECENTLY_ADDED = 'recentlyAdded', + RELEASE_DATE = 'releaseDate', + SONG_COUNT = 'songCount', } export type AlbumArtistListQuery = { - _custom?: { - jellyfin?: Partial>; - navidrome?: Partial>; - }; - limit?: number; - musicFolderId?: string; - searchTerm?: string; - sortBy: AlbumArtistListSort; - sortOrder: SortOrder; - startIndex: number; + _custom?: { + jellyfin?: Partial>; + navidrome?: Partial>; + }; + limit?: number; + musicFolderId?: string; + searchTerm?: string; + sortBy: AlbumArtistListSort; + sortOrder: SortOrder; + startIndex: number; }; export type AlbumArtistListArgs = { query: AlbumArtistListQuery } & BaseEndpointArgs; type AlbumArtistListSortMap = { - jellyfin: Record; - navidrome: Record; - subsonic: Record; + jellyfin: Record; + navidrome: Record; + subsonic: Record; }; export const albumArtistListSortMap: AlbumArtistListSortMap = { - jellyfin: { - album: JFAlbumArtistListSort.ALBUM, - albumCount: undefined, - duration: JFAlbumArtistListSort.DURATION, - favorited: undefined, - name: JFAlbumArtistListSort.NAME, - playCount: undefined, - random: JFAlbumArtistListSort.RANDOM, - rating: undefined, - recentlyAdded: JFAlbumArtistListSort.RECENTLY_ADDED, - releaseDate: undefined, - songCount: undefined, - }, - navidrome: { - album: undefined, - albumCount: NDAlbumArtistListSort.ALBUM_COUNT, - duration: undefined, - favorited: NDAlbumArtistListSort.FAVORITED, - name: NDAlbumArtistListSort.NAME, - playCount: NDAlbumArtistListSort.PLAY_COUNT, - random: undefined, - rating: NDAlbumArtistListSort.RATING, - recentlyAdded: undefined, - releaseDate: undefined, - songCount: NDAlbumArtistListSort.SONG_COUNT, - }, - subsonic: { - album: undefined, - albumCount: undefined, - duration: undefined, - favorited: undefined, - name: undefined, - playCount: undefined, - random: undefined, - rating: undefined, - recentlyAdded: undefined, - releaseDate: undefined, - songCount: undefined, - }, + jellyfin: { + album: JFAlbumArtistListSort.ALBUM, + albumCount: undefined, + duration: JFAlbumArtistListSort.DURATION, + favorited: undefined, + name: JFAlbumArtistListSort.NAME, + playCount: undefined, + random: JFAlbumArtistListSort.RANDOM, + rating: undefined, + recentlyAdded: JFAlbumArtistListSort.RECENTLY_ADDED, + releaseDate: undefined, + songCount: undefined, + }, + navidrome: { + album: undefined, + albumCount: NDAlbumArtistListSort.ALBUM_COUNT, + duration: undefined, + favorited: NDAlbumArtistListSort.FAVORITED, + name: NDAlbumArtistListSort.NAME, + playCount: NDAlbumArtistListSort.PLAY_COUNT, + random: undefined, + rating: NDAlbumArtistListSort.RATING, + recentlyAdded: undefined, + releaseDate: undefined, + songCount: NDAlbumArtistListSort.SONG_COUNT, + }, + subsonic: { + album: undefined, + albumCount: undefined, + duration: undefined, + favorited: undefined, + name: undefined, + playCount: undefined, + random: undefined, + rating: undefined, + recentlyAdded: undefined, + releaseDate: undefined, + songCount: undefined, + }, }; // Album Artist Detail @@ -613,79 +613,79 @@ export type AlbumArtistDetailArgs = { query: AlbumArtistDetailQuery } & BaseEndp export type ArtistListResponse = BasePaginatedResponse; export enum ArtistListSort { - ALBUM = 'album', - ALBUM_COUNT = 'albumCount', - DURATION = 'duration', - FAVORITED = 'favorited', - NAME = 'name', - PLAY_COUNT = 'playCount', - RANDOM = 'random', - RATING = 'rating', - RECENTLY_ADDED = 'recentlyAdded', - RELEASE_DATE = 'releaseDate', - SONG_COUNT = 'songCount', + ALBUM = 'album', + ALBUM_COUNT = 'albumCount', + DURATION = 'duration', + FAVORITED = 'favorited', + NAME = 'name', + PLAY_COUNT = 'playCount', + RANDOM = 'random', + RATING = 'rating', + RECENTLY_ADDED = 'recentlyAdded', + RELEASE_DATE = 'releaseDate', + SONG_COUNT = 'songCount', } export type ArtistListQuery = { - _custom?: { - jellyfin?: Partial>; - navidrome?: Partial>; - }; - limit?: number; - musicFolderId?: string; - sortBy: ArtistListSort; - sortOrder: SortOrder; - startIndex: number; + _custom?: { + jellyfin?: Partial>; + navidrome?: Partial>; + }; + limit?: number; + musicFolderId?: string; + sortBy: ArtistListSort; + sortOrder: SortOrder; + startIndex: number; }; export type ArtistListArgs = { query: ArtistListQuery } & BaseEndpointArgs; type ArtistListSortMap = { - jellyfin: Record; - navidrome: Record; - subsonic: Record; + jellyfin: Record; + navidrome: Record; + subsonic: Record; }; export const artistListSortMap: ArtistListSortMap = { - jellyfin: { - album: JFArtistListSort.ALBUM, - albumCount: undefined, - duration: JFArtistListSort.DURATION, - favorited: undefined, - name: JFArtistListSort.NAME, - playCount: undefined, - random: JFArtistListSort.RANDOM, - rating: undefined, - recentlyAdded: JFArtistListSort.RECENTLY_ADDED, - releaseDate: undefined, - songCount: undefined, - }, - navidrome: { - album: undefined, - albumCount: undefined, - duration: undefined, - favorited: undefined, - name: undefined, - playCount: undefined, - random: undefined, - rating: undefined, - recentlyAdded: undefined, - releaseDate: undefined, - songCount: undefined, - }, - subsonic: { - album: undefined, - albumCount: undefined, - duration: undefined, - favorited: undefined, - name: undefined, - playCount: undefined, - random: undefined, - rating: undefined, - recentlyAdded: undefined, - releaseDate: undefined, - songCount: undefined, - }, + jellyfin: { + album: JFArtistListSort.ALBUM, + albumCount: undefined, + duration: JFArtistListSort.DURATION, + favorited: undefined, + name: JFArtistListSort.NAME, + playCount: undefined, + random: JFArtistListSort.RANDOM, + rating: undefined, + recentlyAdded: JFArtistListSort.RECENTLY_ADDED, + releaseDate: undefined, + songCount: undefined, + }, + navidrome: { + album: undefined, + albumCount: undefined, + duration: undefined, + favorited: undefined, + name: undefined, + playCount: undefined, + random: undefined, + rating: undefined, + recentlyAdded: undefined, + releaseDate: undefined, + songCount: undefined, + }, + subsonic: { + album: undefined, + albumCount: undefined, + duration: undefined, + favorited: undefined, + name: undefined, + playCount: undefined, + random: undefined, + rating: undefined, + recentlyAdded: undefined, + releaseDate: undefined, + songCount: undefined, + }, }; // Artist Detail @@ -694,8 +694,8 @@ export const artistListSortMap: ArtistListSortMap = { export type FavoriteResponse = null | undefined; export type FavoriteQuery = { - id: string[]; - type: LibraryItem; + id: string[]; + type: LibraryItem; }; export type FavoriteArgs = { query: FavoriteQuery; serverId?: string } & BaseEndpointArgs; @@ -704,8 +704,8 @@ export type FavoriteArgs = { query: FavoriteQuery; serverId?: string } & BaseEnd export type RatingResponse = null | undefined; export type RatingQuery = { - item: AnyLibraryItems; - rating: number; + item: AnyLibraryItems; + rating: number; }; export type SetRatingArgs = { query: RatingQuery; serverId?: string } & BaseEndpointArgs; @@ -714,47 +714,47 @@ export type SetRatingArgs = { query: RatingQuery; serverId?: string } & BaseEndp export type AddToPlaylistResponse = null | undefined; export type AddToPlaylistQuery = { - id: string; + id: string; }; export type AddToPlaylistBody = { - songId: string[]; + songId: string[]; }; export type AddToPlaylistArgs = { - body: AddToPlaylistBody; - query: AddToPlaylistQuery; - serverId?: string; + body: AddToPlaylistBody; + query: AddToPlaylistQuery; + serverId?: string; } & BaseEndpointArgs; // Remove from playlist export type RemoveFromPlaylistResponse = null | undefined; export type RemoveFromPlaylistQuery = { - id: string; - songId: string[]; + id: string; + songId: string[]; }; export type RemoveFromPlaylistArgs = { - query: RemoveFromPlaylistQuery; - serverId?: string; + query: RemoveFromPlaylistQuery; + serverId?: string; } & BaseEndpointArgs; // Create Playlist export type CreatePlaylistResponse = { id: string } | undefined; export type CreatePlaylistBody = { - _custom?: { - navidrome?: { - owner?: string; - ownerId?: string; - public?: boolean; - rules?: Record; - sync?: boolean; + _custom?: { + navidrome?: { + owner?: string; + ownerId?: string; + public?: boolean; + rules?: Record; + sync?: boolean; + }; }; - }; - comment?: string; - name: string; + comment?: string; + name: string; }; export type CreatePlaylistArgs = { body: CreatePlaylistBody; serverId?: string } & BaseEndpointArgs; @@ -763,28 +763,28 @@ export type CreatePlaylistArgs = { body: CreatePlaylistBody; serverId?: string } export type UpdatePlaylistResponse = null | undefined; export type UpdatePlaylistQuery = { - id: string; + id: string; }; export type UpdatePlaylistBody = { - _custom?: { - navidrome?: { - owner?: string; - ownerId?: string; - public?: boolean; - rules?: Record; - sync?: boolean; + _custom?: { + navidrome?: { + owner?: string; + ownerId?: string; + public?: boolean; + rules?: Record; + sync?: boolean; + }; }; - }; - comment?: string; - genres?: Genre[]; - name: string; + comment?: string; + genres?: Genre[]; + name: string; }; export type UpdatePlaylistArgs = { - body: UpdatePlaylistBody; - query: UpdatePlaylistQuery; - serverId?: string; + body: UpdatePlaylistBody; + query: UpdatePlaylistQuery; + serverId?: string; } & BaseEndpointArgs; // Delete Playlist @@ -793,74 +793,74 @@ export type DeletePlaylistResponse = null | undefined; export type DeletePlaylistQuery = { id: string }; export type DeletePlaylistArgs = { - query: DeletePlaylistQuery; - serverId?: string; + query: DeletePlaylistQuery; + serverId?: string; } & BaseEndpointArgs; // Playlist List export type PlaylistListResponse = BasePaginatedResponse; export enum PlaylistListSort { - DURATION = 'duration', - NAME = 'name', - OWNER = 'owner', - PUBLIC = 'public', - SONG_COUNT = 'songCount', - UPDATED_AT = 'updatedAt', + DURATION = 'duration', + NAME = 'name', + OWNER = 'owner', + PUBLIC = 'public', + SONG_COUNT = 'songCount', + UPDATED_AT = 'updatedAt', } export type PlaylistListQuery = { - _custom?: { - jellyfin?: Partial>; - navidrome?: Partial>; - }; - limit?: number; - searchTerm?: string; - sortBy: PlaylistListSort; - sortOrder: SortOrder; - startIndex: number; + _custom?: { + jellyfin?: Partial>; + navidrome?: Partial>; + }; + limit?: number; + searchTerm?: string; + sortBy: PlaylistListSort; + sortOrder: SortOrder; + startIndex: number; }; export type PlaylistListArgs = { query: PlaylistListQuery } & BaseEndpointArgs; type PlaylistListSortMap = { - jellyfin: Record; - navidrome: Record; - subsonic: Record; + jellyfin: Record; + navidrome: Record; + subsonic: Record; }; export const playlistListSortMap: PlaylistListSortMap = { - jellyfin: { - duration: JFPlaylistListSort.DURATION, - name: JFPlaylistListSort.NAME, - owner: undefined, - public: undefined, - songCount: JFPlaylistListSort.SONG_COUNT, - updatedAt: undefined, - }, - navidrome: { - duration: NDPlaylistListSort.DURATION, - name: NDPlaylistListSort.NAME, - owner: NDPlaylistListSort.OWNER, - public: NDPlaylistListSort.PUBLIC, - songCount: NDPlaylistListSort.SONG_COUNT, - updatedAt: NDPlaylistListSort.UPDATED_AT, - }, - subsonic: { - duration: undefined, - name: undefined, - owner: undefined, - public: undefined, - songCount: undefined, - updatedAt: undefined, - }, + jellyfin: { + duration: JFPlaylistListSort.DURATION, + name: JFPlaylistListSort.NAME, + owner: undefined, + public: undefined, + songCount: JFPlaylistListSort.SONG_COUNT, + updatedAt: undefined, + }, + navidrome: { + duration: NDPlaylistListSort.DURATION, + name: NDPlaylistListSort.NAME, + owner: NDPlaylistListSort.OWNER, + public: NDPlaylistListSort.PUBLIC, + songCount: NDPlaylistListSort.SONG_COUNT, + updatedAt: NDPlaylistListSort.UPDATED_AT, + }, + subsonic: { + duration: undefined, + name: undefined, + owner: undefined, + public: undefined, + songCount: undefined, + updatedAt: undefined, + }, }; // Playlist Detail export type PlaylistDetailResponse = Playlist; export type PlaylistDetailQuery = { - id: string; + id: string; }; export type PlaylistDetailArgs = { query: PlaylistDetailQuery } & BaseEndpointArgs; @@ -869,11 +869,11 @@ export type PlaylistDetailArgs = { query: PlaylistDetailQuery } & BaseEndpointAr export type PlaylistSongListResponse = BasePaginatedResponse; export type PlaylistSongListQuery = { - id: string; - limit?: number; - sortBy?: SongListSort; - sortOrder?: SortOrder; - startIndex: number; + id: string; + limit?: number; + sortBy?: SongListSort; + sortOrder?: SortOrder; + startIndex: number; }; export type PlaylistSongListArgs = { query: PlaylistSongListQuery } & BaseEndpointArgs; @@ -890,58 +890,58 @@ export type MusicFolderListArgs = BaseEndpointArgs; export type UserListResponse = BasePaginatedResponse; export enum UserListSort { - NAME = 'name', + NAME = 'name', } export type UserListQuery = { - _custom?: { - navidrome?: { - owner_id?: string; + _custom?: { + navidrome?: { + owner_id?: string; + }; }; - }; - limit?: number; - searchTerm?: string; - sortBy: UserListSort; - sortOrder: SortOrder; - startIndex: number; + limit?: number; + searchTerm?: string; + sortBy: UserListSort; + sortOrder: SortOrder; + startIndex: number; }; export type UserListArgs = { query: UserListQuery } & BaseEndpointArgs; type UserListSortMap = { - jellyfin: Record; - navidrome: Record; - subsonic: Record; + jellyfin: Record; + navidrome: Record; + subsonic: Record; }; export const userListSortMap: UserListSortMap = { - jellyfin: { - name: undefined, - }, - navidrome: { - name: NDUserListSort.NAME, - }, - subsonic: { - name: undefined, - }, + jellyfin: { + name: undefined, + }, + navidrome: { + name: NDUserListSort.NAME, + }, + subsonic: { + name: undefined, + }, }; // Top Songs List export type TopSongListResponse = BasePaginatedResponse; export type TopSongListQuery = { - artist: string; - artistId: string; - limit?: number; + artist: string; + artistId: string; + limit?: number; }; export type TopSongListArgs = { query: TopSongListQuery } & BaseEndpointArgs; // Artist Info export type ArtistInfoQuery = { - artistId: string; - limit: number; - musicFolderId?: string; + artistId: string; + limit: number; + musicFolderId?: string; }; export type ArtistInfoArgs = { query: ArtistInfoQuery } & BaseEndpointArgs; @@ -950,79 +950,79 @@ export type ArtistInfoArgs = { query: ArtistInfoQuery } & BaseEndpointArgs; export type ScrobbleResponse = null | undefined; export type ScrobbleArgs = { - query: ScrobbleQuery; - serverId?: string; + query: ScrobbleQuery; + serverId?: string; } & BaseEndpointArgs; export type ScrobbleQuery = { - event?: 'pause' | 'unpause' | 'timeupdate' | 'start'; - id: string; - position?: number; - submission: boolean; + event?: 'pause' | 'unpause' | 'timeupdate' | 'start'; + id: string; + position?: number; + submission: boolean; }; export type SearchQuery = { - albumArtistLimit?: number; - albumArtistStartIndex?: number; - albumLimit?: number; - albumStartIndex?: number; - musicFolderId?: string; - query?: string; - songLimit?: number; - songStartIndex?: number; + albumArtistLimit?: number; + albumArtistStartIndex?: number; + albumLimit?: number; + albumStartIndex?: number; + musicFolderId?: string; + query?: string; + songLimit?: number; + songStartIndex?: number; }; export type SearchSongsQuery = { - musicFolderId?: string; - query?: string; - songLimit?: number; - songStartIndex?: number; + musicFolderId?: string; + query?: string; + songLimit?: number; + songStartIndex?: number; }; export type SearchAlbumsQuery = { - albumLimit?: number; - albumStartIndex?: number; - musicFolderId?: string; - query?: string; + albumLimit?: number; + albumStartIndex?: number; + musicFolderId?: string; + query?: string; }; export type SearchAlbumArtistsQuery = { - albumArtistLimit?: number; - albumArtistStartIndex?: number; - musicFolderId?: string; - query?: string; + albumArtistLimit?: number; + albumArtistStartIndex?: number; + musicFolderId?: string; + query?: string; }; export type SearchArgs = { - query: SearchQuery; + query: SearchQuery; } & BaseEndpointArgs; export type SearchResponse = { - albumArtists: AlbumArtist[]; - albums: Album[]; - songs: Song[]; + albumArtists: AlbumArtist[]; + albums: Album[]; + songs: Song[]; }; export type RandomSongListQuery = { - genre?: string; - limit?: number; - maxYear?: number; - minYear?: number; - musicFolderId?: string; + genre?: string; + limit?: number; + maxYear?: number; + minYear?: number; + musicFolderId?: string; }; export type RandomSongListArgs = { - query: RandomSongListQuery; + query: RandomSongListQuery; } & BaseEndpointArgs; export type RandomSongListResponse = SongListResponse; export type LyricsQuery = { - songId: string; + songId: string; }; export type LyricsArgs = { - query: LyricsQuery; + query: LyricsQuery; } & BaseEndpointArgs; export type SynchronizedLyricsArray = Array<[number, string]>; @@ -1030,29 +1030,29 @@ export type SynchronizedLyricsArray = Array<[number, string]>; export type LyricsResponse = SynchronizedLyricsArray | string; export type InternetProviderLyricResponse = { - artist: string; - id: string; - lyrics: string; - name: string; - source: LyricSource; + artist: string; + id: string; + lyrics: string; + name: string; + source: LyricSource; }; export type InternetProviderLyricSearchResponse = { - artist: string; - id: string; - name: string; - score?: number; - source: LyricSource; + artist: string; + id: string; + name: string; + score?: number; + source: LyricSource; }; export type SynchronizedLyricMetadata = { - lyrics: SynchronizedLyricsArray; - remote: boolean; + lyrics: SynchronizedLyricsArray; + remote: boolean; } & Omit; export type UnsynchronizedLyricMetadata = { - lyrics: string; - remote: boolean; + lyrics: string; + remote: boolean; } & Omit; export type FullLyricsMetadata = SynchronizedLyricMetadata | UnsynchronizedLyricMetadata; @@ -1060,25 +1060,25 @@ export type FullLyricsMetadata = SynchronizedLyricMetadata | UnsynchronizedLyric export type LyricOverride = Omit; export const instanceOfCancellationError = (error: any) => { - return 'revert' in error; + return 'revert' in error; }; export type LyricSearchQuery = { - album?: string; - artist?: string; - duration?: number; - name?: string; + album?: string; + artist?: string; + duration?: number; + name?: string; }; export type LyricGetQuery = { - remoteSongId: string; - remoteSource: LyricSource; + remoteSongId: string; + remoteSource: LyricSource; }; export enum LyricSource { - GENIUS = 'Genius', - LRCLIB = 'lrclib.net', - NETEASE = 'NetEase', + GENIUS = 'Genius', + LRCLIB = 'lrclib.net', + NETEASE = 'NetEase', } export type LyricsOverride = Omit & { id: string }; diff --git a/src/renderer/api/utils.ts b/src/renderer/api/utils.ts index 13871b40..0063fae9 100644 --- a/src/renderer/api/utils.ts +++ b/src/renderer/api/utils.ts @@ -6,35 +6,35 @@ import { ServerListItem } from '/@/renderer/types'; // Since ts-rest client returns a strict response type, we need to add the headers to the body object export const resultWithHeaders = (itemSchema: ItemType) => { - return z.object({ - data: itemSchema, - headers: z.instanceof(AxiosHeaders), - }); + return z.object({ + data: itemSchema, + headers: z.instanceof(AxiosHeaders), + }); }; export const resultSubsonicBaseResponse = ( - itemSchema: ItemType, + itemSchema: ItemType, ) => { - return z.object({ - 'subsonic-response': z - .object({ - status: z.string(), - version: z.string(), - }) - .extend(itemSchema), - }); + return z.object({ + 'subsonic-response': z + .object({ + status: z.string(), + version: z.string(), + }) + .extend(itemSchema), + }); }; export const authenticationFailure = (currentServer: ServerListItem | null) => { - toast.error({ - message: 'Your session has expired.', - }); + toast.error({ + message: 'Your session has expired.', + }); - if (currentServer) { - const serverId = currentServer.id; - const token = currentServer.ndCredential; - console.log(`token is expired: ${token}`); - useAuthStore.getState().actions.updateServer(serverId, { ndCredential: undefined }); - useAuthStore.getState().actions.setCurrentServer(null); - } + if (currentServer) { + const serverId = currentServer.id; + const token = currentServer.ndCredential; + console.log(`token is expired: ${token}`); + useAuthStore.getState().actions.updateServer(serverId, { ndCredential: undefined }); + useAuthStore.getState().actions.setCurrentServer(null); + } }; diff --git a/src/renderer/app.tsx b/src/renderer/app.tsx index a8d30b16..2b21d418 100644 --- a/src/renderer/app.tsx +++ b/src/renderer/app.tsx @@ -29,161 +29,161 @@ const mpvPlayerListener = isElectron() ? window.electron.mpvPlayerListener : nul const ipc = isElectron() ? window.electron.ipc : null; export const App = () => { - const theme = useTheme(); - const contentFont = useSettingsStore((state) => state.general.fontContent); - const { type: playbackType } = usePlaybackSettings(); - const { bindings } = useHotkeySettings(); - const handlePlayQueueAdd = useHandlePlayQueueAdd(); - const { clearQueue, restoreQueue } = useQueueControls(); + const theme = useTheme(); + const contentFont = useSettingsStore((state) => state.general.fontContent); + const { type: playbackType } = usePlaybackSettings(); + const { bindings } = useHotkeySettings(); + const handlePlayQueueAdd = useHandlePlayQueueAdd(); + const { clearQueue, restoreQueue } = useQueueControls(); - useEffect(() => { - const root = document.documentElement; - root.style.setProperty('--content-font-family', contentFont); - }, [contentFont]); + useEffect(() => { + const root = document.documentElement; + root.style.setProperty('--content-font-family', contentFont); + }, [contentFont]); - // Start the mpv instance on startup - useEffect(() => { - const initializeMpv = async () => { - const isRunning: boolean | undefined = await mpvPlayer?.isRunning(); + // Start the mpv instance on startup + useEffect(() => { + const initializeMpv = async () => { + const isRunning: boolean | undefined = await mpvPlayer?.isRunning(); - if (!isRunning) { - const extraParameters = useSettingsStore.getState().playback.mpvExtraParameters; - const properties = { - ...getMpvProperties(useSettingsStore.getState().playback.mpvProperties), + if (!isRunning) { + const extraParameters = useSettingsStore.getState().playback.mpvExtraParameters; + const properties = { + ...getMpvProperties(useSettingsStore.getState().playback.mpvProperties), + }; + + mpvPlayer?.initialize({ + extraParameters, + properties, + }); + + mpvPlayer?.volume(properties.volume); + } }; - mpvPlayer?.initialize({ - extraParameters, - properties, - }); - - mpvPlayer?.volume(properties.volume); - } - }; - - if (isElectron() && playbackType === PlaybackType.LOCAL) { - initializeMpv(); - } - - return () => { - clearQueue(); - mpvPlayer?.stop(); - mpvPlayer?.cleanup(); - }; - }, [clearQueue, playbackType]); - - useEffect(() => { - if (isElectron()) { - ipc?.send('set-global-shortcuts', bindings); - } - }, [bindings]); - - useEffect(() => { - if (isElectron()) { - mpvPlayer.restoreQueue(); - - mpvPlayerListener.rendererSaveQueue(() => { - const { current, queue } = usePlayerStore.getState(); - const stateToSave: Partial> = { - current: { - ...current, - status: PlayerStatus.PAUSED, - }, - queue, - }; - mpvPlayer.saveQueue(stateToSave); - }); - - mpvPlayerListener.rendererRestoreQueue((_event: any, data: Partial) => { - const playerData = restoreQueue(data); - if (playbackType === PlaybackType.LOCAL) { - mpvPlayer.setQueue(playerData, true); + if (isElectron() && playbackType === PlaybackType.LOCAL) { + initializeMpv(); } - }); - } - return () => { - ipc?.removeAllListeners('renderer-player-restore-queue'); - ipc?.removeAllListeners('renderer-player-save-queue'); - }; - }, [playbackType, restoreQueue]); + return () => { + clearQueue(); + mpvPlayer?.stop(); + mpvPlayer?.cleanup(); + }; + }, [clearQueue, playbackType]); - return ( - ({ - border: '1px solid var(--primary-color)', - }), - resetStyles: () => ({ outline: 'none' }), - styles: () => ({ - outline: '1px solid var(--primary-color)', - outlineOffset: '-1px', - }), - }, - fontFamily: 'var(--content-font-family)', - fontSizes: { - lg: '1.1rem', - md: '1rem', - sm: '0.9rem', - xl: '1.5rem', - xs: '0.8rem', - }, - headings: { - fontFamily: 'var(--content-font-family)', - fontWeight: 700, - }, - other: {}, - spacing: { - lg: '2rem', - md: '1rem', - sm: '0.5rem', - xl: '4rem', - xs: '0rem', - }, - }} - > - - - - - - - - - ); + useEffect(() => { + if (isElectron()) { + ipc?.send('set-global-shortcuts', bindings); + } + }, [bindings]); + + useEffect(() => { + if (isElectron()) { + mpvPlayer.restoreQueue(); + + mpvPlayerListener.rendererSaveQueue(() => { + const { current, queue } = usePlayerStore.getState(); + const stateToSave: Partial> = { + current: { + ...current, + status: PlayerStatus.PAUSED, + }, + queue, + }; + mpvPlayer.saveQueue(stateToSave); + }); + + mpvPlayerListener.rendererRestoreQueue((_event: any, data: Partial) => { + const playerData = restoreQueue(data); + if (playbackType === PlaybackType.LOCAL) { + mpvPlayer.setQueue(playerData, true); + } + }); + } + + return () => { + ipc?.removeAllListeners('renderer-player-restore-queue'); + ipc?.removeAllListeners('renderer-player-save-queue'); + }; + }, [playbackType, restoreQueue]); + + return ( + ({ + border: '1px solid var(--primary-color)', + }), + resetStyles: () => ({ outline: 'none' }), + styles: () => ({ + outline: '1px solid var(--primary-color)', + outlineOffset: '-1px', + }), + }, + fontFamily: 'var(--content-font-family)', + fontSizes: { + lg: '1.1rem', + md: '1rem', + sm: '0.9rem', + xl: '1.5rem', + xs: '0.8rem', + }, + headings: { + fontFamily: 'var(--content-font-family)', + fontWeight: 700, + }, + other: {}, + spacing: { + lg: '2rem', + md: '1rem', + sm: '0.5rem', + xl: '4rem', + xs: '0rem', + }, + }} + > + + + + + + + + + ); }; diff --git a/src/renderer/components/accordion/index.tsx b/src/renderer/components/accordion/index.tsx index acb76b4d..63132d23 100644 --- a/src/renderer/components/accordion/index.tsx +++ b/src/renderer/components/accordion/index.tsx @@ -5,17 +5,17 @@ import styled from 'styled-components'; type AccordionProps = MantineAccordionProps; const StyledAccordion = styled(MantineAccordion)` - & .mantine-Accordion-panel { - background: var(--paper-bg); - } + & .mantine-Accordion-panel { + background: var(--paper-bg); + } - .mantine-Accordion-control { - background: var(--paper-bg); - } + .mantine-Accordion-control { + background: var(--paper-bg); + } `; export const Accordion = ({ children, ...props }: AccordionProps) => { - return {children}; + return {children}; }; Accordion.Control = StyledAccordion.Control; diff --git a/src/renderer/components/audio-player/index.tsx b/src/renderer/components/audio-player/index.tsx index f78a50c2..ee602baa 100644 --- a/src/renderer/components/audio-player/index.tsx +++ b/src/renderer/components/audio-player/index.tsx @@ -4,188 +4,192 @@ import type { ReactPlayerProps } from 'react-player'; import ReactPlayer from 'react-player'; import type { Song } from '/@/renderer/api/types'; import { - crossfadeHandler, - gaplessHandler, + crossfadeHandler, + gaplessHandler, } from '/@/renderer/components/audio-player/utils/list-handlers'; import { useSettingsStore } from '/@/renderer/store/settings.store'; import type { CrossfadeStyle } from '/@/renderer/types'; import { PlaybackStyle, PlayerStatus } from '/@/renderer/types'; interface AudioPlayerProps extends ReactPlayerProps { - crossfadeDuration: number; - crossfadeStyle: CrossfadeStyle; - currentPlayer: 1 | 2; - playbackStyle: PlaybackStyle; - player1: Song; - player2: Song; - status: PlayerStatus; - volume: number; + crossfadeDuration: number; + crossfadeStyle: CrossfadeStyle; + currentPlayer: 1 | 2; + playbackStyle: PlaybackStyle; + player1: Song; + player2: Song; + status: PlayerStatus; + volume: number; } export type AudioPlayerProgress = { - loaded: number; - loadedSeconds: number; - played: number; - playedSeconds: number; + loaded: number; + loadedSeconds: number; + played: number; + playedSeconds: number; }; const getDuration = (ref: any) => { - return ref.current?.player?.player?.player?.duration; + return ref.current?.player?.player?.player?.duration; }; export const AudioPlayer = forwardRef( - ( - { - status, - playbackStyle, - crossfadeStyle, - crossfadeDuration, - currentPlayer, - autoNext, - player1, - player2, - muted, - volume, - }: AudioPlayerProps, - ref: any, - ) => { - const player1Ref = useRef(null); - const player2Ref = useRef(null); - const [isTransitioning, setIsTransitioning] = useState(false); - const audioDeviceId = useSettingsStore((state) => state.playback.audioDeviceId); + ( + { + status, + playbackStyle, + crossfadeStyle, + crossfadeDuration, + currentPlayer, + autoNext, + player1, + player2, + muted, + volume, + }: AudioPlayerProps, + ref: any, + ) => { + const player1Ref = useRef(null); + const player2Ref = useRef(null); + const [isTransitioning, setIsTransitioning] = useState(false); + const audioDeviceId = useSettingsStore((state) => state.playback.audioDeviceId); - useImperativeHandle(ref, () => ({ - get player1() { - return player1Ref?.current; - }, - get player2() { - return player2Ref?.current; - }, - })); + useImperativeHandle(ref, () => ({ + get player1() { + return player1Ref?.current; + }, + get player2() { + return player2Ref?.current; + }, + })); - const handleOnEnded = () => { - autoNext(); - setIsTransitioning(false); - }; + const handleOnEnded = () => { + autoNext(); + setIsTransitioning(false); + }; - useEffect(() => { - if (status === PlayerStatus.PLAYING) { - if (currentPlayer === 1) { - player1Ref.current?.getInternalPlayer()?.play(); - } else { - player2Ref.current?.getInternalPlayer()?.play(); - } - } else { - player1Ref.current?.getInternalPlayer()?.pause(); - player2Ref.current?.getInternalPlayer()?.pause(); - } - }, [currentPlayer, status]); + useEffect(() => { + if (status === PlayerStatus.PLAYING) { + if (currentPlayer === 1) { + player1Ref.current?.getInternalPlayer()?.play(); + } else { + player2Ref.current?.getInternalPlayer()?.play(); + } + } else { + player1Ref.current?.getInternalPlayer()?.pause(); + player2Ref.current?.getInternalPlayer()?.pause(); + } + }, [currentPlayer, status]); - const handleCrossfade1 = useCallback( - (e: AudioPlayerProgress) => { - return crossfadeHandler({ - currentPlayer, - currentPlayerRef: player1Ref, - currentTime: e.playedSeconds, - duration: getDuration(player1Ref), - fadeDuration: crossfadeDuration, - fadeType: crossfadeStyle, - isTransitioning, - nextPlayerRef: player2Ref, - player: 1, - setIsTransitioning, - volume, - }); - }, - [crossfadeDuration, crossfadeStyle, currentPlayer, isTransitioning, volume], - ); + const handleCrossfade1 = useCallback( + (e: AudioPlayerProgress) => { + return crossfadeHandler({ + currentPlayer, + currentPlayerRef: player1Ref, + currentTime: e.playedSeconds, + duration: getDuration(player1Ref), + fadeDuration: crossfadeDuration, + fadeType: crossfadeStyle, + isTransitioning, + nextPlayerRef: player2Ref, + player: 1, + setIsTransitioning, + volume, + }); + }, + [crossfadeDuration, crossfadeStyle, currentPlayer, isTransitioning, volume], + ); - const handleCrossfade2 = useCallback( - (e: AudioPlayerProgress) => { - return crossfadeHandler({ - currentPlayer, - currentPlayerRef: player2Ref, - currentTime: e.playedSeconds, - duration: getDuration(player2Ref), - fadeDuration: crossfadeDuration, - fadeType: crossfadeStyle, - isTransitioning, - nextPlayerRef: player1Ref, - player: 2, - setIsTransitioning, - volume, - }); - }, - [crossfadeDuration, crossfadeStyle, currentPlayer, isTransitioning, volume], - ); + const handleCrossfade2 = useCallback( + (e: AudioPlayerProgress) => { + return crossfadeHandler({ + currentPlayer, + currentPlayerRef: player2Ref, + currentTime: e.playedSeconds, + duration: getDuration(player2Ref), + fadeDuration: crossfadeDuration, + fadeType: crossfadeStyle, + isTransitioning, + nextPlayerRef: player1Ref, + player: 2, + setIsTransitioning, + volume, + }); + }, + [crossfadeDuration, crossfadeStyle, currentPlayer, isTransitioning, volume], + ); - const handleGapless1 = useCallback( - (e: AudioPlayerProgress) => { - return gaplessHandler({ - currentTime: e.playedSeconds, - duration: getDuration(player1Ref), - isFlac: player1?.container === 'flac', - isTransitioning, - nextPlayerRef: player2Ref, - setIsTransitioning, - }); - }, - [isTransitioning, player1?.container], - ); + const handleGapless1 = useCallback( + (e: AudioPlayerProgress) => { + return gaplessHandler({ + currentTime: e.playedSeconds, + duration: getDuration(player1Ref), + isFlac: player1?.container === 'flac', + isTransitioning, + nextPlayerRef: player2Ref, + setIsTransitioning, + }); + }, + [isTransitioning, player1?.container], + ); - const handleGapless2 = useCallback( - (e: AudioPlayerProgress) => { - return gaplessHandler({ - currentTime: e.playedSeconds, - duration: getDuration(player2Ref), - isFlac: player2?.container === 'flac', - isTransitioning, - nextPlayerRef: player1Ref, - setIsTransitioning, - }); - }, - [isTransitioning, player2?.container], - ); + const handleGapless2 = useCallback( + (e: AudioPlayerProgress) => { + return gaplessHandler({ + currentTime: e.playedSeconds, + duration: getDuration(player2Ref), + isFlac: player2?.container === 'flac', + isTransitioning, + nextPlayerRef: player1Ref, + setIsTransitioning, + }); + }, + [isTransitioning, player2?.container], + ); - useEffect(() => { - if (isElectron()) { - if (audioDeviceId) { - player1Ref.current?.getInternalPlayer()?.setSinkId(audioDeviceId); - player2Ref.current?.getInternalPlayer()?.setSinkId(audioDeviceId); - } else { - player1Ref.current?.getInternalPlayer()?.setSinkId(''); - player2Ref.current?.getInternalPlayer()?.setSinkId(''); - } - } - }, [audioDeviceId]); + useEffect(() => { + if (isElectron()) { + if (audioDeviceId) { + player1Ref.current?.getInternalPlayer()?.setSinkId(audioDeviceId); + player2Ref.current?.getInternalPlayer()?.setSinkId(audioDeviceId); + } else { + player1Ref.current?.getInternalPlayer()?.setSinkId(''); + player2Ref.current?.getInternalPlayer()?.setSinkId(''); + } + } + }, [audioDeviceId]); - return ( - <> - - - - ); - }, + return ( + <> + + + + ); + }, ); diff --git a/src/renderer/components/audio-player/utils/list-handlers.ts b/src/renderer/components/audio-player/utils/list-handlers.ts index 04f7f096..be2a0952 100644 --- a/src/renderer/components/audio-player/utils/list-handlers.ts +++ b/src/renderer/components/audio-player/utils/list-handlers.ts @@ -3,129 +3,131 @@ import type { Dispatch } from 'react'; import { CrossfadeStyle } from '/@/renderer/types'; export const gaplessHandler = (args: { - currentTime: number; - duration: number; - isFlac: boolean; - isTransitioning: boolean; - nextPlayerRef: any; - setIsTransitioning: Dispatch; + currentTime: number; + duration: number; + isFlac: boolean; + isTransitioning: boolean; + nextPlayerRef: any; + setIsTransitioning: Dispatch; }) => { - const { nextPlayerRef, currentTime, duration, isTransitioning, setIsTransitioning, isFlac } = - args; + const { nextPlayerRef, currentTime, duration, isTransitioning, setIsTransitioning, isFlac } = + args; - if (!isTransitioning) { - if (currentTime > duration - 2) { - return setIsTransitioning(true); + if (!isTransitioning) { + if (currentTime > duration - 2) { + return setIsTransitioning(true); + } + + return null; + } + + const durationPadding = isFlac ? 0.065 : 0.116; + if (currentTime + durationPadding >= duration) { + return nextPlayerRef.current.getInternalPlayer().play(); } return null; - } - - const durationPadding = isFlac ? 0.065 : 0.116; - if (currentTime + durationPadding >= duration) { - return nextPlayerRef.current.getInternalPlayer().play(); - } - - return null; }; export const crossfadeHandler = (args: { - currentPlayer: 1 | 2; - currentPlayerRef: any; - currentTime: number; - duration: number; - fadeDuration: number; - fadeType: CrossfadeStyle; - isTransitioning: boolean; - nextPlayerRef: any; - player: 1 | 2; - setIsTransitioning: Dispatch; - volume: number; + currentPlayer: 1 | 2; + currentPlayerRef: any; + currentTime: number; + duration: number; + fadeDuration: number; + fadeType: CrossfadeStyle; + isTransitioning: boolean; + nextPlayerRef: any; + player: 1 | 2; + setIsTransitioning: Dispatch; + volume: number; }) => { - const { - currentTime, - player, - currentPlayer, - currentPlayerRef, - nextPlayerRef, - fadeDuration, - fadeType, - duration, - volume, - isTransitioning, - setIsTransitioning, - } = args; + const { + currentTime, + player, + currentPlayer, + currentPlayerRef, + nextPlayerRef, + fadeDuration, + fadeType, + duration, + volume, + isTransitioning, + setIsTransitioning, + } = args; - if (!isTransitioning || currentPlayer !== player) { - const shouldBeginTransition = currentTime >= duration - fadeDuration; + if (!isTransitioning || currentPlayer !== player) { + const shouldBeginTransition = currentTime >= duration - fadeDuration; - if (shouldBeginTransition) { - setIsTransitioning(true); - return nextPlayerRef.current.getInternalPlayer().play(); + if (shouldBeginTransition) { + setIsTransitioning(true); + return nextPlayerRef.current.getInternalPlayer().play(); + } + return null; } + + const timeLeft = duration - currentTime; + let currentPlayerVolumeCalculation; + let nextPlayerVolumeCalculation; + let percentageOfFadeLeft; + let n; + switch (fadeType) { + case 'equalPower': + // https://dsp.stackexchange.com/a/14755 + percentageOfFadeLeft = (timeLeft / fadeDuration) * 2; + currentPlayerVolumeCalculation = Math.sqrt(0.5 * percentageOfFadeLeft) * volume; + nextPlayerVolumeCalculation = Math.sqrt(0.5 * (2 - percentageOfFadeLeft)) * volume; + break; + case 'linear': + currentPlayerVolumeCalculation = (timeLeft / fadeDuration) * volume; + nextPlayerVolumeCalculation = ((fadeDuration - timeLeft) / fadeDuration) * volume; + break; + case 'dipped': + // https://math.stackexchange.com/a/4622 + percentageOfFadeLeft = timeLeft / fadeDuration; + currentPlayerVolumeCalculation = percentageOfFadeLeft ** 2 * volume; + nextPlayerVolumeCalculation = (percentageOfFadeLeft - 1) ** 2 * volume; + break; + case fadeType.match(/constantPower.*/)?.input: + // https://math.stackexchange.com/a/26159 + n = + fadeType === 'constantPower' + ? 0 + : fadeType === 'constantPowerSlowFade' + ? 1 + : fadeType === 'constantPowerSlowCut' + ? 3 + : 10; + + percentageOfFadeLeft = timeLeft / fadeDuration; + currentPlayerVolumeCalculation = + Math.cos((Math.PI / 4) * ((2 * percentageOfFadeLeft - 1) ** (2 * n + 1) - 1)) * + volume; + nextPlayerVolumeCalculation = + Math.cos((Math.PI / 4) * ((2 * percentageOfFadeLeft - 1) ** (2 * n + 1) + 1)) * + volume; + break; + + default: + currentPlayerVolumeCalculation = (timeLeft / fadeDuration) * volume; + nextPlayerVolumeCalculation = ((fadeDuration - timeLeft) / fadeDuration) * volume; + break; + } + + const currentPlayerVolume = + currentPlayerVolumeCalculation >= 0 ? currentPlayerVolumeCalculation : 0; + + const nextPlayerVolume = + nextPlayerVolumeCalculation <= volume ? nextPlayerVolumeCalculation : volume; + + if (currentPlayer === 1) { + currentPlayerRef.current.getInternalPlayer().volume = currentPlayerVolume; + nextPlayerRef.current.getInternalPlayer().volume = nextPlayerVolume; + } else { + currentPlayerRef.current.getInternalPlayer().volume = currentPlayerVolume; + nextPlayerRef.current.getInternalPlayer().volume = nextPlayerVolume; + } + // } + return null; - } - - const timeLeft = duration - currentTime; - let currentPlayerVolumeCalculation; - let nextPlayerVolumeCalculation; - let percentageOfFadeLeft; - let n; - switch (fadeType) { - case 'equalPower': - // https://dsp.stackexchange.com/a/14755 - percentageOfFadeLeft = (timeLeft / fadeDuration) * 2; - currentPlayerVolumeCalculation = Math.sqrt(0.5 * percentageOfFadeLeft) * volume; - nextPlayerVolumeCalculation = Math.sqrt(0.5 * (2 - percentageOfFadeLeft)) * volume; - break; - case 'linear': - currentPlayerVolumeCalculation = (timeLeft / fadeDuration) * volume; - nextPlayerVolumeCalculation = ((fadeDuration - timeLeft) / fadeDuration) * volume; - break; - case 'dipped': - // https://math.stackexchange.com/a/4622 - percentageOfFadeLeft = timeLeft / fadeDuration; - currentPlayerVolumeCalculation = percentageOfFadeLeft ** 2 * volume; - nextPlayerVolumeCalculation = (percentageOfFadeLeft - 1) ** 2 * volume; - break; - case fadeType.match(/constantPower.*/)?.input: - // https://math.stackexchange.com/a/26159 - n = - fadeType === 'constantPower' - ? 0 - : fadeType === 'constantPowerSlowFade' - ? 1 - : fadeType === 'constantPowerSlowCut' - ? 3 - : 10; - - percentageOfFadeLeft = timeLeft / fadeDuration; - currentPlayerVolumeCalculation = - Math.cos((Math.PI / 4) * ((2 * percentageOfFadeLeft - 1) ** (2 * n + 1) - 1)) * volume; - nextPlayerVolumeCalculation = - Math.cos((Math.PI / 4) * ((2 * percentageOfFadeLeft - 1) ** (2 * n + 1) + 1)) * volume; - break; - - default: - currentPlayerVolumeCalculation = (timeLeft / fadeDuration) * volume; - nextPlayerVolumeCalculation = ((fadeDuration - timeLeft) / fadeDuration) * volume; - break; - } - - const currentPlayerVolume = - currentPlayerVolumeCalculation >= 0 ? currentPlayerVolumeCalculation : 0; - - const nextPlayerVolume = - nextPlayerVolumeCalculation <= volume ? nextPlayerVolumeCalculation : volume; - - if (currentPlayer === 1) { - currentPlayerRef.current.getInternalPlayer().volume = currentPlayerVolume; - nextPlayerRef.current.getInternalPlayer().volume = nextPlayerVolume; - } else { - currentPlayerRef.current.getInternalPlayer().volume = currentPlayerVolume; - nextPlayerRef.current.getInternalPlayer().volume = nextPlayerVolume; - } - // } - - return null; }; diff --git a/src/renderer/components/badge/index.tsx b/src/renderer/components/badge/index.tsx index fd40b60b..2343f744 100644 --- a/src/renderer/components/badge/index.tsx +++ b/src/renderer/components/badge/index.tsx @@ -5,30 +5,30 @@ import styled from 'styled-components'; export type BadgeProps = MantineBadgeProps; const StyledBadge = styled(MantineBadge)` - border-radius: var(--badge-radius); + border-radius: var(--badge-radius); - .mantine-Badge-root { - color: var(--badge-fg); - } + .mantine-Badge-root { + color: var(--badge-fg); + } - .mantine-Badge-inner { - color: var(--badge-fg); - } + .mantine-Badge-inner { + color: var(--badge-fg); + } `; const _Badge = ({ children, ...props }: BadgeProps) => { - return ( - - {children} - - ); + return ( + + {children} + + ); }; export const Badge = createPolymorphicComponent<'button', BadgeProps>(_Badge); diff --git a/src/renderer/components/button/index.tsx b/src/renderer/components/button/index.tsx index 17b0a322..3490feb4 100644 --- a/src/renderer/components/button/index.tsx +++ b/src/renderer/components/button/index.tsx @@ -8,177 +8,177 @@ import { Spinner } from '/@/renderer/components/spinner'; import { Tooltip } from '/@/renderer/components/tooltip'; export interface ButtonProps extends MantineButtonProps { - children: React.ReactNode; - loading?: boolean; - onClick?: (e: React.MouseEvent) => void; - onMouseDown?: (e: React.MouseEvent) => void; - tooltip?: Omit; + children: React.ReactNode; + loading?: boolean; + onClick?: (e: React.MouseEvent) => void; + onMouseDown?: (e: React.MouseEvent) => void; + tooltip?: Omit; } interface StyledButtonProps extends ButtonProps { - ref: Ref; + ref: Ref; } const StyledButton = styled(MantineButton)` - color: ${(props) => `var(--btn-${props.variant}-fg)`}; - background: ${(props) => `var(--btn-${props.variant}-bg)`}; - border: ${(props) => `var(--btn-${props.variant}-border)`}; - border-radius: ${(props) => `var(--btn-${props.variant}-radius)`}; - transition: background 0.2s ease-in-out, color 0.2s ease-in-out, border 0.2s ease-in-out; - - svg { - transition: fill 0.2s ease-in-out; - fill: ${(props) => `var(--btn-${props.variant}-fg)`}; - } - - &:disabled { color: ${(props) => `var(--btn-${props.variant}-fg)`}; background: ${(props) => `var(--btn-${props.variant}-bg)`}; - - opacity: 0.6; - } - - &:not([data-disabled])&:hover { - color: ${(props) => `var(--btn-${props.variant}-fg-hover) !important`}; - background: ${(props) => `var(--btn-${props.variant}-bg-hover)`}; - border: ${(props) => `var(--btn-${props.variant}-border-hover)`}; + border: ${(props) => `var(--btn-${props.variant}-border)`}; + border-radius: ${(props) => `var(--btn-${props.variant}-radius)`}; + transition: background 0.2s ease-in-out, color 0.2s ease-in-out, border 0.2s ease-in-out; svg { - fill: ${(props) => `var(--btn-${props.variant}-fg-hover)`}; + transition: fill 0.2s ease-in-out; + fill: ${(props) => `var(--btn-${props.variant}-fg)`}; } - } - &:not([data-disabled])&:focus-visible { - color: ${(props) => `var(--btn-${props.variant}-fg-hover)`}; - background: ${(props) => `var(--btn-${props.variant}-bg-hover)`}; - } + &:disabled { + color: ${(props) => `var(--btn-${props.variant}-fg)`}; + background: ${(props) => `var(--btn-${props.variant}-bg)`}; - &:active { - transform: none; - } + opacity: 0.6; + } - & .mantine-Button-centerLoader { - display: none; - } + &:not([data-disabled])&:hover { + color: ${(props) => `var(--btn-${props.variant}-fg-hover) !important`}; + background: ${(props) => `var(--btn-${props.variant}-bg-hover)`}; + border: ${(props) => `var(--btn-${props.variant}-border-hover)`}; - & .mantine-Button-leftIcon { - display: flex; - height: 100%; - margin-right: 0.5rem; - transform: translateY(-0.1rem); - } + svg { + fill: ${(props) => `var(--btn-${props.variant}-fg-hover)`}; + } + } - .mantine-Button-rightIcon { - display: flex; - margin-left: 0.5rem; - } + &:not([data-disabled])&:focus-visible { + color: ${(props) => `var(--btn-${props.variant}-fg-hover)`}; + background: ${(props) => `var(--btn-${props.variant}-bg-hover)`}; + } + + &:active { + transform: none; + } + + & .mantine-Button-centerLoader { + display: none; + } + + & .mantine-Button-leftIcon { + display: flex; + height: 100%; + margin-right: 0.5rem; + transform: translateY(-0.1rem); + } + + .mantine-Button-rightIcon { + display: flex; + margin-left: 0.5rem; + } `; const ButtonChildWrapper = styled.span<{ $loading?: boolean }>` - color: ${(props) => props.$loading && 'transparent !important'}; + color: ${(props) => props.$loading && 'transparent !important'}; `; const SpinnerWrapper = styled.div` - position: absolute; - top: 50%; - left: 50%; - transform: translate3d(-50%, -50%, 0); + position: absolute; + top: 50%; + left: 50%; + transform: translate3d(-50%, -50%, 0); `; export const _Button = forwardRef( - ({ children, tooltip, ...props }: ButtonProps, ref) => { - if (tooltip) { - return ( - - - {children} - {props.loading && ( - - - - )} - - - ); - } + ({ children, tooltip, ...props }: ButtonProps, ref) => { + if (tooltip) { + return ( + + + {children} + {props.loading && ( + + + + )} + + + ); + } - return ( - - {children} - {props.loading && ( - - - - )} - - ); - }, + return ( + + {children} + {props.loading && ( + + + + )} + + ); + }, ); export const Button = createPolymorphicComponent<'button', ButtonProps>(_Button); _Button.defaultProps = { - loading: undefined, - onClick: undefined, - tooltip: undefined, + loading: undefined, + onClick: undefined, + tooltip: undefined, }; interface HoldButtonProps extends ButtonProps { - timeoutProps: { - callback: () => void; - duration: number; - }; + timeoutProps: { + callback: () => void; + duration: number; + }; } export const TimeoutButton = ({ timeoutProps, ...props }: HoldButtonProps) => { - const [, setTimeoutRemaining] = useState(timeoutProps.duration); - const [isRunning, setIsRunning] = useState(false); - const intervalRef = useRef(0); + const [, setTimeoutRemaining] = useState(timeoutProps.duration); + const [isRunning, setIsRunning] = useState(false); + const intervalRef = useRef(0); - const callback = () => { - timeoutProps.callback(); - setTimeoutRemaining(timeoutProps.duration); - clearInterval(intervalRef.current); - setIsRunning(false); - }; + const callback = () => { + timeoutProps.callback(); + setTimeoutRemaining(timeoutProps.duration); + clearInterval(intervalRef.current); + setIsRunning(false); + }; - const { start, clear } = useTimeout(callback, timeoutProps.duration); + const { start, clear } = useTimeout(callback, timeoutProps.duration); - const startTimeout = useCallback(() => { - if (isRunning) { - clearInterval(intervalRef.current); - setIsRunning(false); - clear(); - } else { - setIsRunning(true); - start(); + const startTimeout = useCallback(() => { + if (isRunning) { + clearInterval(intervalRef.current); + setIsRunning(false); + clear(); + } else { + setIsRunning(true); + start(); - const intervalId = window.setInterval(() => { - setTimeoutRemaining((prev) => prev - 100); - }, 100); + const intervalId = window.setInterval(() => { + setTimeoutRemaining((prev) => prev - 100); + }, 100); - intervalRef.current = intervalId; - } - }, [clear, isRunning, start]); + intervalRef.current = intervalId; + } + }, [clear, isRunning, start]); - return ( - - ); + return ( + + ); }; diff --git a/src/renderer/components/card/album-card.tsx b/src/renderer/components/card/album-card.tsx index 3be8e3e9..2d3db134 100644 --- a/src/renderer/components/card/album-card.tsx +++ b/src/renderer/components/card/album-card.tsx @@ -11,208 +11,208 @@ import { Album, AlbumArtist, Artist, LibraryItem } from '/@/renderer/api/types'; import { CardRows } from '/@/renderer/components/card/card-rows'; const CardWrapper = styled.div<{ - link?: boolean; + link?: boolean; }>` - padding: 1rem; - background: var(--card-default-bg); - border-radius: var(--card-default-radius); - cursor: ${({ link }) => link && 'pointer'}; - transition: border 0.2s ease-in-out, background 0.2s ease-in-out; + padding: 1rem; + background: var(--card-default-bg); + border-radius: var(--card-default-radius); + cursor: ${({ link }) => link && 'pointer'}; + transition: border 0.2s ease-in-out, background 0.2s ease-in-out; - &:hover { - background: var(--card-default-bg-hover); - } - - &:hover div { - opacity: 1; - } - - &:hover * { - &::before { - opacity: 0.5; + &:hover { + background: var(--card-default-bg-hover); } - } - &:focus-visible { - outline: 1px solid #fff; - } + &:hover div { + opacity: 1; + } + + &:hover * { + &::before { + opacity: 0.5; + } + } + + &:focus-visible { + outline: 1px solid #fff; + } `; const StyledCard = styled.div` - display: flex; - flex-direction: column; - gap: 0.5rem; - width: 100%; - height: 100%; - padding: 0; - border-radius: var(--card-default-radius); + display: flex; + flex-direction: column; + gap: 0.5rem; + width: 100%; + height: 100%; + padding: 0; + border-radius: var(--card-default-radius); `; const ImageSection = styled.div` - position: relative; - display: flex; - justify-content: center; - border-radius: var(--card-default-radius); + position: relative; + display: flex; + justify-content: center; + border-radius: var(--card-default-radius); - &::before { - position: absolute; - top: 0; - left: 0; - z-index: 1; - width: 100%; - height: 100%; - background: linear-gradient(0deg, rgba(0, 0, 0, 100%) 35%, rgba(0, 0, 0, 0%) 100%); - opacity: 0; - transition: all 0.2s ease-in-out; - content: ''; - user-select: none; - } + &::before { + position: absolute; + top: 0; + left: 0; + z-index: 1; + width: 100%; + height: 100%; + background: linear-gradient(0deg, rgba(0, 0, 0, 100%) 35%, rgba(0, 0, 0, 0%) 100%); + opacity: 0; + transition: all 0.2s ease-in-out; + content: ''; + user-select: none; + } `; const Image = styled(SimpleImg)` - border-radius: var(--card-default-radius); - box-shadow: 2px 2px 10px 2px rgba(0, 0, 0, 20%); + border-radius: var(--card-default-radius); + box-shadow: 2px 2px 10px 2px rgba(0, 0, 0, 20%); `; const ControlsContainer = styled.div` - position: absolute; - bottom: 0; - z-index: 50; - width: 100%; - opacity: 0; - transition: all 0.2s ease-in-out; + position: absolute; + bottom: 0; + z-index: 50; + width: 100%; + opacity: 0; + transition: all 0.2s ease-in-out; `; const DetailSection = styled.div` - display: flex; - flex-direction: column; + display: flex; + flex-direction: column; `; const Row = styled.div<{ $secondary?: boolean }>` - width: 100%; - max-width: 100%; - height: 22px; - padding: 0 0.2rem; - overflow: hidden; - color: ${({ $secondary }) => ($secondary ? 'var(--main-fg-secondary)' : 'var(--main-fg)')}; - white-space: nowrap; - text-overflow: ellipsis; - user-select: none; + width: 100%; + max-width: 100%; + height: 22px; + padding: 0 0.2rem; + overflow: hidden; + color: ${({ $secondary }) => ($secondary ? 'var(--main-fg-secondary)' : 'var(--main-fg)')}; + white-space: nowrap; + text-overflow: ellipsis; + user-select: none; `; interface BaseGridCardProps { - controls: { - cardRows: CardRow[]; - itemType: LibraryItem; - playButtonBehavior: Play; - route: CardRoute; - }; - data: any; - handlePlayQueueAdd?: (options: PlayQueueAddOptions) => void; - loading?: boolean; - size: number; + controls: { + cardRows: CardRow[]; + itemType: LibraryItem; + playButtonBehavior: Play; + route: CardRoute; + }; + data: any; + handlePlayQueueAdd?: (options: PlayQueueAddOptions) => void; + loading?: boolean; + size: number; } export const AlbumCard = ({ - loading, - size, - handlePlayQueueAdd, - data, - controls, + loading, + size, + handlePlayQueueAdd, + data, + controls, }: BaseGridCardProps) => { - const navigate = useNavigate(); - const { itemType, cardRows, route } = controls; + const navigate = useNavigate(); + const { itemType, cardRows, route } = controls; - const handleNavigate = useCallback(() => { - navigate( - generatePath( - route.route, - route.slugs?.reduce((acc, slug) => { - return { - ...acc, - [slug.slugProperty]: data[slug.idProperty], - }; - }, {}), - ), - ); - }, [data, navigate, route.route, route.slugs]); + const handleNavigate = useCallback(() => { + navigate( + generatePath( + route.route, + route.slugs?.reduce((acc, slug) => { + return { + ...acc, + [slug.slugProperty]: data[slug.idProperty], + }; + }, {}), + ), + ); + }, [data, navigate, route.route, route.slugs]); - if (!loading) { - return ( - - - - {data?.imageUrl ? ( - - ) : ( -
- -
- )} - - - -
- - - -
-
- ); - } - - return ( - - - - - - - {cardRows.map((_row: CardRow, index: number) => ( - 0 ? '50%' : '90%') : '100%'} + if (!loading) { + return ( + - - - ))} - - - - ); + + + {data?.imageUrl ? ( + + ) : ( +
+ +
+ )} + + + +
+ + + +
+ + ); + } + + return ( + + + + + + + {cardRows.map((_row: CardRow, index: number) => ( + 0 ? '50%' : '90%') : '100%'} + > + + + ))} + + + + ); }; diff --git a/src/renderer/components/card/card-controls.tsx b/src/renderer/components/card/card-controls.tsx index 542173fc..c44446c5 100644 --- a/src/renderer/components/card/card-controls.tsx +++ b/src/renderer/components/card/card-controls.tsx @@ -11,69 +11,69 @@ import { usePlayButtonBehavior } from '/@/renderer/store/settings.store'; import { LibraryItem } from '/@/renderer/api/types'; import { useHandleGeneralContextMenu } from '/@/renderer/features/context-menu/hooks/use-handle-context-menu'; import { - ALBUM_CONTEXT_MENU_ITEMS, - ARTIST_CONTEXT_MENU_ITEMS, + ALBUM_CONTEXT_MENU_ITEMS, + ARTIST_CONTEXT_MENU_ITEMS, } from '/@/renderer/features/context-menu/context-menu-items'; type PlayButtonType = UnstyledButtonProps & React.ComponentPropsWithoutRef<'button'>; const PlayButton = styled.button` - display: flex; - align-items: center; - justify-content: center; - width: 50px; - height: 50px; - background-color: rgb(255, 255, 255); - border: none; - border-radius: 50%; - opacity: 0.8; - transition: opacity 0.2s ease-in-out; - transition: scale 0.2s linear; + display: flex; + align-items: center; + justify-content: center; + width: 50px; + height: 50px; + background-color: rgb(255, 255, 255); + border: none; + border-radius: 50%; + opacity: 0.8; + transition: opacity 0.2s ease-in-out; + transition: scale 0.2s linear; - &:hover { - opacity: 1; - scale: 1.1; - } + &:hover { + opacity: 1; + scale: 1.1; + } - &:active { - opacity: 1; - scale: 1; - } + &:active { + opacity: 1; + scale: 1; + } - svg { - fill: rgb(0, 0, 0); - stroke: rgb(0, 0, 0); - } + svg { + fill: rgb(0, 0, 0); + stroke: rgb(0, 0, 0); + } `; const SecondaryButton = styled(_Button)` - opacity: 0.8; - transition: opacity 0.2s ease-in-out; - transition: scale 0.2s linear; + opacity: 0.8; + transition: opacity 0.2s ease-in-out; + transition: scale 0.2s linear; - &:hover { - opacity: 1; - scale: 1.1; - } + &:hover { + opacity: 1; + scale: 1.1; + } - &:active { - opacity: 1; - scale: 1; - } + &:active { + opacity: 1; + scale: 1; + } `; const GridCardControlsContainer = styled.div` - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - width: 100%; - height: 100%; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; `; const ControlsRow = styled.div` - width: 100%; - height: calc(100% / 3); + width: 100%; + height: calc(100% / 3); `; // const TopControls = styled(ControlsRow)` @@ -91,87 +91,87 @@ const ControlsRow = styled.div` // `; const BottomControls = styled(ControlsRow)` - display: flex; - align-items: flex-end; - justify-content: space-between; - padding: 1rem 0.5rem; + display: flex; + align-items: flex-end; + justify-content: space-between; + padding: 1rem 0.5rem; `; const FavoriteWrapper = styled.span<{ isFavorite: boolean }>` - svg { - fill: ${(props) => props.isFavorite && 'var(--primary-color)'}; - } + svg { + fill: ${(props) => props.isFavorite && 'var(--primary-color)'}; + } `; export const CardControls = ({ - itemData, - itemType, - handlePlayQueueAdd, -}: { - handlePlayQueueAdd?: (options: PlayQueueAddOptions) => void; - itemData: any; - itemType: LibraryItem; -}) => { - const playButtonBehavior = usePlayButtonBehavior(); - - const handlePlay = (e: MouseEvent, playType?: Play) => { - e.preventDefault(); - e.stopPropagation(); - handlePlayQueueAdd?.({ - byItemType: { - id: [itemData.id], - type: itemType, - }, - playType: playType || playButtonBehavior, - }); - }; - - const handleContextMenu = useHandleGeneralContextMenu( + itemData, itemType, - itemType === LibraryItem.ALBUM ? ALBUM_CONTEXT_MENU_ITEMS : ARTIST_CONTEXT_MENU_ITEMS, - ); + handlePlayQueueAdd, +}: { + handlePlayQueueAdd?: (options: PlayQueueAddOptions) => void; + itemData: any; + itemType: LibraryItem; +}) => { + const playButtonBehavior = usePlayButtonBehavior(); - return ( - - - - - - - - - {itemData?.isFavorite ? ( - - ) : ( - - )} - - - { - e.preventDefault(); - e.stopPropagation(); - handleContextMenu(e, [itemData]); - }} - > - - - - - - ); + const handlePlay = (e: MouseEvent, playType?: Play) => { + e.preventDefault(); + e.stopPropagation(); + handlePlayQueueAdd?.({ + byItemType: { + id: [itemData.id], + type: itemType, + }, + playType: playType || playButtonBehavior, + }); + }; + + const handleContextMenu = useHandleGeneralContextMenu( + itemType, + itemType === LibraryItem.ALBUM ? ALBUM_CONTEXT_MENU_ITEMS : ARTIST_CONTEXT_MENU_ITEMS, + ); + + return ( + + + + + + + + + {itemData?.isFavorite ? ( + + ) : ( + + )} + + + { + e.preventDefault(); + e.stopPropagation(); + handleContextMenu(e, [itemData]); + }} + > + + + + + + ); }; diff --git a/src/renderer/components/card/card-rows.tsx b/src/renderer/components/card/card-rows.tsx index d96bec6e..4b1576b4 100644 --- a/src/renderer/components/card/card-rows.tsx +++ b/src/renderer/components/card/card-rows.tsx @@ -8,205 +8,208 @@ import { AppRoute } from '/@/renderer/router/routes'; import { CardRow } from '/@/renderer/types'; const Row = styled.div<{ $secondary?: boolean }>` - width: 100%; - max-width: 100%; - height: 22px; - padding: 0 0.2rem; - overflow: hidden; - color: ${({ $secondary }) => ($secondary ? 'var(--main-fg-secondary)' : 'var(--main-fg)')}; - white-space: nowrap; - text-overflow: ellipsis; - user-select: none; + width: 100%; + max-width: 100%; + height: 22px; + padding: 0 0.2rem; + overflow: hidden; + color: ${({ $secondary }) => ($secondary ? 'var(--main-fg-secondary)' : 'var(--main-fg)')}; + white-space: nowrap; + text-overflow: ellipsis; + user-select: none; `; interface CardRowsProps { - data: any; - rows: CardRow[] | CardRow[] | CardRow[]; + data: any; + rows: CardRow[] | CardRow[] | CardRow[]; } export const CardRows = ({ data, rows }: CardRowsProps) => { - return ( - <> - {rows.map((row, index: number) => { - if (row.arrayProperty && row.route) { - return ( - 0} - > - {data[row.property].map((item: any, itemIndex: number) => ( - - {itemIndex > 0 && ( - - , - - )}{' '} - 0} - component={Link} - overflow="hidden" - size={index > 0 ? 'sm' : 'md'} - to={generatePath( - row.route!.route, - row.route!.slugs?.reduce((acc, slug) => { - return { - ...acc, - [slug.slugProperty]: data[row.property][itemIndex][slug.idProperty], - }; - }, {}), - )} - onClick={(e) => e.stopPropagation()} - > - {row.arrayProperty && item[row.arrayProperty]} - - - ))} - - ); - } + return ( + <> + {rows.map((row, index: number) => { + if (row.arrayProperty && row.route) { + return ( + 0} + > + {data[row.property].map((item: any, itemIndex: number) => ( + + {itemIndex > 0 && ( + + , + + )}{' '} + 0} + component={Link} + overflow="hidden" + size={index > 0 ? 'sm' : 'md'} + to={generatePath( + row.route!.route, + row.route!.slugs?.reduce((acc, slug) => { + return { + ...acc, + [slug.slugProperty]: + data[row.property][itemIndex][ + slug.idProperty + ], + }; + }, {}), + )} + onClick={(e) => e.stopPropagation()} + > + {row.arrayProperty && item[row.arrayProperty]} + + + ))} + + ); + } - if (row.arrayProperty) { - return ( - - {data[row.property].map((item: any) => ( - 0} - overflow="hidden" - size={index > 0 ? 'sm' : 'md'} - > - {row.arrayProperty && item[row.arrayProperty]} - - ))} - - ); - } + if (row.arrayProperty) { + return ( + + {data[row.property].map((item: any) => ( + 0} + overflow="hidden" + size={index > 0 ? 'sm' : 'md'} + > + {row.arrayProperty && item[row.arrayProperty]} + + ))} + + ); + } - return ( - - {row.route ? ( - { - return { - ...acc, - [slug.slugProperty]: data[slug.idProperty], - }; - }, {}), - )} - onClick={(e) => e.stopPropagation()} - > - {data && data[row.property]} - - ) : ( - 0} - overflow="hidden" - size={index > 0 ? 'sm' : 'md'} - > - {data && data[row.property]} - - )} - - ); - })} - - ); + return ( + + {row.route ? ( + { + return { + ...acc, + [slug.slugProperty]: data[slug.idProperty], + }; + }, {}), + )} + onClick={(e) => e.stopPropagation()} + > + {data && data[row.property]} + + ) : ( + 0} + overflow="hidden" + size={index > 0 ? 'sm' : 'md'} + > + {data && data[row.property]} + + )} + + ); + })} + + ); }; export const ALBUM_CARD_ROWS: { [key: string]: CardRow } = { - albumArtists: { - arrayProperty: 'name', - property: 'albumArtists', - route: { - route: AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, - slugs: [{ idProperty: 'id', slugProperty: 'albumArtistId' }], + albumArtists: { + arrayProperty: 'name', + property: 'albumArtists', + route: { + route: AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, + slugs: [{ idProperty: 'id', slugProperty: 'albumArtistId' }], + }, }, - }, - artists: { - arrayProperty: 'name', - property: 'artists', - route: { - route: AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, - slugs: [{ idProperty: 'id', slugProperty: 'albumArtistId' }], + artists: { + arrayProperty: 'name', + property: 'artists', + route: { + route: AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, + slugs: [{ idProperty: 'id', slugProperty: 'albumArtistId' }], + }, }, - }, - createdAt: { - property: 'createdAt', - }, - duration: { - property: 'duration', - }, - lastPlayedAt: { - property: 'lastPlayedAt', - }, - name: { - property: 'name', - route: { - route: AppRoute.LIBRARY_ALBUMS_DETAIL, - slugs: [{ idProperty: 'id', slugProperty: 'albumId' }], + createdAt: { + property: 'createdAt', + }, + duration: { + property: 'duration', + }, + lastPlayedAt: { + property: 'lastPlayedAt', + }, + name: { + property: 'name', + route: { + route: AppRoute.LIBRARY_ALBUMS_DETAIL, + slugs: [{ idProperty: 'id', slugProperty: 'albumId' }], + }, + }, + playCount: { + property: 'playCount', + }, + rating: { + property: 'userRating', + }, + releaseDate: { + property: 'releaseDate', + }, + releaseYear: { + property: 'releaseYear', + }, + songCount: { + property: 'songCount', }, - }, - playCount: { - property: 'playCount', - }, - rating: { - property: 'userRating', - }, - releaseDate: { - property: 'releaseDate', - }, - releaseYear: { - property: 'releaseYear', - }, - songCount: { - property: 'songCount', - }, }; export const ALBUMARTIST_CARD_ROWS: { [key: string]: CardRow } = { - albumCount: { - property: 'albumCount', - }, - duration: { - property: 'duration', - }, - genres: { - property: 'genres', - }, - lastPlayedAt: { - property: 'lastPlayedAt', - }, - name: { - property: 'name', - route: { - route: AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, - slugs: [{ idProperty: 'id', slugProperty: 'albumArtistId' }], + albumCount: { + property: 'albumCount', + }, + duration: { + property: 'duration', + }, + genres: { + property: 'genres', + }, + lastPlayedAt: { + property: 'lastPlayedAt', + }, + name: { + property: 'name', + route: { + route: AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, + slugs: [{ idProperty: 'id', slugProperty: 'albumArtistId' }], + }, + }, + playCount: { + property: 'playCount', + }, + rating: { + property: 'userRating', + }, + songCount: { + property: 'songCount', }, - }, - playCount: { - property: 'playCount', - }, - rating: { - property: 'userRating', - }, - songCount: { - property: 'songCount', - }, }; diff --git a/src/renderer/components/card/poster-card.tsx b/src/renderer/components/card/poster-card.tsx index ed9a0ebb..5cdc8b94 100644 --- a/src/renderer/components/card/poster-card.tsx +++ b/src/renderer/components/card/poster-card.tsx @@ -10,197 +10,197 @@ import { GridCardControls } from '/@/renderer/components/virtual-grid/grid-card/ import { CardRow, PlayQueueAddOptions, Play, CardRoute } from '/@/renderer/types'; interface BaseGridCardProps { - controls: { - cardRows: CardRow[] | CardRow[] | CardRow[]; - handleFavorite: (options: { - id: string[]; - isFavorite: boolean; - itemType: LibraryItem; - serverId: string; - }) => void; - handlePlayQueueAdd: ((options: PlayQueueAddOptions) => void) | undefined; - itemType: LibraryItem; - playButtonBehavior: Play; - route: CardRoute; - }; - data: any; - isLoading?: boolean; + controls: { + cardRows: CardRow[] | CardRow[] | CardRow[]; + handleFavorite: (options: { + id: string[]; + isFavorite: boolean; + itemType: LibraryItem; + serverId: string; + }) => void; + handlePlayQueueAdd: ((options: PlayQueueAddOptions) => void) | undefined; + itemType: LibraryItem; + playButtonBehavior: Play; + route: CardRoute; + }; + data: any; + isLoading?: boolean; } const PosterCardContainer = styled.div<{ $isHidden?: boolean }>` - display: flex; - flex-direction: column; - width: 100%; - height: 100%; - overflow: hidden; - opacity: ${({ $isHidden }) => ($isHidden ? 0 : 1)}; - pointer-events: auto; + display: flex; + flex-direction: column; + width: 100%; + height: 100%; + overflow: hidden; + opacity: ${({ $isHidden }) => ($isHidden ? 0 : 1)}; + pointer-events: auto; - .card-controls { - opacity: 0; - } + .card-controls { + opacity: 0; + } `; const ImageContainerStyles = css` - position: relative; - display: flex; - align-items: center; - aspect-ratio: 1/1; - overflow: hidden; - background: var(--card-default-bg); - border-radius: var(--card-poster-radius); + position: relative; + display: flex; + align-items: center; + aspect-ratio: 1/1; + overflow: hidden; + background: var(--card-default-bg); + border-radius: var(--card-poster-radius); - &::before { - position: absolute; - top: 0; - left: 0; - z-index: 1; - width: 100%; - height: 100%; - background: linear-gradient(0deg, rgba(0, 0, 0, 100%) 35%, rgba(0, 0, 0, 0%) 100%); - opacity: 0; - transition: all 0.2s ease-in-out; - content: ''; - user-select: none; - } - - &:hover { &::before { - opacity: 0.5; + position: absolute; + top: 0; + left: 0; + z-index: 1; + width: 100%; + height: 100%; + background: linear-gradient(0deg, rgba(0, 0, 0, 100%) 35%, rgba(0, 0, 0, 0%) 100%); + opacity: 0; + transition: all 0.2s ease-in-out; + content: ''; + user-select: none; } - } - &:hover .card-controls { - opacity: 1; - } + &:hover { + &::before { + opacity: 0.5; + } + } + + &:hover .card-controls { + opacity: 1; + } `; const ImageContainer = styled(Link)<{ $isFavorite?: boolean }>` - ${ImageContainerStyles} + ${ImageContainerStyles} `; const ImageContainerSkeleton = styled.div` - ${ImageContainerStyles} + ${ImageContainerStyles} `; const Image = styled(SimpleImg)` - width: 100%; - max-width: 100%; - height: 100% !important; - max-height: 100%; - border: 0; + width: 100%; + max-width: 100%; + height: 100% !important; + max-height: 100%; + border: 0; - img { - height: 100%; - object-fit: cover; - } + img { + height: 100%; + object-fit: cover; + } `; const DetailContainer = styled.div` - margin-top: 0.5rem; + margin-top: 0.5rem; `; export const PosterCard = ({ - data, - controls, - isLoading, - uniqueId, + data, + controls, + isLoading, + uniqueId, }: BaseGridCardProps & { uniqueId: string }) => { - if (!isLoading) { - const path = generatePath( - controls.route.route, - controls.route.slugs?.reduce((acc, slug) => { - return { - ...acc, - [slug.slugProperty]: data[slug.idProperty], - }; - }, {}), - ); + if (!isLoading) { + const path = generatePath( + controls.route.route, + controls.route.slugs?.reduce((acc, slug) => { + return { + ...acc, + [slug.slugProperty]: data[slug.idProperty], + }; + }, {}), + ); - let Placeholder = RiAlbumFill; + let Placeholder = RiAlbumFill; - switch (controls.itemType) { - case LibraryItem.ALBUM: - Placeholder = RiAlbumFill; - break; - case LibraryItem.ARTIST: - Placeholder = RiUserVoiceFill; - break; - case LibraryItem.ALBUM_ARTIST: - Placeholder = RiUserVoiceFill; - break; - case LibraryItem.PLAYLIST: - Placeholder = RiPlayListFill; - break; - default: - Placeholder = RiAlbumFill; - break; + switch (controls.itemType) { + case LibraryItem.ALBUM: + Placeholder = RiAlbumFill; + break; + case LibraryItem.ARTIST: + Placeholder = RiUserVoiceFill; + break; + case LibraryItem.ALBUM_ARTIST: + Placeholder = RiUserVoiceFill; + break; + case LibraryItem.PLAYLIST: + Placeholder = RiPlayListFill; + break; + default: + Placeholder = RiAlbumFill; + break; + } + + return ( + + + {data?.imageUrl ? ( + + ) : ( +
+ +
+ )} + +
+ + + +
+ ); } return ( - - - {data?.imageUrl ? ( - - ) : ( -
- -
- )} - -
- - - -
- ); - } - - return ( - - - - - - - {controls.cardRows.map((row, index) => ( + - ))} - - - - ); + visible + radius="sm" + > + + + + + {controls.cardRows.map((row, index) => ( + + ))} + + + + ); }; diff --git a/src/renderer/components/checkbox/index.tsx b/src/renderer/components/checkbox/index.tsx index b054f759..dff0c054 100644 --- a/src/renderer/components/checkbox/index.tsx +++ b/src/renderer/components/checkbox/index.tsx @@ -3,30 +3,30 @@ import { Checkbox as MantineCheckbox, CheckboxProps } from '@mantine/core'; import styled from 'styled-components'; const StyledCheckbox = styled(MantineCheckbox)` - & .mantine-Checkbox-input { - background-color: var(--input-bg); + & .mantine-Checkbox-input { + background-color: var(--input-bg); - &:checked { - background-color: var(--primary-color); - border-color: var(--primary-color); + &:checked { + background-color: var(--primary-color); + border-color: var(--primary-color); + } + + &:hover:not(:checked) { + background-color: var(--primary-color); + opacity: 0.5; + } + + transition: none; } - - &:hover:not(:checked) { - background-color: var(--primary-color); - opacity: 0.5; - } - - transition: none; - } `; export const Checkbox = forwardRef( - ({ ...props }: CheckboxProps, ref) => { - return ( - - ); - }, + ({ ...props }: CheckboxProps, ref) => { + return ( + + ); + }, ); diff --git a/src/renderer/components/context-menu/index.tsx b/src/renderer/components/context-menu/index.tsx index 83b675f0..27b4d861 100644 --- a/src/renderer/components/context-menu/index.tsx +++ b/src/renderer/components/context-menu/index.tsx @@ -4,124 +4,124 @@ import { motion, Variants } from 'framer-motion'; import styled from 'styled-components'; interface ContextMenuProps { - children: ReactNode; - maxWidth?: number; - minWidth?: number; - xPos: number; - yPos: number; + children: ReactNode; + maxWidth?: number; + minWidth?: number; + xPos: number; + yPos: number; } const ContextMenuContainer = styled(motion.div)>` - position: absolute; - top: ${({ yPos }) => yPos}px !important; - left: ${({ xPos }) => xPos}px !important; - z-index: 1000; - min-width: ${({ minWidth }) => minWidth}px; - max-width: ${({ maxWidth }) => maxWidth}px; - background: var(--dropdown-menu-bg); - border-radius: var(--dropdown-menu-border-radius); - box-shadow: 2px 2px 10px 2px rgba(0, 0, 0, 40%); + position: absolute; + top: ${({ yPos }) => yPos}px !important; + left: ${({ xPos }) => xPos}px !important; + z-index: 1000; + min-width: ${({ minWidth }) => minWidth}px; + max-width: ${({ maxWidth }) => maxWidth}px; + background: var(--dropdown-menu-bg); + border-radius: var(--dropdown-menu-border-radius); + box-shadow: 2px 2px 10px 2px rgba(0, 0, 0, 40%); - button:first-child { - border-top-left-radius: var(--dropdown-menu-border-radius); - border-top-right-radius: var(--dropdown-menu-border-radius); - } + button:first-child { + border-top-left-radius: var(--dropdown-menu-border-radius); + border-top-right-radius: var(--dropdown-menu-border-radius); + } - button:last-child { - border-bottom-right-radius: var(--dropdown-menu-border-radius); - border-bottom-left-radius: var(--dropdown-menu-border-radius); - } + button:last-child { + border-bottom-right-radius: var(--dropdown-menu-border-radius); + border-bottom-left-radius: var(--dropdown-menu-border-radius); + } `; export const StyledContextMenuButton = styled(UnstyledButton)` - padding: var(--dropdown-menu-item-padding); - color: var(--dropdown-menu-fg); - font-weight: 500; - font-family: var(--content-font-family); - text-align: left; - background: var(--dropdown-menu-bg); - border: none; - cursor: default; + padding: var(--dropdown-menu-item-padding); + color: var(--dropdown-menu-fg); + font-weight: 500; + font-family: var(--content-font-family); + text-align: left; + background: var(--dropdown-menu-bg); + border: none; + cursor: default; - & .mantine-Button-inner { - justify-content: flex-start; - } + & .mantine-Button-inner { + justify-content: flex-start; + } - &:hover { - background: var(--dropdown-menu-bg-hover); - } + &:hover { + background: var(--dropdown-menu-bg-hover); + } - &:disabled { - background: transparent; - opacity: 0.6; - } + &:disabled { + background: transparent; + opacity: 0.6; + } `; export const ContextMenuButton = forwardRef( - ( - { - children, - rightIcon, - leftIcon, - ...props - }: UnstyledButtonProps & - React.ComponentPropsWithoutRef<'button'> & { - leftIcon?: ReactNode; - rightIcon?: ReactNode; - }, - ref: any, - ) => { - return ( - - - - {leftIcon} - {children} - - {rightIcon} - - - ); - }, + ( + { + children, + rightIcon, + leftIcon, + ...props + }: UnstyledButtonProps & + React.ComponentPropsWithoutRef<'button'> & { + leftIcon?: ReactNode; + rightIcon?: ReactNode; + }, + ref: any, + ) => { + return ( + + + + {leftIcon} + {children} + + {rightIcon} + + + ); + }, ); const variants: Variants = { - closed: { - opacity: 0, - transition: { - duration: 0.1, + closed: { + opacity: 0, + transition: { + duration: 0.1, + }, }, - }, - open: { - opacity: 1, - transition: { - duration: 0.1, + open: { + opacity: 1, + transition: { + duration: 0.1, + }, }, - }, }; export const ContextMenu = forwardRef( - ({ yPos, xPos, minWidth, maxWidth, children }: ContextMenuProps, ref: Ref) => { - return ( - - {children} - - ); - }, + ({ yPos, xPos, minWidth, maxWidth, children }: ContextMenuProps, ref: Ref) => { + return ( + + {children} + + ); + }, ); diff --git a/src/renderer/components/date-picker/index.tsx b/src/renderer/components/date-picker/index.tsx index 7d6a66f7..bd96fe53 100644 --- a/src/renderer/components/date-picker/index.tsx +++ b/src/renderer/components/date-picker/index.tsx @@ -3,47 +3,47 @@ import { DatePicker as MantineDatePicker } from '@mantine/dates'; import styled from 'styled-components'; interface DatePickerProps extends MantineDatePickerProps { - maxWidth?: number | string; - width?: number | string; + maxWidth?: number | string; + width?: number | string; } const StyledDatePicker = styled(MantineDatePicker)` - & .mantine-DatePicker-input { - color: var(--input-fg); - background: var(--input-bg); + & .mantine-DatePicker-input { + color: var(--input-fg); + background: var(--input-bg); - &::placeholder { - color: var(--input-placeholder-fg); + &::placeholder { + color: var(--input-placeholder-fg); + } } - } - & .mantine-DatePicker-icon { - color: var(--input-placeholder-fg); - } + & .mantine-DatePicker-icon { + color: var(--input-placeholder-fg); + } - & .mantine-DatePicker-required { - color: var(--secondary-color); - } + & .mantine-DatePicker-required { + color: var(--secondary-color); + } - & .mantine-DatePicker-label { - font-family: var(--label-font-family); - } + & .mantine-DatePicker-label { + font-family: var(--label-font-family); + } - & .mantine-DateRangePicker-disabled { - opacity: 0.6; - } + & .mantine-DateRangePicker-disabled { + opacity: 0.6; + } `; export const DatePicker = ({ width, maxWidth, ...props }: DatePickerProps) => { - return ( - - ); + return ( + + ); }; DatePicker.defaultProps = { - maxWidth: undefined, - width: undefined, + maxWidth: undefined, + width: undefined, }; diff --git a/src/renderer/components/dropdown-menu/index.tsx b/src/renderer/components/dropdown-menu/index.tsx index b9cbd913..71585d97 100644 --- a/src/renderer/components/dropdown-menu/index.tsx +++ b/src/renderer/components/dropdown-menu/index.tsx @@ -1,9 +1,9 @@ import type { - MenuProps as MantineMenuProps, - MenuItemProps as MantineMenuItemProps, - MenuLabelProps as MantineMenuLabelProps, - MenuDividerProps as MantineMenuDividerProps, - MenuDropdownProps as MantineMenuDropdownProps, + MenuProps as MantineMenuProps, + MenuItemProps as MantineMenuItemProps, + MenuLabelProps as MantineMenuLabelProps, + MenuDividerProps as MantineMenuDividerProps, + MenuDropdownProps as MantineMenuDropdownProps, } from '@mantine/core'; import { Menu as MantineMenu, createPolymorphicComponent } from '@mantine/core'; import { RiArrowLeftSFill } from 'react-icons/ri'; @@ -12,9 +12,9 @@ import styled from 'styled-components'; type MenuProps = MantineMenuProps; type MenuLabelProps = MantineMenuLabelProps; interface MenuItemProps extends MantineMenuItemProps { - $danger?: boolean; - $isActive?: boolean; - children: React.ReactNode; + $danger?: boolean; + $isActive?: boolean; + children: React.ReactNode; } type MenuDividerProps = MantineMenuDividerProps; type MenuDropdownProps = MantineMenuDropdownProps; @@ -22,46 +22,46 @@ type MenuDropdownProps = MantineMenuDropdownProps; const StyledMenu = styled(MantineMenu)``; const StyledMenuLabel = styled(MantineMenu.Label)` - padding: 0.5rem; - font-family: var(--content-font-family); + padding: 0.5rem; + font-family: var(--content-font-family); `; const StyledMenuItem = styled(MantineMenu.Item)` - position: relative; - padding: var(--dropdown-menu-item-padding); - font-size: var(--dropdown-menu-item-font-size); - font-family: var(--content-font-family); + position: relative; + padding: var(--dropdown-menu-item-padding); + font-size: var(--dropdown-menu-item-font-size); + font-family: var(--content-font-family); - &:disabled { - opacity: 0.6; - } + &:disabled { + opacity: 0.6; + } - &:hover { - background-color: var(--dropdown-menu-bg-hover); - } + &:hover { + background-color: var(--dropdown-menu-bg-hover); + } - & .mantine-Menu-itemLabel { - margin-right: 2rem; - margin-left: 1rem; - color: ${(props) => (props.$danger ? 'var(--danger-color)' : 'var(--dropdown-menu-fg)')}; - } + & .mantine-Menu-itemLabel { + margin-right: 2rem; + margin-left: 1rem; + color: ${(props) => (props.$danger ? 'var(--danger-color)' : 'var(--dropdown-menu-fg)')}; + } - & .mantine-Menu-itemRightSection { - display: flex; - } + & .mantine-Menu-itemRightSection { + display: flex; + } - cursor: default; + cursor: default; `; const StyledMenuDropdown = styled(MantineMenu.Dropdown)` - margin: 0; - padding: 0; - background: var(--dropdown-menu-bg); - border: var(--dropdown-menu-border); - border-radius: var(--dropdown-menu-border-radius); - filter: drop-shadow(0 0 5px rgb(0, 0, 0, 50%)); + margin: 0; + padding: 0; + background: var(--dropdown-menu-bg); + border: var(--dropdown-menu-border); + border-radius: var(--dropdown-menu-border-radius); + filter: drop-shadow(0 0 5px rgb(0, 0, 0, 50%)); - /* *:first-child { + /* *:first-child { border-top-left-radius: var(--dropdown-menu-border-radius); border-top-right-radius: var(--dropdown-menu-border-radius); } @@ -73,51 +73,51 @@ const StyledMenuDropdown = styled(MantineMenu.Dropdown)` `; const StyledMenuDivider = styled(MantineMenu.Divider)` - margin: 0; - padding: 0; + margin: 0; + padding: 0; `; export const DropdownMenu = ({ children, ...props }: MenuProps) => { - return ( - - {children} - - ); + return ( + + {children} + + ); }; const MenuLabel = ({ children, ...props }: MenuLabelProps) => { - return {children}; + return {children}; }; const pMenuItem = ({ $isActive, $danger, children, ...props }: MenuItemProps) => { - return ( - } - {...props} - > - {children} - - ); + return ( + } + {...props} + > + {children} + + ); }; const MenuDropdown = ({ children, ...props }: MenuDropdownProps) => { - return {children}; + return {children}; }; const MenuItem = createPolymorphicComponent<'button', MenuItemProps>(pMenuItem); const MenuDivider = ({ ...props }: MenuDividerProps) => { - return ; + return ; }; DropdownMenu.Label = MenuLabel; diff --git a/src/renderer/components/feature-carousel/index.tsx b/src/renderer/components/feature-carousel/index.tsx index 78e5a1a7..c71879c5 100644 --- a/src/renderer/components/feature-carousel/index.tsx +++ b/src/renderer/components/feature-carousel/index.tsx @@ -15,245 +15,247 @@ import { usePlayQueueAdd } from '/@/renderer/features/player/hooks/use-playqueue import { Play } from '/@/renderer/types'; const Carousel = styled(motion.div)` - position: relative; - height: 35vh; - min-height: 250px; - padding: 2rem; - overflow: hidden; - background: linear-gradient(180deg, var(--main-bg), rgba(25, 26, 28, 60%)); - border-radius: 1rem; + position: relative; + height: 35vh; + min-height: 250px; + padding: 2rem; + overflow: hidden; + background: linear-gradient(180deg, var(--main-bg), rgba(25, 26, 28, 60%)); + border-radius: 1rem; `; const Grid = styled.div` - display: grid; - grid-auto-columns: 1fr; - grid-template-areas: 'image info'; - grid-template-rows: 1fr; - grid-template-columns: 200px minmax(0, 1fr); - width: 100%; - max-width: 100%; - height: 100%; + display: grid; + grid-auto-columns: 1fr; + grid-template-areas: 'image info'; + grid-template-rows: 1fr; + grid-template-columns: 200px minmax(0, 1fr); + width: 100%; + max-width: 100%; + height: 100%; `; const ImageColumn = styled.div` - z-index: 15; - display: flex; - grid-area: image; - align-items: flex-end; + z-index: 15; + display: flex; + grid-area: image; + align-items: flex-end; `; const InfoColumn = styled.div` - z-index: 15; - display: flex; - grid-area: info; - align-items: flex-end; - width: 100%; - max-width: 100%; - padding-left: 1rem; + z-index: 15; + display: flex; + grid-area: info; + align-items: flex-end; + width: 100%; + max-width: 100%; + padding-left: 1rem; `; const BackgroundImage = styled.img` - position: absolute; - top: 0; - left: 0; - z-index: 0; - width: 150%; - height: 150%; - object-fit: cover; - object-position: 0 30%; - filter: blur(24px); - user-select: none; + position: absolute; + top: 0; + left: 0; + z-index: 0; + width: 150%; + height: 150%; + object-fit: cover; + object-position: 0 30%; + filter: blur(24px); + user-select: none; `; const BackgroundImageOverlay = styled.div` - position: absolute; - top: 0; - left: 0; - z-index: 10; - width: 100%; - height: 100%; - background: linear-gradient(180deg, rgba(25, 26, 28, 30%), var(--main-bg)); + position: absolute; + top: 0; + left: 0; + z-index: 10; + width: 100%; + height: 100%; + background: linear-gradient(180deg, rgba(25, 26, 28, 30%), var(--main-bg)); `; const Wrapper = styled(Link)` - position: relative; - width: 100%; - height: 100%; - overflow: hidden; + position: relative; + width: 100%; + height: 100%; + overflow: hidden; `; const TitleWrapper = styled.div` - /* stylelint-disable-next-line value-no-vendor-prefix */ - display: -webkit-box; - -webkit-line-clamp: 2; - -webkit-box-orient: vertical; - overflow: hidden; + /* stylelint-disable-next-line value-no-vendor-prefix */ + display: -webkit-box; + -webkit-line-clamp: 2; + -webkit-box-orient: vertical; + overflow: hidden; `; const variants: Variants = { - animate: { - opacity: 1, - transition: { opacity: { duration: 0.5 } }, - }, - exit: { - opacity: 0, - transition: { opacity: { duration: 0.5 } }, - }, - initial: { - opacity: 0, - }, + animate: { + opacity: 1, + transition: { opacity: { duration: 0.5 } }, + }, + exit: { + opacity: 0, + transition: { opacity: { duration: 0.5 } }, + }, + initial: { + opacity: 0, + }, }; interface FeatureCarouselProps { - data: Album[] | undefined; + data: Album[] | undefined; } export const FeatureCarousel = ({ data }: FeatureCarouselProps) => { - const handlePlayQueueAdd = usePlayQueueAdd(); - const [itemIndex, setItemIndex] = useState(0); - const [direction, setDirection] = useState(0); + const handlePlayQueueAdd = usePlayQueueAdd(); + const [itemIndex, setItemIndex] = useState(0); + const [direction, setDirection] = useState(0); - const currentItem = data?.[itemIndex]; + const currentItem = data?.[itemIndex]; - const handleNext = (e: MouseEvent) => { - e.preventDefault(); - setDirection(1); - if (itemIndex === (data?.length || 0) - 1 || 0) { - setItemIndex(0); - return; - } + const handleNext = (e: MouseEvent) => { + e.preventDefault(); + setDirection(1); + if (itemIndex === (data?.length || 0) - 1 || 0) { + setItemIndex(0); + return; + } - setItemIndex((prev) => prev + 1); - }; + setItemIndex((prev) => prev + 1); + }; - const handlePrevious = (e: MouseEvent) => { - e.preventDefault(); - setDirection(-1); - if (itemIndex === 0) { - setItemIndex((data?.length || 0) - 1); - return; - } + const handlePrevious = (e: MouseEvent) => { + e.preventDefault(); + setDirection(-1); + if (itemIndex === 0) { + setItemIndex((data?.length || 0) - 1); + return; + } - setItemIndex((prev) => prev - 1); - }; + setItemIndex((prev) => prev - 1); + }; - return ( - - - {data && ( - - - - - - - - - + + {data && ( + - {currentItem?.name} - - - - {currentItem?.albumArtists.slice(0, 1).map((artist) => ( - - {artist.name} - - ))} - - - {currentItem?.genres?.slice(0, 1).map((genre) => ( - - {genre.name} - - ))} - {currentItem?.releaseYear} - {currentItem?.songCount} tracks - - - - - - - - - - - - - - - )} - - - ); + handlePlayQueueAdd?.({ + byItemType: { + id: [currentItem.id], + type: LibraryItem.ALBUM, + }, + playType: Play.NOW, + }); + }} + > + Play + + + + + + + + + + + + + )} + + + ); }; diff --git a/src/renderer/components/grid-carousel/index.tsx b/src/renderer/components/grid-carousel/index.tsx index aac71bf5..32935f54 100644 --- a/src/renderer/components/grid-carousel/index.tsx +++ b/src/renderer/components/grid-carousel/index.tsx @@ -17,262 +17,267 @@ import { usePlayButtonBehavior } from '/@/renderer/store'; import { CardRoute, CardRow } from '/@/renderer/types'; const getSlidesPerView = (windowWidth: number) => { - if (windowWidth < 400) return 2; - if (windowWidth < 700) return 3; - if (windowWidth < 900) return 4; - if (windowWidth < 1100) return 5; - if (windowWidth < 1300) return 6; - if (windowWidth < 1500) return 7; - if (windowWidth < 1920) return 8; - return 10; + if (windowWidth < 400) return 2; + if (windowWidth < 700) return 3; + if (windowWidth < 900) return 4; + if (windowWidth < 1100) return 5; + if (windowWidth < 1300) return 6; + if (windowWidth < 1500) return 7; + if (windowWidth < 1920) return 8; + return 10; }; const CarouselContainer = styled(Stack)` - container-type: inline-size; + container-type: inline-size; `; interface TitleProps { - handleNext?: () => void; - handlePrev?: () => void; - label?: string | ReactNode; - pagination: { - hasNextPage: boolean; - hasPreviousPage: boolean; - }; + handleNext?: () => void; + handlePrev?: () => void; + label?: string | ReactNode; + pagination: { + hasNextPage: boolean; + hasPreviousPage: boolean; + }; } const Title = ({ label, handleNext, handlePrev, pagination }: TitleProps) => { - return ( - - {isValidElement(label) ? ( - label - ) : ( - - {label} - - )} + return ( + + {isValidElement(label) ? ( + label + ) : ( + + {label} + + )} - - - - - - ); + + + + + + ); }; interface SwiperGridCarouselProps { - cardRows: CardRow[] | CardRow[] | CardRow[]; - data: Album[] | AlbumArtist[] | Artist[] | RelatedArtist[] | undefined; - isLoading?: boolean; - itemType: LibraryItem; - route: CardRoute; - swiperProps?: SwiperOptions; - title?: { - children?: ReactNode; - hasPagination?: boolean; - icon?: ReactNode; - label: string | ReactNode; - }; - uniqueId: string; + cardRows: CardRow[] | CardRow[] | CardRow[]; + data: Album[] | AlbumArtist[] | Artist[] | RelatedArtist[] | undefined; + isLoading?: boolean; + itemType: LibraryItem; + route: CardRoute; + swiperProps?: SwiperOptions; + title?: { + children?: ReactNode; + hasPagination?: boolean; + icon?: ReactNode; + label: string | ReactNode; + }; + uniqueId: string; } export const SwiperGridCarousel = ({ - cardRows, - data, - itemType, - route, - swiperProps, - title, - isLoading, - uniqueId, -}: SwiperGridCarouselProps) => { - const swiperRef = useRef(null); - const playButtonBehavior = usePlayButtonBehavior(); - const handlePlayQueueAdd = usePlayQueueAdd(); - - const [pagination, setPagination] = useState({ - hasNextPage: (data?.length || 0) > Math.round(3), - hasPreviousPage: false, - }); - - const createFavoriteMutation = useCreateFavorite({}); - const deleteFavoriteMutation = useDeleteFavorite({}); - - const handleFavorite = useCallback( - (options: { id: string[]; isFavorite: boolean; itemType: LibraryItem; serverId: string }) => { - const { id, itemType, isFavorite, serverId } = options; - if (isFavorite) { - deleteFavoriteMutation.mutate({ - query: { - id, - type: itemType, - }, - serverId, - }); - } else { - createFavoriteMutation.mutate({ - query: { - id, - type: itemType, - }, - serverId, - }); - } - }, - [createFavoriteMutation, deleteFavoriteMutation], - ); - - const slides = useMemo(() => { - if (!data) return []; - - return data.map((el) => ( - - )); - }, [ cardRows, data, - handleFavorite, - handlePlayQueueAdd, - isLoading, itemType, - playButtonBehavior, route, + swiperProps, + title, + isLoading, uniqueId, - ]); +}: SwiperGridCarouselProps) => { + const swiperRef = useRef(null); + const playButtonBehavior = usePlayButtonBehavior(); + const handlePlayQueueAdd = usePlayQueueAdd(); - const handleNext = useCallback(() => { - const activeIndex = swiperRef?.current?.activeIndex || 0; - const slidesPerView = Math.round(Number(swiperProps?.slidesPerView || 4)); - swiperRef?.current?.slideTo(activeIndex + slidesPerView); - }, [swiperProps?.slidesPerView]); - - const handlePrev = useCallback(() => { - const activeIndex = swiperRef?.current?.activeIndex || 0; - const slidesPerView = Math.round(Number(swiperProps?.slidesPerView || 4)); - swiperRef?.current?.slideTo(activeIndex - slidesPerView); - }, [swiperProps?.slidesPerView]); - - const handleOnSlideChange = useCallback((e: SwiperCore) => { - const { slides, isEnd, isBeginning, params } = e; - if (isEnd || isBeginning) return; - - setPagination({ - hasNextPage: (params?.slidesPerView || 4) < slides.length, - hasPreviousPage: (params?.slidesPerView || 4) < slides.length, + const [pagination, setPagination] = useState({ + hasNextPage: (data?.length || 0) > Math.round(3), + hasPreviousPage: false, }); - }, []); - const handleOnZoomChange = useCallback((e: SwiperCore) => { - const { slides, isEnd, isBeginning, params } = e; - if (isEnd || isBeginning) return; + const createFavoriteMutation = useCreateFavorite({}); + const deleteFavoriteMutation = useDeleteFavorite({}); - setPagination({ - hasNextPage: (params.slidesPerView || 4) < slides.length, - hasPreviousPage: (params.slidesPerView || 4) < slides.length, - }); - }, []); + const handleFavorite = useCallback( + (options: { + id: string[]; + isFavorite: boolean; + itemType: LibraryItem; + serverId: string; + }) => { + const { id, itemType, isFavorite, serverId } = options; + if (isFavorite) { + deleteFavoriteMutation.mutate({ + query: { + id, + type: itemType, + }, + serverId, + }); + } else { + createFavoriteMutation.mutate({ + query: { + id, + type: itemType, + }, + serverId, + }); + } + }, + [createFavoriteMutation, deleteFavoriteMutation], + ); - const handleOnReachEnd = useCallback((e: SwiperCore) => { - const { slides, params } = e; + const slides = useMemo(() => { + if (!data) return []; - setPagination({ - hasNextPage: false, - hasPreviousPage: (params.slidesPerView || 4) < slides.length, - }); - }, []); + return data.map((el) => ( + + )); + }, [ + cardRows, + data, + handleFavorite, + handlePlayQueueAdd, + isLoading, + itemType, + playButtonBehavior, + route, + uniqueId, + ]); - const handleOnReachBeginning = useCallback((e: SwiperCore) => { - const { slides, params } = e; + const handleNext = useCallback(() => { + const activeIndex = swiperRef?.current?.activeIndex || 0; + const slidesPerView = Math.round(Number(swiperProps?.slidesPerView || 4)); + swiperRef?.current?.slideTo(activeIndex + slidesPerView); + }, [swiperProps?.slidesPerView]); - setPagination({ - hasNextPage: (params.slidesPerView || 4) < slides.length, - hasPreviousPage: false, - }); - }, []); + const handlePrev = useCallback(() => { + const activeIndex = swiperRef?.current?.activeIndex || 0; + const slidesPerView = Math.round(Number(swiperProps?.slidesPerView || 4)); + swiperRef?.current?.slideTo(activeIndex - slidesPerView); + }, [swiperProps?.slidesPerView]); - const handleOnResize = useCallback((e: SwiperCore) => { - if (!e) return; - const { width } = e; - const slidesPerView = getSlidesPerView(width); - if (!e.params) return; - e.params.slidesPerView = slidesPerView; - }, []); + const handleOnSlideChange = useCallback((e: SwiperCore) => { + const { slides, isEnd, isBeginning, params } = e; + if (isEnd || isBeginning) return; - const throttledOnResize = throttle(handleOnResize, 200); + setPagination({ + hasNextPage: (params?.slidesPerView || 4) < slides.length, + hasPreviousPage: (params?.slidesPerView || 4) < slides.length, + }); + }, []); - return ( - - {title ? ( - - ) : null} - <Swiper - ref={swiperRef} - resizeObserver - modules={[Virtual]} - slidesPerView={4} - spaceBetween={20} - style={{ height: '100%', width: '100%' }} - onBeforeInit={(swiper) => { - swiperRef.current = swiper; - }} - onBeforeResize={handleOnResize} - onReachBeginning={handleOnReachBeginning} - onReachEnd={handleOnReachEnd} - onResize={throttledOnResize} - onSlideChange={handleOnSlideChange} - onZoomChange={handleOnZoomChange} - {...swiperProps} - > - {slides.map((slideContent, index) => { - return ( - <SwiperSlide - key={`${uniqueId}-${slideContent?.props?.data?.id}-${index}`} - virtualIndex={index} + const handleOnZoomChange = useCallback((e: SwiperCore) => { + const { slides, isEnd, isBeginning, params } = e; + if (isEnd || isBeginning) return; + + setPagination({ + hasNextPage: (params.slidesPerView || 4) < slides.length, + hasPreviousPage: (params.slidesPerView || 4) < slides.length, + }); + }, []); + + const handleOnReachEnd = useCallback((e: SwiperCore) => { + const { slides, params } = e; + + setPagination({ + hasNextPage: false, + hasPreviousPage: (params.slidesPerView || 4) < slides.length, + }); + }, []); + + const handleOnReachBeginning = useCallback((e: SwiperCore) => { + const { slides, params } = e; + + setPagination({ + hasNextPage: (params.slidesPerView || 4) < slides.length, + hasPreviousPage: false, + }); + }, []); + + const handleOnResize = useCallback((e: SwiperCore) => { + if (!e) return; + const { width } = e; + const slidesPerView = getSlidesPerView(width); + if (!e.params) return; + e.params.slidesPerView = slidesPerView; + }, []); + + const throttledOnResize = throttle(handleOnResize, 200); + + return ( + <CarouselContainer + className="grid-carousel" + spacing="md" + > + {title ? ( + <Title + {...title} + handleNext={handleNext} + handlePrev={handlePrev} + pagination={pagination} + /> + ) : null} + <Swiper + ref={swiperRef} + resizeObserver + modules={[Virtual]} + slidesPerView={4} + spaceBetween={20} + style={{ height: '100%', width: '100%' }} + onBeforeInit={(swiper) => { + swiperRef.current = swiper; + }} + onBeforeResize={handleOnResize} + onReachBeginning={handleOnReachBeginning} + onReachEnd={handleOnReachEnd} + onResize={throttledOnResize} + onSlideChange={handleOnSlideChange} + onZoomChange={handleOnZoomChange} + {...swiperProps} > - {slideContent} - </SwiperSlide> - ); - })} - </Swiper> - </CarouselContainer> - ); + {slides.map((slideContent, index) => { + return ( + <SwiperSlide + key={`${uniqueId}-${slideContent?.props?.data?.id}-${index}`} + virtualIndex={index} + > + {slideContent} + </SwiperSlide> + ); + })} + </Swiper> + </CarouselContainer> + ); }; diff --git a/src/renderer/components/hover-card/index.tsx b/src/renderer/components/hover-card/index.tsx index 1d5459c5..7de932b7 100644 --- a/src/renderer/components/hover-card/index.tsx +++ b/src/renderer/components/hover-card/index.tsx @@ -1,23 +1,23 @@ import { HoverCard as MantineHoverCard, HoverCardProps } from '@mantine/core'; export const HoverCard = ({ children, ...props }: HoverCardProps) => { - return ( - <MantineHoverCard - styles={{ - dropdown: { - background: 'var(--dropdown-menu-bg)', - border: 'none', - borderRadius: 'var(--dropdown-menu-border-radius)', - boxShadow: '2px 2px 10px 2px rgba(0, 0, 0, 40%)', - margin: 0, - padding: 0, - }, - }} - {...props} - > - {children} - </MantineHoverCard> - ); + return ( + <MantineHoverCard + styles={{ + dropdown: { + background: 'var(--dropdown-menu-bg)', + border: 'none', + borderRadius: 'var(--dropdown-menu-border-radius)', + boxShadow: '2px 2px 10px 2px rgba(0, 0, 0, 40%)', + margin: 0, + padding: 0, + }, + }} + {...props} + > + {children} + </MantineHoverCard> + ); }; HoverCard.Target = MantineHoverCard.Target; diff --git a/src/renderer/components/input/index.tsx b/src/renderer/components/input/index.tsx index 6a8f63cd..94e1d1e1 100644 --- a/src/renderer/components/input/index.tsx +++ b/src/renderer/components/input/index.tsx @@ -1,404 +1,404 @@ import React, { forwardRef } from 'react'; import type { - TextInputProps as MantineTextInputProps, - NumberInputProps as MantineNumberInputProps, - PasswordInputProps as MantinePasswordInputProps, - FileInputProps as MantineFileInputProps, - JsonInputProps as MantineJsonInputProps, - TextareaProps as MantineTextareaProps, + TextInputProps as MantineTextInputProps, + NumberInputProps as MantineNumberInputProps, + PasswordInputProps as MantinePasswordInputProps, + FileInputProps as MantineFileInputProps, + JsonInputProps as MantineJsonInputProps, + TextareaProps as MantineTextareaProps, } from '@mantine/core'; import { - TextInput as MantineTextInput, - NumberInput as MantineNumberInput, - PasswordInput as MantinePasswordInput, - FileInput as MantineFileInput, - JsonInput as MantineJsonInput, - Textarea as MantineTextarea, + TextInput as MantineTextInput, + NumberInput as MantineNumberInput, + PasswordInput as MantinePasswordInput, + FileInput as MantineFileInput, + JsonInput as MantineJsonInput, + Textarea as MantineTextarea, } from '@mantine/core'; import styled from 'styled-components'; interface TextInputProps extends MantineTextInputProps { - children?: React.ReactNode; - maxWidth?: number | string; - width?: number | string; + children?: React.ReactNode; + maxWidth?: number | string; + width?: number | string; } interface NumberInputProps extends MantineNumberInputProps { - children?: React.ReactNode; - maxWidth?: number | string; - width?: number | string; + children?: React.ReactNode; + maxWidth?: number | string; + width?: number | string; } interface PasswordInputProps extends MantinePasswordInputProps { - children?: React.ReactNode; - maxWidth?: number | string; - width?: number | string; + children?: React.ReactNode; + maxWidth?: number | string; + width?: number | string; } interface FileInputProps extends MantineFileInputProps { - children?: React.ReactNode; - maxWidth?: number | string; - width?: number | string; + children?: React.ReactNode; + maxWidth?: number | string; + width?: number | string; } interface JsonInputProps extends MantineJsonInputProps { - children?: React.ReactNode; - maxWidth?: number | string; - width?: number | string; + children?: React.ReactNode; + maxWidth?: number | string; + width?: number | string; } interface TextareaProps extends MantineTextareaProps { - children?: React.ReactNode; - maxWidth?: number | string; - width?: number | string; + children?: React.ReactNode; + maxWidth?: number | string; + width?: number | string; } const StyledTextInput = styled(MantineTextInput)<TextInputProps>` - & .mantine-TextInput-wrapper { - border-color: var(--primary-color); - } - - & .mantine-TextInput-input { - color: var(--input-fg); - background: var(--input-bg); - - &::placeholder { - color: var(--input-placeholder-fg); + & .mantine-TextInput-wrapper { + border-color: var(--primary-color); } - } - & .mantine-Input-icon { - color: var(--input-placeholder-fg); - } + & .mantine-TextInput-input { + color: var(--input-fg); + background: var(--input-bg); - & .mantine-TextInput-required { - color: var(--secondary-color); - } + &::placeholder { + color: var(--input-placeholder-fg); + } + } - & .mantine-TextInput-label { - margin-bottom: 0.5rem; - font-family: var(--label-font-family); - } + & .mantine-Input-icon { + color: var(--input-placeholder-fg); + } - & .mantine-TextInput-disabled { - opacity: 0.6; - } + & .mantine-TextInput-required { + color: var(--secondary-color); + } - & [data-disabled='true'] { - opacity: 0.6; - } + & .mantine-TextInput-label { + margin-bottom: 0.5rem; + font-family: var(--label-font-family); + } - transition: width 0.3s ease-in-out; + & .mantine-TextInput-disabled { + opacity: 0.6; + } + + & [data-disabled='true'] { + opacity: 0.6; + } + + transition: width 0.3s ease-in-out; `; const StyledNumberInput = styled(MantineNumberInput)<NumberInputProps>` - & .mantine-NumberInput-wrapper { - border-color: var(--primary-color); - } - - & .mantine-NumberInput-input { - color: var(--input-fg); - background: var(--input-bg); - - &::placeholder { - color: var(--input-placeholder-fg); + & .mantine-NumberInput-wrapper { + border-color: var(--primary-color); } - } - & .mantine-NumberInput-controlUp { - svg { - color: var(--btn-default-fg); - fill: var(--btn-default-fg); + & .mantine-NumberInput-input { + color: var(--input-fg); + background: var(--input-bg); + + &::placeholder { + color: var(--input-placeholder-fg); + } } - } - & .mantine-NumberInput-controlDown { - svg { - color: var(--btn-default-fg); - fill: var(--btn-default-fg); + & .mantine-NumberInput-controlUp { + svg { + color: var(--btn-default-fg); + fill: var(--btn-default-fg); + } } - } - & .mantine-Input-icon { - color: var(--input-placeholder-fg); - } + & .mantine-NumberInput-controlDown { + svg { + color: var(--btn-default-fg); + fill: var(--btn-default-fg); + } + } - & .mantine-NumberInput-required { - color: var(--secondary-color); - } + & .mantine-Input-icon { + color: var(--input-placeholder-fg); + } - & .mantine-NumberInput-label { - margin-bottom: 0.5rem; - font-family: var(--label-font-family); - } + & .mantine-NumberInput-required { + color: var(--secondary-color); + } - & .mantine-NumberInput-disabled { - opacity: 0.6; - } + & .mantine-NumberInput-label { + margin-bottom: 0.5rem; + font-family: var(--label-font-family); + } - & [data-disabled='true'] { - opacity: 0.6; - } + & .mantine-NumberInput-disabled { + opacity: 0.6; + } - transition: width 0.3s ease-in-out; + & [data-disabled='true'] { + opacity: 0.6; + } + + transition: width 0.3s ease-in-out; `; const StyledPasswordInput = styled(MantinePasswordInput)<PasswordInputProps>` - & .mantine-PasswordInput-input { - color: var(--input-fg); - background: var(--input-bg); + & .mantine-PasswordInput-input { + color: var(--input-fg); + background: var(--input-bg); - &::placeholder { - color: var(--input-placeholder-fg); + &::placeholder { + color: var(--input-placeholder-fg); + } } - } - & .mantine-PasswordInput-icon { - color: var(--input-placeholder-fg); - } + & .mantine-PasswordInput-icon { + color: var(--input-placeholder-fg); + } - & .mantine-PasswordInput-required { - color: var(--secondary-color); - } + & .mantine-PasswordInput-required { + color: var(--secondary-color); + } - & .mantine-PasswordInput-label { - margin-bottom: 0.5rem; - font-family: var(--label-font-family); - } + & .mantine-PasswordInput-label { + margin-bottom: 0.5rem; + font-family: var(--label-font-family); + } - & .mantine-PasswordInput-disabled { - opacity: 0.6; - } + & .mantine-PasswordInput-disabled { + opacity: 0.6; + } - & [data-disabled='true'] { - opacity: 0.6; - } + & [data-disabled='true'] { + opacity: 0.6; + } - transition: width 0.3s ease-in-out; + transition: width 0.3s ease-in-out; `; const StyledFileInput = styled(MantineFileInput)<FileInputProps>` - & .mantine-FileInput-input { - color: var(--input-fg); - background: var(--input-bg); + & .mantine-FileInput-input { + color: var(--input-fg); + background: var(--input-bg); - &::placeholder { - color: var(--input-placeholder-fg); + &::placeholder { + color: var(--input-placeholder-fg); + } } - } - & .mantine-FileInput-icon { - color: var(--input-placeholder-fg); - } + & .mantine-FileInput-icon { + color: var(--input-placeholder-fg); + } - & .mantine-FileInput-required { - color: var(--secondary-color); - } + & .mantine-FileInput-required { + color: var(--secondary-color); + } - & .mantine-FileInput-label { - margin-bottom: 0.5rem; - font-family: var(--label-font-family); - } + & .mantine-FileInput-label { + margin-bottom: 0.5rem; + font-family: var(--label-font-family); + } - & .mantine-FileInput-disabled { - opacity: 0.6; - } + & .mantine-FileInput-disabled { + opacity: 0.6; + } - & [data-disabled='true'] { - opacity: 0.6; - } + & [data-disabled='true'] { + opacity: 0.6; + } - transition: width 0.3s ease-in-out; + transition: width 0.3s ease-in-out; `; const StyledJsonInput = styled(MantineJsonInput)<JsonInputProps>` - & .mantine-JsonInput-input { - color: var(--input-fg); - background: var(--input-bg); + & .mantine-JsonInput-input { + color: var(--input-fg); + background: var(--input-bg); - &::placeholder { - color: var(--input-placeholder-fg); + &::placeholder { + color: var(--input-placeholder-fg); + } } - } - & .mantine-JsonInput-icon { - color: var(--input-placeholder-fg); - } + & .mantine-JsonInput-icon { + color: var(--input-placeholder-fg); + } - & .mantine-JsonInput-required { - color: var(--secondary-color); - } + & .mantine-JsonInput-required { + color: var(--secondary-color); + } - & .mantine-JsonInput-label { - margin-bottom: 0.5rem; - font-family: var(--label-font-family); - } + & .mantine-JsonInput-label { + margin-bottom: 0.5rem; + font-family: var(--label-font-family); + } - & .mantine-JsonInput-disabled { - opacity: 0.6; - } + & .mantine-JsonInput-disabled { + opacity: 0.6; + } - & [data-disabled='true'] { - opacity: 0.6; - } + & [data-disabled='true'] { + opacity: 0.6; + } - transition: width 0.3s ease-in-out; + transition: width 0.3s ease-in-out; `; const StyledTextarea = styled(MantineTextarea)<TextareaProps>` - & .mantine-Textarea-input { - color: var(--input-fg); - background: var(--input-bg); - } + & .mantine-Textarea-input { + color: var(--input-fg); + background: var(--input-bg); + } - & .mantine-Textarea-icon { - color: var(--input-placeholder-fg); - } + & .mantine-Textarea-icon { + color: var(--input-placeholder-fg); + } - & .mantine-Textarea-required { - color: var(--secondary-color); - } + & .mantine-Textarea-required { + color: var(--secondary-color); + } - & .mantine-Textarea-label { - margin-bottom: 0.5rem; - font-family: var(--label-font-family); - } + & .mantine-Textarea-label { + margin-bottom: 0.5rem; + font-family: var(--label-font-family); + } - & .mantine-Textarea-disabled { - opacity: 0.6; - } + & .mantine-Textarea-disabled { + opacity: 0.6; + } - & [data-disabled='true'] { - opacity: 0.6; - } + & [data-disabled='true'] { + opacity: 0.6; + } - transition: width 0.3s ease-in-out; + transition: width 0.3s ease-in-out; `; export const TextInput = forwardRef<HTMLInputElement, TextInputProps>( - ({ children, width, maxWidth, ...props }: TextInputProps, ref) => { - return ( - <StyledTextInput - ref={ref} - spellCheck={false} - {...props} - sx={{ maxWidth, width }} - > - {children} - </StyledTextInput> - ); - }, + ({ children, width, maxWidth, ...props }: TextInputProps, ref) => { + return ( + <StyledTextInput + ref={ref} + spellCheck={false} + {...props} + sx={{ maxWidth, width }} + > + {children} + </StyledTextInput> + ); + }, ); export const NumberInput = forwardRef<HTMLInputElement, NumberInputProps>( - ({ children, width, maxWidth, ...props }: NumberInputProps, ref) => { - return ( - <StyledNumberInput - ref={ref} - hideControls - spellCheck={false} - {...props} - sx={{ maxWidth, width }} - > - {children} - </StyledNumberInput> - ); - }, + ({ children, width, maxWidth, ...props }: NumberInputProps, ref) => { + return ( + <StyledNumberInput + ref={ref} + hideControls + spellCheck={false} + {...props} + sx={{ maxWidth, width }} + > + {children} + </StyledNumberInput> + ); + }, ); export const PasswordInput = forwardRef<HTMLInputElement, PasswordInputProps>( - ({ children, width, maxWidth, ...props }: PasswordInputProps, ref) => { - return ( - <StyledPasswordInput - ref={ref} - {...props} - sx={{ maxWidth, width }} - > - {children} - </StyledPasswordInput> - ); - }, + ({ children, width, maxWidth, ...props }: PasswordInputProps, ref) => { + return ( + <StyledPasswordInput + ref={ref} + {...props} + sx={{ maxWidth, width }} + > + {children} + </StyledPasswordInput> + ); + }, ); export const FileInput = forwardRef<HTMLButtonElement, FileInputProps>( - ({ children, width, maxWidth, ...props }: FileInputProps, ref) => { - return ( - <StyledFileInput - ref={ref} - {...props} - styles={{ - placeholder: { - color: 'var(--input-placeholder-fg)', - }, - }} - sx={{ maxWidth, width }} - > - {children} - </StyledFileInput> - ); - }, + ({ children, width, maxWidth, ...props }: FileInputProps, ref) => { + return ( + <StyledFileInput + ref={ref} + {...props} + styles={{ + placeholder: { + color: 'var(--input-placeholder-fg)', + }, + }} + sx={{ maxWidth, width }} + > + {children} + </StyledFileInput> + ); + }, ); export const JsonInput = forwardRef<HTMLTextAreaElement, JsonInputProps>( - ({ children, width, maxWidth, ...props }: JsonInputProps, ref) => { - return ( - <StyledJsonInput - ref={ref} - {...props} - sx={{ maxWidth, width }} - > - {children} - </StyledJsonInput> - ); - }, + ({ children, width, maxWidth, ...props }: JsonInputProps, ref) => { + return ( + <StyledJsonInput + ref={ref} + {...props} + sx={{ maxWidth, width }} + > + {children} + </StyledJsonInput> + ); + }, ); export const Textarea = forwardRef<HTMLTextAreaElement, TextareaProps>( - ({ children, width, maxWidth, ...props }: TextareaProps, ref) => { - return ( - <StyledTextarea - ref={ref} - {...props} - sx={{ maxWidth, width }} - > - {children} - </StyledTextarea> - ); - }, + ({ children, width, maxWidth, ...props }: TextareaProps, ref) => { + return ( + <StyledTextarea + ref={ref} + {...props} + sx={{ maxWidth, width }} + > + {children} + </StyledTextarea> + ); + }, ); TextInput.defaultProps = { - children: undefined, - maxWidth: undefined, - width: undefined, + children: undefined, + maxWidth: undefined, + width: undefined, }; NumberInput.defaultProps = { - children: undefined, - maxWidth: undefined, - width: undefined, + children: undefined, + maxWidth: undefined, + width: undefined, }; PasswordInput.defaultProps = { - children: undefined, - maxWidth: undefined, - width: undefined, + children: undefined, + maxWidth: undefined, + width: undefined, }; FileInput.defaultProps = { - children: undefined, - maxWidth: undefined, - width: undefined, + children: undefined, + maxWidth: undefined, + width: undefined, }; JsonInput.defaultProps = { - children: undefined, - maxWidth: undefined, - width: undefined, + children: undefined, + maxWidth: undefined, + width: undefined, }; Textarea.defaultProps = { - children: undefined, - maxWidth: undefined, - width: undefined, + children: undefined, + maxWidth: undefined, + width: undefined, }; diff --git a/src/renderer/components/modal/index.tsx b/src/renderer/components/modal/index.tsx index 97b80b27..2eae7bc7 100644 --- a/src/renderer/components/modal/index.tsx +++ b/src/renderer/components/modal/index.tsx @@ -1,99 +1,99 @@ import React, { ReactNode } from 'react'; import { - ModalProps as MantineModalProps, - Stack, - Modal as MantineModal, - Flex, - Group, + ModalProps as MantineModalProps, + Stack, + Modal as MantineModal, + Flex, + Group, } from '@mantine/core'; import { closeAllModals, ContextModalProps } from '@mantine/modals'; import { Button } from '/@/renderer/components/button'; export interface ModalProps extends Omit<MantineModalProps, 'onClose'> { - children?: ReactNode; - handlers: { - close: () => void; - open: () => void; - toggle: () => void; - }; + children?: ReactNode; + handlers: { + close: () => void; + open: () => void; + toggle: () => void; + }; } export const Modal = ({ children, handlers, ...rest }: ModalProps) => { - return ( - <MantineModal - {...rest} - onClose={handlers.close} - > - {children} - </MantineModal> - ); + return ( + <MantineModal + {...rest} + onClose={handlers.close} + > + {children} + </MantineModal> + ); }; export type ContextModalVars = { - context: ContextModalProps['context']; - id: ContextModalProps['id']; + context: ContextModalProps['context']; + id: ContextModalProps['id']; }; export const BaseContextModal = ({ - context, - id, - innerProps, + context, + id, + innerProps, }: ContextModalProps<{ - modalBody: (vars: ContextModalVars) => React.ReactNode; + modalBody: (vars: ContextModalVars) => React.ReactNode; }>) => <>{innerProps.modalBody({ context, id })}</>; Modal.defaultProps = { - children: undefined, + children: undefined, }; interface ConfirmModalProps { - children: ReactNode; - disabled?: boolean; - labels?: { - cancel?: string; - confirm?: string; - }; - loading?: boolean; - onCancel?: () => void; - onConfirm: () => void; + children: ReactNode; + disabled?: boolean; + labels?: { + cancel?: string; + confirm?: string; + }; + loading?: boolean; + onCancel?: () => void; + onConfirm: () => void; } export const ConfirmModal = ({ - loading, - disabled, - labels, - onCancel, - onConfirm, - children, + loading, + disabled, + labels, + onCancel, + onConfirm, + children, }: ConfirmModalProps) => { - const handleCancel = () => { - if (onCancel) { - onCancel(); - } else { - closeAllModals(); - } - }; + const handleCancel = () => { + if (onCancel) { + onCancel(); + } else { + closeAllModals(); + } + }; - return ( - <Stack> - <Flex>{children}</Flex> - <Group position="right"> - <Button - data-focus - variant="default" - onClick={handleCancel} - > - {labels?.cancel ? labels.cancel : 'Cancel'} - </Button> - <Button - disabled={disabled} - loading={loading} - variant="filled" - onClick={onConfirm} - > - {labels?.confirm ? labels.confirm : 'Confirm'} - </Button> - </Group> - </Stack> - ); + return ( + <Stack> + <Flex>{children}</Flex> + <Group position="right"> + <Button + data-focus + variant="default" + onClick={handleCancel} + > + {labels?.cancel ? labels.cancel : 'Cancel'} + </Button> + <Button + disabled={disabled} + loading={loading} + variant="filled" + onClick={onConfirm} + > + {labels?.confirm ? labels.confirm : 'Confirm'} + </Button> + </Group> + </Stack> + ); }; diff --git a/src/renderer/components/option/index.tsx b/src/renderer/components/option/index.tsx index a4e90b5b..cf814a90 100644 --- a/src/renderer/components/option/index.tsx +++ b/src/renderer/components/option/index.tsx @@ -2,30 +2,30 @@ import { ReactNode } from 'react'; import { Flex, Group } from '@mantine/core'; export const Option = ({ children }: any) => { - return ( - <Group - grow - p="0.5rem" - > - {children} - </Group> - ); + return ( + <Group + grow + p="0.5rem" + > + {children} + </Group> + ); }; interface LabelProps { - children: ReactNode; + children: ReactNode; } const Label = ({ children }: LabelProps) => { - return <Flex align="flex-start">{children}</Flex>; + return <Flex align="flex-start">{children}</Flex>; }; interface ControlProps { - children: ReactNode; + children: ReactNode; } const Control = ({ children }: ControlProps) => { - return <Flex justify="flex-end">{children}</Flex>; + return <Flex justify="flex-end">{children}</Flex>; }; Option.Label = Label; diff --git a/src/renderer/components/page-header/index.tsx b/src/renderer/components/page-header/index.tsx index 2cc6c0b2..a31d7c4a 100644 --- a/src/renderer/components/page-header/index.tsx +++ b/src/renderer/components/page-header/index.tsx @@ -7,127 +7,127 @@ import { useWindowSettings } from '/@/renderer/store/settings.store'; import { Platform } from '/@/renderer/types'; const Container = styled(motion(Flex))<{ - height?: string; - position?: string; + height?: string; + position?: string; }>` - position: ${(props) => props.position || 'relative'}; - z-index: 2000; - width: 100%; - height: ${(props) => props.height || '65px'}; - background: var(--titlebar-bg); + position: ${(props) => props.position || 'relative'}; + z-index: 2000; + width: 100%; + height: ${(props) => props.height || '65px'}; + background: var(--titlebar-bg); `; const Header = styled(motion.div)<{ - $isDraggable?: boolean; - $isHidden?: boolean; - $padRight?: boolean; + $isDraggable?: boolean; + $isHidden?: boolean; + $padRight?: boolean; }>` - position: relative; - z-index: 15; - width: 100%; - height: 100%; - margin-right: ${(props) => (props.$padRight ? '140px' : '1rem')}; - user-select: ${(props) => (props.$isHidden ? 'none' : 'auto')}; - pointer-events: ${(props) => (props.$isHidden ? 'none' : 'auto')}; - -webkit-app-region: ${(props) => props.$isDraggable && 'drag'}; + position: relative; + z-index: 15; + width: 100%; + height: 100%; + margin-right: ${(props) => (props.$padRight ? '140px' : '1rem')}; + user-select: ${(props) => (props.$isHidden ? 'none' : 'auto')}; + pointer-events: ${(props) => (props.$isHidden ? 'none' : 'auto')}; + -webkit-app-region: ${(props) => props.$isDraggable && 'drag'}; - button { - -webkit-app-region: no-drag; - } + button { + -webkit-app-region: no-drag; + } - input { - -webkit-app-region: no-drag; - } + input { + -webkit-app-region: no-drag; + } `; const BackgroundImage = styled.div<{ background: string }>` - position: absolute; - top: 0; - z-index: 1; - width: 100%; - height: 100%; - background: ${(props) => props.background || 'var(--titlebar-bg)'}; + position: absolute; + top: 0; + z-index: 1; + width: 100%; + height: 100%; + background: ${(props) => props.background || 'var(--titlebar-bg)'}; `; const BackgroundImageOverlay = styled.div<{ theme: 'light' | 'dark' }>` - position: absolute; - top: 0; - left: 0; - z-index: 10; - width: 100%; - height: 100%; - background: ${(props) => - props.theme === 'light' - ? 'linear-gradient(rgba(255, 255, 255, 25%), rgba(255, 255, 255, 25%))' - : 'linear-gradient(rgba(0, 0, 0, 50%), rgba(0, 0, 0, 50%))'}; + position: absolute; + top: 0; + left: 0; + z-index: 10; + width: 100%; + height: 100%; + background: ${(props) => + props.theme === 'light' + ? 'linear-gradient(rgba(255, 255, 255, 25%), rgba(255, 255, 255, 25%))' + : 'linear-gradient(rgba(0, 0, 0, 50%), rgba(0, 0, 0, 50%))'}; `; export interface PageHeaderProps - extends Omit<FlexProps, 'onAnimationStart' | 'onDragStart' | 'onDragEnd' | 'onDrag'> { - backgroundColor?: string; - children?: React.ReactNode; - height?: string; - isHidden?: boolean; - position?: string; + extends Omit<FlexProps, 'onAnimationStart' | 'onDragStart' | 'onDragEnd' | 'onDrag'> { + backgroundColor?: string; + children?: React.ReactNode; + height?: string; + isHidden?: boolean; + position?: string; } const TitleWrapper = styled(motion.div)` - position: absolute; - display: flex; - width: 100%; - height: 100%; + position: absolute; + display: flex; + width: 100%; + height: 100%; `; const variants: Variants = { - animate: { opacity: 1 }, - exit: { opacity: 0 }, - initial: { opacity: 0 }, + animate: { opacity: 1 }, + exit: { opacity: 0 }, + initial: { opacity: 0 }, }; export const PageHeader = ({ - position, - height, - backgroundColor, - isHidden, - children, - ...props + position, + height, + backgroundColor, + isHidden, + children, + ...props }: PageHeaderProps) => { - const ref = useRef(null); - const padRight = useShouldPadTitlebar(); - const { windowBarStyle } = useWindowSettings(); - const theme = useTheme(); + const ref = useRef(null); + const padRight = useShouldPadTitlebar(); + const { windowBarStyle } = useWindowSettings(); + const theme = useTheme(); - return ( - <Container - ref={ref} - height={height} - position={position} - {...props} - > - <Header - $isDraggable={windowBarStyle === Platform.WEB} - $isHidden={isHidden} - $padRight={padRight} - > - <AnimatePresence initial={false}> - {!isHidden && ( - <TitleWrapper - animate="animate" - exit="exit" - initial="initial" - variants={variants} + return ( + <Container + ref={ref} + height={height} + position={position} + {...props} + > + <Header + $isDraggable={windowBarStyle === Platform.WEB} + $isHidden={isHidden} + $padRight={padRight} > - {children} - </TitleWrapper> - )} - </AnimatePresence> - </Header> - {backgroundColor && ( - <> - <BackgroundImage background={backgroundColor || 'var(--titlebar-bg)'} /> - <BackgroundImageOverlay theme={theme} /> - </> - )} - </Container> - ); + <AnimatePresence initial={false}> + {!isHidden && ( + <TitleWrapper + animate="animate" + exit="exit" + initial="initial" + variants={variants} + > + {children} + </TitleWrapper> + )} + </AnimatePresence> + </Header> + {backgroundColor && ( + <> + <BackgroundImage background={backgroundColor || 'var(--titlebar-bg)'} /> + <BackgroundImageOverlay theme={theme} /> + </> + )} + </Container> + ); }; diff --git a/src/renderer/components/pagination/index.tsx b/src/renderer/components/pagination/index.tsx index b01fa032..a5f5a980 100644 --- a/src/renderer/components/pagination/index.tsx +++ b/src/renderer/components/pagination/index.tsx @@ -1,52 +1,52 @@ import { - Pagination as MantinePagination, - PaginationProps as MantinePaginationProps, + Pagination as MantinePagination, + PaginationProps as MantinePaginationProps, } from '@mantine/core'; import styled from 'styled-components'; const StyledPagination = styled(MantinePagination)<PaginationProps>` - & .mantine-Pagination-item { - color: var(--btn-default-fg); - background-color: var(--btn-default-bg); - border: none; - transition: background 0.2s ease-in-out, color 0.2s ease-in-out; + & .mantine-Pagination-item { + color: var(--btn-default-fg); + background-color: var(--btn-default-bg); + border: none; + transition: background 0.2s ease-in-out, color 0.2s ease-in-out; - &[data-active] { - color: var(--btn-primary-fg); - background-color: var(--btn-primary-bg); + &[data-active] { + color: var(--btn-primary-fg); + background-color: var(--btn-primary-bg); + } + + &[data-dots] { + display: ${({ $hideDividers }) => ($hideDividers ? 'none' : 'block')}; + background-color: transparent; + } + + &:hover { + color: var(--btn-default-fg-hover); + background-color: var(--btn-default-bg-hover); + + &[data-active] { + color: var(--btn-primary-fg-hover); + background-color: var(--btn-primary-bg-hover); + } + + &[data-dots] { + background-color: transparent; + } + } } - - &[data-dots] { - display: ${({ $hideDividers }) => ($hideDividers ? 'none' : 'block')}; - background-color: transparent; - } - - &:hover { - color: var(--btn-default-fg-hover); - background-color: var(--btn-default-bg-hover); - - &[data-active] { - color: var(--btn-primary-fg-hover); - background-color: var(--btn-primary-bg-hover); - } - - &[data-dots] { - background-color: transparent; - } - } - } `; interface PaginationProps extends MantinePaginationProps { - $hideDividers?: boolean; + $hideDividers?: boolean; } export const Pagination = ({ $hideDividers, ...props }: PaginationProps) => { - return ( - <StyledPagination - $hideDividers={$hideDividers} - radius="xl" - {...props} - /> - ); + return ( + <StyledPagination + $hideDividers={$hideDividers} + radius="xl" + {...props} + /> + ); }; diff --git a/src/renderer/components/paper/index.tsx b/src/renderer/components/paper/index.tsx index b5504749..0c643cf1 100644 --- a/src/renderer/components/paper/index.tsx +++ b/src/renderer/components/paper/index.tsx @@ -3,13 +3,13 @@ import { Paper as MantinePaper } from '@mantine/core'; import styled from 'styled-components'; export interface PaperProps extends MantinePaperProps { - children: React.ReactNode; + children: React.ReactNode; } const StyledPaper = styled(MantinePaper)<PaperProps>` - background: var(--paper-bg); + background: var(--paper-bg); `; export const Paper = ({ children, ...props }: PaperProps) => { - return <StyledPaper {...props}>{children}</StyledPaper>; + return <StyledPaper {...props}>{children}</StyledPaper>; }; diff --git a/src/renderer/components/popover/index.tsx b/src/renderer/components/popover/index.tsx index f9b79d4d..f375267f 100644 --- a/src/renderer/components/popover/index.tsx +++ b/src/renderer/components/popover/index.tsx @@ -1,6 +1,6 @@ import type { - PopoverProps as MantinePopoverProps, - PopoverDropdownProps as MantinePopoverDropdownProps, + PopoverProps as MantinePopoverProps, + PopoverDropdownProps as MantinePopoverDropdownProps, } from '@mantine/core'; import { Popover as MantinePopover } from '@mantine/core'; import styled from 'styled-components'; @@ -11,28 +11,28 @@ type PopoverDropdownProps = MantinePopoverDropdownProps; const StyledPopover = styled(MantinePopover)``; const StyledDropdown = styled(MantinePopover.Dropdown)<PopoverDropdownProps>` - padding: 0.5rem; - font-size: 0.9em; - font-family: var(--content-font-family); - background-color: var(--dropdown-menu-bg); - border: var(--dropdown-menu-border); + padding: 0.5rem; + font-size: 0.9em; + font-family: var(--content-font-family); + background-color: var(--dropdown-menu-bg); + border: var(--dropdown-menu-border); `; export const Popover = ({ children, ...props }: PopoverProps) => { - return ( - <StyledPopover - withinPortal - styles={{ - dropdown: { - filter: 'drop-shadow(0 0 5px rgb(0, 0, 0, 50%))', - }, - }} - transitionProps={{ transition: 'fade' }} - {...props} - > - {children} - </StyledPopover> - ); + return ( + <StyledPopover + withinPortal + styles={{ + dropdown: { + filter: 'drop-shadow(0 0 5px rgb(0, 0, 0, 50%))', + }, + }} + transitionProps={{ transition: 'fade' }} + {...props} + > + {children} + </StyledPopover> + ); }; Popover.Target = MantinePopover.Target; diff --git a/src/renderer/components/query-builder/index.tsx b/src/renderer/components/query-builder/index.tsx index 5707e553..5332a9de 100644 --- a/src/renderer/components/query-builder/index.tsx +++ b/src/renderer/components/query-builder/index.tsx @@ -8,211 +8,211 @@ import { QueryBuilderOption } from '/@/renderer/components/query-builder/query-b import { QueryBuilderGroup, QueryBuilderRule } from '/@/renderer/types'; const FILTER_GROUP_OPTIONS_DATA = [ - { - label: 'Match all', - value: 'all', - }, - { - label: 'Match any', - value: 'any', - }, + { + label: 'Match all', + value: 'all', + }, + { + label: 'Match any', + value: 'any', + }, ]; type AddArgs = { - groupIndex: number[]; - level: number; + groupIndex: number[]; + level: number; }; type DeleteArgs = { - groupIndex: number[]; - level: number; - uniqueId: string; + groupIndex: number[]; + level: number; + uniqueId: string; }; interface QueryBuilderProps { - data: Record<string, any>; - filters: { label: string; type: string; value: string }[]; - groupIndex: number[]; - level: number; - onAddRule: (args: AddArgs) => void; - onAddRuleGroup: (args: AddArgs) => void; - onChangeField: (args: any) => void; - onChangeOperator: (args: any) => void; - onChangeType: (args: any) => void; - onChangeValue: (args: any) => void; - onClearFilters: () => void; - onDeleteRule: (args: DeleteArgs) => void; - onDeleteRuleGroup: (args: DeleteArgs) => void; - onResetFilters: () => void; - operators: { - boolean: { label: string; value: string }[]; - date: { label: string; value: string }[]; - number: { label: string; value: string }[]; - string: { label: string; value: string }[]; - }; - uniqueId: string; + data: Record<string, any>; + filters: { label: string; type: string; value: string }[]; + groupIndex: number[]; + level: number; + onAddRule: (args: AddArgs) => void; + onAddRuleGroup: (args: AddArgs) => void; + onChangeField: (args: any) => void; + onChangeOperator: (args: any) => void; + onChangeType: (args: any) => void; + onChangeValue: (args: any) => void; + onClearFilters: () => void; + onDeleteRule: (args: DeleteArgs) => void; + onDeleteRuleGroup: (args: DeleteArgs) => void; + onResetFilters: () => void; + operators: { + boolean: { label: string; value: string }[]; + date: { label: string; value: string }[]; + number: { label: string; value: string }[]; + string: { label: string; value: string }[]; + }; + uniqueId: string; } export const QueryBuilder = ({ - data, - level, - onAddRule, - onDeleteRuleGroup, - onDeleteRule, - onAddRuleGroup, - onChangeType, - onChangeField, - operators, - onChangeOperator, - onChangeValue, - onClearFilters, - onResetFilters, - groupIndex, - uniqueId, - filters, + data, + level, + onAddRule, + onDeleteRuleGroup, + onDeleteRule, + onAddRuleGroup, + onChangeType, + onChangeField, + operators, + onChangeOperator, + onChangeValue, + onClearFilters, + onResetFilters, + groupIndex, + uniqueId, + filters, }: QueryBuilderProps) => { - const handleAddRule = () => { - onAddRule({ groupIndex, level }); - }; + const handleAddRule = () => { + onAddRule({ groupIndex, level }); + }; - const handleAddRuleGroup = () => { - onAddRuleGroup({ groupIndex, level }); - }; + const handleAddRuleGroup = () => { + onAddRuleGroup({ groupIndex, level }); + }; - const handleDeleteRuleGroup = () => { - onDeleteRuleGroup({ groupIndex, level, uniqueId }); - }; + const handleDeleteRuleGroup = () => { + onDeleteRuleGroup({ groupIndex, level, uniqueId }); + }; - const handleChangeType = (value: string | null) => { - onChangeType({ groupIndex, level, value }); - }; + const handleChangeType = (value: string | null) => { + onChangeType({ groupIndex, level, value }); + }; - return ( - <Stack - ml={`${level * 10}px`} - spacing="sm" - > - <Group spacing="sm"> - <Select - data={FILTER_GROUP_OPTIONS_DATA} - maxWidth={175} - size="sm" - value={data.type} - width="20%" - onChange={handleChangeType} - /> - <Button - px={5} - size="sm" - tooltip={{ label: 'Add rule' }} - variant="default" - onClick={handleAddRule} + return ( + <Stack + ml={`${level * 10}px`} + spacing="sm" > - <RiAddLine size={20} /> - </Button> - <DropdownMenu position="bottom-start"> - <DropdownMenu.Target> - <Button - p={0} - size="sm" - variant="subtle" - > - <RiMore2Line size={20} /> - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - <DropdownMenu.Item - icon={<RiAddFill />} - onClick={handleAddRuleGroup} - > - Add rule group - </DropdownMenu.Item> + <Group spacing="sm"> + <Select + data={FILTER_GROUP_OPTIONS_DATA} + maxWidth={175} + size="sm" + value={data.type} + width="20%" + onChange={handleChangeType} + /> + <Button + px={5} + size="sm" + tooltip={{ label: 'Add rule' }} + variant="default" + onClick={handleAddRule} + > + <RiAddLine size={20} /> + </Button> + <DropdownMenu position="bottom-start"> + <DropdownMenu.Target> + <Button + p={0} + size="sm" + variant="subtle" + > + <RiMore2Line size={20} /> + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + <DropdownMenu.Item + icon={<RiAddFill />} + onClick={handleAddRuleGroup} + > + Add rule group + </DropdownMenu.Item> - {level > 0 && ( - <DropdownMenu.Item - icon={<RiDeleteBinFill />} - onClick={handleDeleteRuleGroup} - > - Remove rule group - </DropdownMenu.Item> + {level > 0 && ( + <DropdownMenu.Item + icon={<RiDeleteBinFill />} + onClick={handleDeleteRuleGroup} + > + Remove rule group + </DropdownMenu.Item> + )} + {level === 0 && ( + <> + <DropdownMenu.Divider /> + <DropdownMenu.Item + $danger + icon={<RiRestartLine color="var(--danger-color)" />} + onClick={onResetFilters} + > + Reset to default + </DropdownMenu.Item> + <DropdownMenu.Item + $danger + icon={<RiDeleteBinFill color="var(--danger-color)" />} + onClick={onClearFilters} + > + Clear filters + </DropdownMenu.Item> + </> + )} + </DropdownMenu.Dropdown> + </DropdownMenu> + </Group> + <AnimatePresence initial={false}> + {data?.rules?.map((rule: QueryBuilderRule) => ( + <motion.div + key={rule.uniqueId} + animate={{ opacity: 1, x: 0 }} + exit={{ opacity: 0, x: -25 }} + initial={{ opacity: 0, x: -25 }} + transition={{ duration: 0.2, ease: 'easeInOut' }} + > + <QueryBuilderOption + data={rule} + filters={filters} + groupIndex={groupIndex || []} + level={level} + noRemove={data?.rules?.length === 1} + operators={operators} + onChangeField={onChangeField} + onChangeOperator={onChangeOperator} + onChangeValue={onChangeValue} + onDeleteRule={onDeleteRule} + /> + </motion.div> + ))} + </AnimatePresence> + {data?.group && ( + <AnimatePresence initial={false}> + {data.group?.map((group: QueryBuilderGroup, index: number) => ( + <motion.div + key={group.uniqueId} + animate={{ opacity: 1, x: 0 }} + exit={{ opacity: 0, x: -25 }} + initial={{ opacity: 0, x: -25 }} + transition={{ duration: 0.2, ease: 'easeInOut' }} + > + <QueryBuilder + data={group} + filters={filters} + groupIndex={[...(groupIndex || []), index]} + level={level + 1} + operators={operators} + uniqueId={group.uniqueId} + onAddRule={onAddRule} + onAddRuleGroup={onAddRuleGroup} + onChangeField={onChangeField} + onChangeOperator={onChangeOperator} + onChangeType={onChangeType} + onChangeValue={onChangeValue} + onClearFilters={onClearFilters} + onDeleteRule={onDeleteRule} + onDeleteRuleGroup={onDeleteRuleGroup} + onResetFilters={onResetFilters} + /> + </motion.div> + ))} + </AnimatePresence> )} - {level === 0 && ( - <> - <DropdownMenu.Divider /> - <DropdownMenu.Item - $danger - icon={<RiRestartLine color="var(--danger-color)" />} - onClick={onResetFilters} - > - Reset to default - </DropdownMenu.Item> - <DropdownMenu.Item - $danger - icon={<RiDeleteBinFill color="var(--danger-color)" />} - onClick={onClearFilters} - > - Clear filters - </DropdownMenu.Item> - </> - )} - </DropdownMenu.Dropdown> - </DropdownMenu> - </Group> - <AnimatePresence initial={false}> - {data?.rules?.map((rule: QueryBuilderRule) => ( - <motion.div - key={rule.uniqueId} - animate={{ opacity: 1, x: 0 }} - exit={{ opacity: 0, x: -25 }} - initial={{ opacity: 0, x: -25 }} - transition={{ duration: 0.2, ease: 'easeInOut' }} - > - <QueryBuilderOption - data={rule} - filters={filters} - groupIndex={groupIndex || []} - level={level} - noRemove={data?.rules?.length === 1} - operators={operators} - onChangeField={onChangeField} - onChangeOperator={onChangeOperator} - onChangeValue={onChangeValue} - onDeleteRule={onDeleteRule} - /> - </motion.div> - ))} - </AnimatePresence> - {data?.group && ( - <AnimatePresence initial={false}> - {data.group?.map((group: QueryBuilderGroup, index: number) => ( - <motion.div - key={group.uniqueId} - animate={{ opacity: 1, x: 0 }} - exit={{ opacity: 0, x: -25 }} - initial={{ opacity: 0, x: -25 }} - transition={{ duration: 0.2, ease: 'easeInOut' }} - > - <QueryBuilder - data={group} - filters={filters} - groupIndex={[...(groupIndex || []), index]} - level={level + 1} - operators={operators} - uniqueId={group.uniqueId} - onAddRule={onAddRule} - onAddRuleGroup={onAddRuleGroup} - onChangeField={onChangeField} - onChangeOperator={onChangeOperator} - onChangeType={onChangeType} - onChangeValue={onChangeValue} - onClearFilters={onClearFilters} - onDeleteRule={onDeleteRule} - onDeleteRuleGroup={onDeleteRuleGroup} - onResetFilters={onResetFilters} - /> - </motion.div> - ))} - </AnimatePresence> - )} - </Stack> - ); + </Stack> + ); }; diff --git a/src/renderer/components/query-builder/query-builder-option.tsx b/src/renderer/components/query-builder/query-builder-option.tsx index ad3792c7..1a34f431 100644 --- a/src/renderer/components/query-builder/query-builder-option.tsx +++ b/src/renderer/components/query-builder/query-builder-option.tsx @@ -7,233 +7,233 @@ import { Select } from '/@/renderer/components/select'; import { QueryBuilderRule } from '/@/renderer/types'; type DeleteArgs = { - groupIndex: number[]; - level: number; - uniqueId: string; + groupIndex: number[]; + level: number; + uniqueId: string; }; interface QueryOptionProps { - data: QueryBuilderRule; - filters: { label: string; type: string; value: string }[]; - groupIndex: number[]; - level: number; - noRemove: boolean; - onChangeField: (args: any) => void; - onChangeOperator: (args: any) => void; - onChangeValue: (args: any) => void; - onDeleteRule: (args: DeleteArgs) => void; - operators: { - boolean: { label: string; value: string }[]; - date: { label: string; value: string }[]; - number: { label: string; value: string }[]; - string: { label: string; value: string }[]; - }; + data: QueryBuilderRule; + filters: { label: string; type: string; value: string }[]; + groupIndex: number[]; + level: number; + noRemove: boolean; + onChangeField: (args: any) => void; + onChangeOperator: (args: any) => void; + onChangeValue: (args: any) => void; + onDeleteRule: (args: DeleteArgs) => void; + operators: { + boolean: { label: string; value: string }[]; + date: { label: string; value: string }[]; + number: { label: string; value: string }[]; + string: { label: string; value: string }[]; + }; } const QueryValueInput = ({ onChange, type, ...props }: any) => { - const [numberRange, setNumberRange] = useState([0, 0]); + const [numberRange, setNumberRange] = useState([0, 0]); - switch (type) { - case 'string': - return ( - <TextInput - size="sm" - onChange={onChange} - {...props} - /> - ); - case 'number': - return ( - <NumberInput - size="sm" - onChange={onChange} - {...props} - defaultValue={props.defaultValue && Number(props.defaultValue)} - /> - ); - case 'date': - return ( - <TextInput - size="sm" - onChange={onChange} - {...props} - /> - ); + switch (type) { + case 'string': + return ( + <TextInput + size="sm" + onChange={onChange} + {...props} + /> + ); + case 'number': + return ( + <NumberInput + size="sm" + onChange={onChange} + {...props} + defaultValue={props.defaultValue && Number(props.defaultValue)} + /> + ); + case 'date': + return ( + <TextInput + size="sm" + onChange={onChange} + {...props} + /> + ); - case 'dateRange': - return ( - <> - <NumberInput - {...props} - defaultValue={props.defaultValue && Number(props.defaultValue?.[0])} - maxWidth={81} - width="10%" - onChange={(e) => { - const newRange = [e || 0, numberRange[1]]; - setNumberRange(newRange); - onChange(newRange); - }} - /> - <NumberInput - {...props} - defaultValue={props.defaultValue && Number(props.defaultValue?.[1])} - maxWidth={81} - width="10%" - onChange={(e) => { - const newRange = [numberRange[0], e || 0]; - setNumberRange(newRange); - onChange(newRange); - }} - /> - </> - ); + case 'dateRange': + return ( + <> + <NumberInput + {...props} + defaultValue={props.defaultValue && Number(props.defaultValue?.[0])} + maxWidth={81} + width="10%" + onChange={(e) => { + const newRange = [e || 0, numberRange[1]]; + setNumberRange(newRange); + onChange(newRange); + }} + /> + <NumberInput + {...props} + defaultValue={props.defaultValue && Number(props.defaultValue?.[1])} + maxWidth={81} + width="10%" + onChange={(e) => { + const newRange = [numberRange[0], e || 0]; + setNumberRange(newRange); + onChange(newRange); + }} + /> + </> + ); - case 'boolean': - return ( - <Select - data={[ - { label: 'true', value: 'true' }, - { label: 'false', value: 'false' }, - ]} - onChange={onChange} - {...props} - /> - ); + case 'boolean': + return ( + <Select + data={[ + { label: 'true', value: 'true' }, + { label: 'false', value: 'false' }, + ]} + onChange={onChange} + {...props} + /> + ); - default: - return <></>; - } + default: + return <></>; + } }; export const QueryBuilderOption = ({ - data, - filters, - level, - onDeleteRule, - operators, - groupIndex, - noRemove, - onChangeField, - onChangeOperator, - onChangeValue, + data, + filters, + level, + onDeleteRule, + operators, + groupIndex, + noRemove, + onChangeField, + onChangeOperator, + onChangeValue, }: QueryOptionProps) => { - const { field, operator, uniqueId, value } = data; + const { field, operator, uniqueId, value } = data; - const handleDeleteRule = () => { - onDeleteRule({ groupIndex, level, uniqueId }); - }; + const handleDeleteRule = () => { + onDeleteRule({ groupIndex, level, uniqueId }); + }; - const handleChangeField = (e: any) => { - onChangeField({ groupIndex, level, uniqueId, value: e }); - }; + const handleChangeField = (e: any) => { + onChangeField({ groupIndex, level, uniqueId, value: e }); + }; - const handleChangeOperator = (e: any) => { - onChangeOperator({ groupIndex, level, uniqueId, value: e }); - }; + const handleChangeOperator = (e: any) => { + onChangeOperator({ groupIndex, level, uniqueId, value: e }); + }; - const handleChangeValue = (e: any) => { - const isDirectValue = - typeof e === 'string' || - typeof e === 'number' || - typeof e === 'undefined' || - typeof e === null; + const handleChangeValue = (e: any) => { + const isDirectValue = + typeof e === 'string' || + typeof e === 'number' || + typeof e === 'undefined' || + typeof e === null; - if (isDirectValue) { - return onChangeValue({ - groupIndex, - level, - uniqueId, - value: e, - }); - } + if (isDirectValue) { + return onChangeValue({ + groupIndex, + level, + uniqueId, + value: e, + }); + } - // const isDate = e instanceof Date; + // const isDate = e instanceof Date; - // if (isDate) { - // return onChangeValue({ - // groupIndex, - // level, - // uniqueId, - // value: dayjs(e).format('YYYY-MM-DD'), - // }); - // } + // if (isDate) { + // return onChangeValue({ + // groupIndex, + // level, + // uniqueId, + // value: dayjs(e).format('YYYY-MM-DD'), + // }); + // } - const isArray = Array.isArray(e); + const isArray = Array.isArray(e); - if (isArray) { - return onChangeValue({ - groupIndex, - level, - uniqueId, - value: e, - }); - } + if (isArray) { + return onChangeValue({ + groupIndex, + level, + uniqueId, + value: e, + }); + } - return onChangeValue({ - groupIndex, - level, - uniqueId, - value: e.currentTarget.value, - }); - }; + return onChangeValue({ + groupIndex, + level, + uniqueId, + value: e.currentTarget.value, + }); + }; - const fieldType = filters.find((f) => f.value === field)?.type; - const operatorsByFieldType = operators[fieldType as keyof typeof operators]; - const ml = (level + 1) * 10; + const fieldType = filters.find((f) => f.value === field)?.type; + const operatorsByFieldType = operators[fieldType as keyof typeof operators]; + const ml = (level + 1) * 10; - return ( - <Group - ml={ml} - spacing="sm" - > - <Select - searchable - data={filters} - maxWidth={170} - size="sm" - value={field} - width="25%" - onChange={handleChangeField} - /> - <Select - searchable - data={operatorsByFieldType || []} - disabled={!field} - maxWidth={170} - size="sm" - value={operator} - width="25%" - onChange={handleChangeOperator} - /> - {field ? ( - <QueryValueInput - defaultValue={value} - maxWidth={170} - size="sm" - type={operator === 'inTheRange' ? 'dateRange' : fieldType} - width="25%" - onChange={handleChangeValue} - /> - ) : ( - <TextInput - disabled - defaultValue={value} - maxWidth={170} - size="sm" - width="25%" - onChange={handleChangeValue} - /> - )} - <Button - disabled={noRemove} - px={5} - size="sm" - tooltip={{ label: 'Remove rule' }} - variant="default" - onClick={handleDeleteRule} - > - <RiSubtractLine size={20} /> - </Button> - </Group> - ); + return ( + <Group + ml={ml} + spacing="sm" + > + <Select + searchable + data={filters} + maxWidth={170} + size="sm" + value={field} + width="25%" + onChange={handleChangeField} + /> + <Select + searchable + data={operatorsByFieldType || []} + disabled={!field} + maxWidth={170} + size="sm" + value={operator} + width="25%" + onChange={handleChangeOperator} + /> + {field ? ( + <QueryValueInput + defaultValue={value} + maxWidth={170} + size="sm" + type={operator === 'inTheRange' ? 'dateRange' : fieldType} + width="25%" + onChange={handleChangeValue} + /> + ) : ( + <TextInput + disabled + defaultValue={value} + maxWidth={170} + size="sm" + width="25%" + onChange={handleChangeValue} + /> + )} + <Button + disabled={noRemove} + px={5} + size="sm" + tooltip={{ label: 'Remove rule' }} + variant="default" + onClick={handleDeleteRule} + > + <RiSubtractLine size={20} /> + </Button> + </Group> + ); }; diff --git a/src/renderer/components/rating/index.tsx b/src/renderer/components/rating/index.tsx index 21a303d0..9f308a14 100644 --- a/src/renderer/components/rating/index.tsx +++ b/src/renderer/components/rating/index.tsx @@ -5,29 +5,29 @@ import styled from 'styled-components'; import { Tooltip } from '/@/renderer/components/tooltip'; interface RatingProps extends Omit<MantineRatingProps, 'onClick'> { - onClick: (e: MouseEvent<HTMLDivElement>, value: number | undefined) => void; + onClick: (e: MouseEvent<HTMLDivElement>, value: number | undefined) => void; } const StyledRating = styled(MantineRating)` - & .mantine-Rating-symbolBody { - svg { - stroke: var(--main-fg-secondary); + & .mantine-Rating-symbolBody { + svg { + stroke: var(--main-fg-secondary); + } } - } `; export const Rating = ({ onClick, ...props }: RatingProps) => { - // const debouncedOnClick = debounce(onClick, 100); + // const debouncedOnClick = debounce(onClick, 100); - return ( - <Tooltip - label="Double click to clear" - openDelay={1000} - > - <StyledRating - {...props} - onDoubleClick={(e) => onClick(e, props.value)} - /> - </Tooltip> - ); + return ( + <Tooltip + label="Double click to clear" + openDelay={1000} + > + <StyledRating + {...props} + onDoubleClick={(e) => onClick(e, props.value)} + /> + </Tooltip> + ); }; diff --git a/src/renderer/components/scroll-area/index.tsx b/src/renderer/components/scroll-area/index.tsx index 386645e5..dd35cfb3 100644 --- a/src/renderer/components/scroll-area/index.tsx +++ b/src/renderer/components/scroll-area/index.tsx @@ -9,169 +9,169 @@ import { useWindowSettings } from '/@/renderer/store/settings.store'; import { Platform } from '/@/renderer/types'; interface ScrollAreaProps extends MantineScrollAreaProps { - children: React.ReactNode; + children: React.ReactNode; } const StyledScrollArea = styled(MantineScrollArea)` - & .mantine-ScrollArea-thumb { - background: var(--scrollbar-thumb-bg); - border-radius: 0; - } + & .mantine-ScrollArea-thumb { + background: var(--scrollbar-thumb-bg); + border-radius: 0; + } - & .mantine-ScrollArea-scrollbar { - padding: 0; - background: var(--scrollbar-track-bg); - } + & .mantine-ScrollArea-scrollbar { + padding: 0; + background: var(--scrollbar-track-bg); + } - & .mantine-ScrollArea-viewport > div { - display: block !important; - } + & .mantine-ScrollArea-viewport > div { + display: block !important; + } `; const StyledNativeScrollArea = styled.div<{ scrollBarOffset?: string; windowBarStyle?: Platform }>` - height: 100%; - overflow-y: overlay !important; + height: 100%; + overflow-y: overlay !important; - &::-webkit-scrollbar-track { - margin-top: ${(props) => - props.windowBarStyle === Platform.WINDOWS || - props.windowBarStyle === Platform.MACOS || - props.windowBarStyle === Platform.LINUX - ? '0px' - : props.scrollBarOffset || '65px'}; - } + &::-webkit-scrollbar-track { + margin-top: ${(props) => + props.windowBarStyle === Platform.WINDOWS || + props.windowBarStyle === Platform.MACOS || + props.windowBarStyle === Platform.LINUX + ? '0px' + : props.scrollBarOffset || '65px'}; + } - &::-webkit-scrollbar-thumb { - margin-top: ${(props) => - props.windowBarStyle === Platform.WINDOWS || - props.windowBarStyle === Platform.MACOS || - props.windowBarStyle === Platform.LINUX - ? '0px' - : props.scrollBarOffset || '65px'}; - } + &::-webkit-scrollbar-thumb { + margin-top: ${(props) => + props.windowBarStyle === Platform.WINDOWS || + props.windowBarStyle === Platform.MACOS || + props.windowBarStyle === Platform.LINUX + ? '0px' + : props.scrollBarOffset || '65px'}; + } `; export const ScrollArea = forwardRef(({ children, ...props }: ScrollAreaProps, ref: Ref<any>) => { - return ( - <StyledScrollArea - ref={ref} - scrollbarSize={12} - {...props} - > - {children} - </StyledScrollArea> - ); + return ( + <StyledScrollArea + ref={ref} + scrollbarSize={12} + {...props} + > + {children} + </StyledScrollArea> + ); }); interface NativeScrollAreaProps { - children: React.ReactNode; - debugScrollPosition?: boolean; - noHeader?: boolean; - pageHeaderProps?: PageHeaderProps & { offset?: any; target?: any }; - scrollBarOffset?: string; - scrollHideDelay?: number; - style?: React.CSSProperties; + children: React.ReactNode; + debugScrollPosition?: boolean; + noHeader?: boolean; + pageHeaderProps?: PageHeaderProps & { offset?: any; target?: any }; + scrollBarOffset?: string; + scrollHideDelay?: number; + style?: React.CSSProperties; } export const NativeScrollArea = forwardRef( - ( - { - children, - pageHeaderProps, - debugScrollPosition, - scrollBarOffset, - scrollHideDelay, - noHeader, - ...props - }: NativeScrollAreaProps, - ref: Ref<HTMLDivElement>, - ) => { - const { windowBarStyle } = useWindowSettings(); - const [hideScrollbar, setHideScrollbar] = useState(false); - const [hideHeader, setHideHeader] = useState(true); - const { start, clear } = useTimeout( - () => setHideScrollbar(true), - scrollHideDelay !== undefined ? scrollHideDelay * 1000 : 0, - ); + ( + { + children, + pageHeaderProps, + debugScrollPosition, + scrollBarOffset, + scrollHideDelay, + noHeader, + ...props + }: NativeScrollAreaProps, + ref: Ref<HTMLDivElement>, + ) => { + const { windowBarStyle } = useWindowSettings(); + const [hideScrollbar, setHideScrollbar] = useState(false); + const [hideHeader, setHideHeader] = useState(true); + const { start, clear } = useTimeout( + () => setHideScrollbar(true), + scrollHideDelay !== undefined ? scrollHideDelay * 1000 : 0, + ); - const containerRef = useRef(null); - const mergedRef = useMergedRef(ref, containerRef); + const containerRef = useRef(null); + const mergedRef = useMergedRef(ref, containerRef); - const { scrollYProgress } = useScroll({ - container: containerRef, - offset: pageHeaderProps?.offset || ['center start', 'end start'], - target: pageHeaderProps?.target, - }); + const { scrollYProgress } = useScroll({ + container: containerRef, + offset: pageHeaderProps?.offset || ['center start', 'end start'], + target: pageHeaderProps?.target, + }); - // Automatically hide the scrollbar after the timeout duration - useEffect(() => { - start(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - - useEffect(() => { - const setHeaderVisibility = (v: number) => { - if (v === 1) { - return setHideHeader(false); - } - - if (hideHeader === false) { - return setHideHeader(true); - } - - return undefined; - }; - - const unsubscribe = scrollYProgress.on('change', setHeaderVisibility); - - return () => { - unsubscribe(); - }; - }, [hideHeader, scrollYProgress]); - - return ( - <> - {!noHeader && ( - <PageHeader - isHidden={hideHeader} - position="absolute" - style={{ opacity: scrollYProgress as any }} - {...pageHeaderProps} - /> - )} - <StyledNativeScrollArea - ref={mergedRef} - className={hideScrollbar ? 'hide-scrollbar' : undefined} - scrollBarOffset={scrollBarOffset} - windowBarStyle={windowBarStyle} - onMouseEnter={() => { - setHideScrollbar(false); - clear(); - }} - onMouseLeave={() => { + // Automatically hide the scrollbar after the timeout duration + useEffect(() => { start(); - }} - {...props} - > - {children} - </StyledNativeScrollArea> - {debugScrollPosition && ( - <motion.div - style={{ - background: 'red', - height: '10px', - left: 0, - position: 'fixed', - right: 0, - scaleX: scrollYProgress, - top: 0, - transformOrigin: '0%', - width: '100%', - zIndex: 5000, - }} - /> - )} - </> - ); - }, + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + useEffect(() => { + const setHeaderVisibility = (v: number) => { + if (v === 1) { + return setHideHeader(false); + } + + if (hideHeader === false) { + return setHideHeader(true); + } + + return undefined; + }; + + const unsubscribe = scrollYProgress.on('change', setHeaderVisibility); + + return () => { + unsubscribe(); + }; + }, [hideHeader, scrollYProgress]); + + return ( + <> + {!noHeader && ( + <PageHeader + isHidden={hideHeader} + position="absolute" + style={{ opacity: scrollYProgress as any }} + {...pageHeaderProps} + /> + )} + <StyledNativeScrollArea + ref={mergedRef} + className={hideScrollbar ? 'hide-scrollbar' : undefined} + scrollBarOffset={scrollBarOffset} + windowBarStyle={windowBarStyle} + onMouseEnter={() => { + setHideScrollbar(false); + clear(); + }} + onMouseLeave={() => { + start(); + }} + {...props} + > + {children} + </StyledNativeScrollArea> + {debugScrollPosition && ( + <motion.div + style={{ + background: 'red', + height: '10px', + left: 0, + position: 'fixed', + right: 0, + scaleX: scrollYProgress, + top: 0, + transformOrigin: '0%', + width: '100%', + zIndex: 5000, + }} + /> + )} + </> + ); + }, ); diff --git a/src/renderer/components/search-input/index.tsx b/src/renderer/components/search-input/index.tsx index 76f2b32b..45f728d6 100644 --- a/src/renderer/components/search-input/index.tsx +++ b/src/renderer/components/search-input/index.tsx @@ -7,64 +7,64 @@ import { useSettingsStore } from '/@/renderer/store'; import { shallow } from 'zustand/shallow'; interface SearchInputProps extends TextInputProps { - initialWidth?: number; - openedWidth?: number; - value?: string; + initialWidth?: number; + openedWidth?: number; + value?: string; } export const SearchInput = ({ - initialWidth, - onChange, - openedWidth, - ...props + initialWidth, + onChange, + openedWidth, + ...props }: SearchInputProps) => { - const { ref, focused } = useFocusWithin(); - const mergedRef = useMergedRef<HTMLInputElement>(ref); - const binding = useSettingsStore((state) => state.hotkeys.bindings.localSearch, shallow); + const { ref, focused } = useFocusWithin(); + const mergedRef = useMergedRef<HTMLInputElement>(ref); + const binding = useSettingsStore((state) => state.hotkeys.bindings.localSearch, shallow); - const isOpened = focused || ref.current?.value; - const showIcon = !isOpened || (openedWidth || 100) > 100; + const isOpened = focused || ref.current?.value; + const showIcon = !isOpened || (openedWidth || 100) > 100; - useHotkeys([[binding.hotkey, () => ref.current.select()]]); + useHotkeys([[binding.hotkey, () => ref.current.select()]]); - const handleEscape = (e: KeyboardEvent<HTMLInputElement>) => { - if (e.code === 'Escape') { - onChange?.({ target: { value: '' } } as ChangeEvent<HTMLInputElement>); - ref.current.value = ''; - ref.current.blur(); - } - }; + const handleEscape = (e: KeyboardEvent<HTMLInputElement>) => { + if (e.code === 'Escape') { + onChange?.({ target: { value: '' } } as ChangeEvent<HTMLInputElement>); + ref.current.value = ''; + ref.current.blur(); + } + }; - return ( - <TextInput - ref={mergedRef} - {...props} - icon={showIcon && <RiSearchLine />} - rightSection={ - isOpened ? ( - <ActionIcon - onClick={() => { - ref.current.value = ''; - ref.current.focus(); + return ( + <TextInput + ref={mergedRef} + {...props} + icon={showIcon && <RiSearchLine />} + rightSection={ + isOpened ? ( + <ActionIcon + onClick={() => { + ref.current.value = ''; + ref.current.focus(); + }} + > + <RiCloseFill /> + </ActionIcon> + ) : null + } + size="md" + styles={{ + icon: { svg: { fill: 'var(--titlebar-fg)' } }, + input: { + backgroundColor: isOpened ? 'inherit' : 'transparent !important', + border: 'none !important', + cursor: isOpened ? 'text' : 'pointer', + padding: isOpened ? '10px' : 0, + }, }} - > - <RiCloseFill /> - </ActionIcon> - ) : null - } - size="md" - styles={{ - icon: { svg: { fill: 'var(--titlebar-fg)' } }, - input: { - backgroundColor: isOpened ? 'inherit' : 'transparent !important', - border: 'none !important', - cursor: isOpened ? 'text' : 'pointer', - padding: isOpened ? '10px' : 0, - }, - }} - width={isOpened ? openedWidth || 150 : initialWidth || 35} - onChange={onChange} - onKeyDown={handleEscape} - /> - ); + width={isOpened ? openedWidth || 150 : initialWidth || 35} + onChange={onChange} + onKeyDown={handleEscape} + /> + ); }; diff --git a/src/renderer/components/segmented-control/index.tsx b/src/renderer/components/segmented-control/index.tsx index fa426614..de3f8e1f 100644 --- a/src/renderer/components/segmented-control/index.tsx +++ b/src/renderer/components/segmented-control/index.tsx @@ -6,37 +6,37 @@ import styled from 'styled-components'; type SegmentedControlProps = MantineSegmentedControlProps; const StyledSegmentedControl = styled(MantineSegmentedControl)<MantineSegmentedControlProps>` - & .mantine-SegmentedControl-label { - color: var(--input-fg); - font-family: var(--content-font-family); - } + & .mantine-SegmentedControl-label { + color: var(--input-fg); + font-family: var(--content-font-family); + } - background-color: var(--input-bg); + background-color: var(--input-bg); - & .mantine-SegmentedControl-disabled { - opacity: 0.6; - } + & .mantine-SegmentedControl-disabled { + opacity: 0.6; + } - & [data-disabled='true'] { - opacity: 0.6; - } + & [data-disabled='true'] { + opacity: 0.6; + } - & .mantine-SegmentedControl-active { - color: var(--input-active-fg); - background-color: var(--input-active-bg); - } + & .mantine-SegmentedControl-active { + color: var(--input-active-fg); + background-color: var(--input-active-bg); + } `; export const SegmentedControl = forwardRef<HTMLDivElement, SegmentedControlProps>( - ({ ...props }: SegmentedControlProps, ref) => { - return ( - <StyledSegmentedControl - ref={ref} - styles={{}} - transitionDuration={250} - transitionTimingFunction="linear" - {...props} - /> - ); - }, + ({ ...props }: SegmentedControlProps, ref) => { + return ( + <StyledSegmentedControl + ref={ref} + styles={{}} + transitionDuration={250} + transitionTimingFunction="linear" + {...props} + /> + ); + }, ); diff --git a/src/renderer/components/select/index.tsx b/src/renderer/components/select/index.tsx index d887326c..9890cae8 100644 --- a/src/renderer/components/select/index.tsx +++ b/src/renderer/components/select/index.tsx @@ -1,142 +1,142 @@ import type { - SelectProps as MantineSelectProps, - MultiSelectProps as MantineMultiSelectProps, + SelectProps as MantineSelectProps, + MultiSelectProps as MantineMultiSelectProps, } from '@mantine/core'; import { Select as MantineSelect, MultiSelect as MantineMultiSelect } from '@mantine/core'; import styled from 'styled-components'; interface SelectProps extends MantineSelectProps { - maxWidth?: number | string; - width?: number | string; + maxWidth?: number | string; + width?: number | string; } export interface MultiSelectProps extends MantineMultiSelectProps { - maxWidth?: number | string; - width?: number | string; + maxWidth?: number | string; + width?: number | string; } const StyledSelect = styled(MantineSelect)` - & [data-selected='true'] { - background: var(--input-bg); - } - - & [data-disabled='true'] { - background: var(--input-bg); - opacity: 0.6; - } - - & .mantine-Select-itemsWrapper { - & .mantine-Select-item { - padding: 40px; + & [data-selected='true'] { + background: var(--input-bg); + } + + & [data-disabled='true'] { + background: var(--input-bg); + opacity: 0.6; + } + + & .mantine-Select-itemsWrapper { + & .mantine-Select-item { + padding: 40px; + } } - } `; export const Select = ({ width, maxWidth, ...props }: SelectProps) => { - return ( - <StyledSelect - withinPortal - styles={{ - dropdown: { - background: 'var(--dropdown-menu-bg)', - filter: 'drop-shadow(0 0 5px rgb(0, 0, 0, 20%))', - }, - input: { - background: 'var(--input-bg)', - color: 'var(--input-fg)', - }, - item: { - '&:hover': { - background: 'var(--dropdown-menu-bg-hover)', - }, - '&[data-hovered]': { - background: 'var(--dropdown-menu-bg-hover)', - }, - '&[data-selected="true"]': { - '&:hover': { - background: 'var(--dropdown-menu-bg-hover)', - }, - background: 'none', - color: 'var(--primary-color)', - }, - color: 'var(--dropdown-menu-fg)', - padding: '.3rem', - }, - }} - sx={{ maxWidth, width }} - transitionProps={{ duration: 100, transition: 'fade' }} - {...props} - /> - ); + return ( + <StyledSelect + withinPortal + styles={{ + dropdown: { + background: 'var(--dropdown-menu-bg)', + filter: 'drop-shadow(0 0 5px rgb(0, 0, 0, 20%))', + }, + input: { + background: 'var(--input-bg)', + color: 'var(--input-fg)', + }, + item: { + '&:hover': { + background: 'var(--dropdown-menu-bg-hover)', + }, + '&[data-hovered]': { + background: 'var(--dropdown-menu-bg-hover)', + }, + '&[data-selected="true"]': { + '&:hover': { + background: 'var(--dropdown-menu-bg-hover)', + }, + background: 'none', + color: 'var(--primary-color)', + }, + color: 'var(--dropdown-menu-fg)', + padding: '.3rem', + }, + }} + sx={{ maxWidth, width }} + transitionProps={{ duration: 100, transition: 'fade' }} + {...props} + /> + ); }; const StyledMultiSelect = styled(MantineMultiSelect)` - & [data-selected='true'] { - background: var(--input-select-bg); - } - - & [data-disabled='true'] { - background: var(--input-bg); - opacity: 0.6; - } - - & .mantine-MultiSelect-itemsWrapper { - & .mantine-Select-item { - padding: 40px; + & [data-selected='true'] { + background: var(--input-select-bg); + } + + & [data-disabled='true'] { + background: var(--input-bg); + opacity: 0.6; + } + + & .mantine-MultiSelect-itemsWrapper { + & .mantine-Select-item { + padding: 40px; + } } - } `; export const MultiSelect = ({ width, maxWidth, ...props }: MultiSelectProps) => { - return ( - <StyledMultiSelect - withinPortal - styles={{ - dropdown: { - background: 'var(--dropdown-menu-bg)', - filter: 'drop-shadow(0 0 5px rgb(0, 0, 0, 20%))', - }, - input: { - background: 'var(--input-bg)', - color: 'var(--input-fg)', - }, - item: { - '&:hover': { - background: 'var(--dropdown-menu-bg-hover)', - }, - '&[data-hovered]': { - background: 'var(--dropdown-menu-bg-hover)', - }, - '&[data-selected="true"]': { - '&:hover': { - background: 'var(--dropdown-menu-bg-hover)', - }, - background: 'none', - color: 'var(--primary-color)', - }, - color: 'var(--dropdown-menu-fg)', - padding: '.5rem .1rem', - }, - value: { - margin: '.2rem', - paddingBottom: '1rem', - paddingLeft: '1rem', - paddingTop: '1rem', - }, - }} - sx={{ maxWidth, width }} - transitionProps={{ duration: 100, transition: 'fade' }} - {...props} - /> - ); + return ( + <StyledMultiSelect + withinPortal + styles={{ + dropdown: { + background: 'var(--dropdown-menu-bg)', + filter: 'drop-shadow(0 0 5px rgb(0, 0, 0, 20%))', + }, + input: { + background: 'var(--input-bg)', + color: 'var(--input-fg)', + }, + item: { + '&:hover': { + background: 'var(--dropdown-menu-bg-hover)', + }, + '&[data-hovered]': { + background: 'var(--dropdown-menu-bg-hover)', + }, + '&[data-selected="true"]': { + '&:hover': { + background: 'var(--dropdown-menu-bg-hover)', + }, + background: 'none', + color: 'var(--primary-color)', + }, + color: 'var(--dropdown-menu-fg)', + padding: '.5rem .1rem', + }, + value: { + margin: '.2rem', + paddingBottom: '1rem', + paddingLeft: '1rem', + paddingTop: '1rem', + }, + }} + sx={{ maxWidth, width }} + transitionProps={{ duration: 100, transition: 'fade' }} + {...props} + /> + ); }; Select.defaultProps = { - maxWidth: undefined, - width: undefined, + maxWidth: undefined, + width: undefined, }; MultiSelect.defaultProps = { - maxWidth: undefined, - width: undefined, + maxWidth: undefined, + width: undefined, }; diff --git a/src/renderer/components/skeleton/index.tsx b/src/renderer/components/skeleton/index.tsx index f2cc7e89..f60c1104 100644 --- a/src/renderer/components/skeleton/index.tsx +++ b/src/renderer/components/skeleton/index.tsx @@ -3,16 +3,16 @@ import { Skeleton as MantineSkeleton } from '@mantine/core'; import styled from 'styled-components'; const StyledSkeleton = styled(MantineSkeleton)` - &::after { - background: var(--placeholder-bg); - } + &::after { + background: var(--placeholder-bg); + } `; export const Skeleton = ({ ...props }: MantineSkeletonProps) => { - return ( - <StyledSkeleton - animate={false} - {...props} - /> - ); + return ( + <StyledSkeleton + animate={false} + {...props} + /> + ); }; diff --git a/src/renderer/components/slider/index.tsx b/src/renderer/components/slider/index.tsx index 3a4214c3..bc991583 100644 --- a/src/renderer/components/slider/index.tsx +++ b/src/renderer/components/slider/index.tsx @@ -5,30 +5,30 @@ import styled from 'styled-components'; type SliderProps = MantineSliderProps; const StyledSlider = styled(MantineSlider)` - & .mantine-Slider-track { - height: 0.5rem; - background-color: var(--slider-track-bg); - } + & .mantine-Slider-track { + height: 0.5rem; + background-color: var(--slider-track-bg); + } - & .mantine-Slider-bar { - background-color: var(--primary-color); - } + & .mantine-Slider-bar { + background-color: var(--primary-color); + } - & .mantine-Slider-thumb { - width: 1rem; - height: 1rem; - background: var(--slider-thumb-bg); - border: none; - } + & .mantine-Slider-thumb { + width: 1rem; + height: 1rem; + background: var(--slider-thumb-bg); + border: none; + } - & .mantine-Slider-label { - padding: 0 1rem; - color: var(--tooltip-fg); - font-size: 1em; - background: var(--tooltip-bg); - } + & .mantine-Slider-label { + padding: 0 1rem; + color: var(--tooltip-fg); + font-size: 1em; + background: var(--tooltip-bg); + } `; export const Slider = ({ ...props }: SliderProps) => { - return <StyledSlider {...props} />; + return <StyledSlider {...props} />; }; diff --git a/src/renderer/components/spinner/index.tsx b/src/renderer/components/spinner/index.tsx index c470320b..b3cff709 100644 --- a/src/renderer/components/spinner/index.tsx +++ b/src/renderer/components/spinner/index.tsx @@ -5,35 +5,35 @@ import styled from 'styled-components'; import { rotating } from '/@/renderer/styles'; interface SpinnerProps extends IconType { - color?: string; - container?: boolean; - size?: number; + color?: string; + container?: boolean; + size?: number; } export const SpinnerIcon = styled(RiLoader5Fill)` - ${rotating} - animation: rotating 1s ease-in-out infinite; + ${rotating} + animation: rotating 1s ease-in-out infinite; `; export const Spinner = ({ ...props }: SpinnerProps) => { - if (props.container) { - return ( - <Center - h="100%" - w="100%" - > - <SpinnerIcon - color={props.color} - size={props.size} - /> - </Center> - ); - } + if (props.container) { + return ( + <Center + h="100%" + w="100%" + > + <SpinnerIcon + color={props.color} + size={props.size} + /> + </Center> + ); + } - return <SpinnerIcon {...props} />; + return <SpinnerIcon {...props} />; }; Spinner.defaultProps = { - color: undefined, - size: 15, + color: undefined, + size: 15, }; diff --git a/src/renderer/components/switch/index.tsx b/src/renderer/components/switch/index.tsx index c397c069..08e0d36f 100644 --- a/src/renderer/components/switch/index.tsx +++ b/src/renderer/components/switch/index.tsx @@ -5,24 +5,24 @@ import styled from 'styled-components'; type SwitchProps = MantineSwitchProps; const StyledSwitch = styled(MantineSwitch)` - display: flex; + display: flex; - & .mantine-Switch-track { - background-color: var(--switch-track-bg); - border: none; - } - - & .mantine-Switch-input { - &:checked + .mantine-Switch-track { - background-color: var(--switch-track-enabled-bg); + & .mantine-Switch-track { + background-color: var(--switch-track-bg); + border: none; } - } - & .mantine-Switch-thumb { - background-color: var(--switch-thumb-bg); - } + & .mantine-Switch-input { + &:checked + .mantine-Switch-track { + background-color: var(--switch-track-enabled-bg); + } + } + + & .mantine-Switch-thumb { + background-color: var(--switch-thumb-bg); + } `; export const Switch = ({ ...props }: SwitchProps) => { - return <StyledSwitch {...props} />; + return <StyledSwitch {...props} />; }; diff --git a/src/renderer/components/tabs/index.tsx b/src/renderer/components/tabs/index.tsx index 0563a2ed..2a827616 100644 --- a/src/renderer/components/tabs/index.tsx +++ b/src/renderer/components/tabs/index.tsx @@ -5,57 +5,57 @@ import styled from 'styled-components'; type TabsProps = MantineTabsProps; const StyledTabs = styled(MantineTabs)` - height: 100%; + height: 100%; - & .mantine-Tabs-tabsList { - padding-right: 1rem; - } - - &.mantine-Tabs-tab { - padding: 0.5rem 1rem; - font-weight: 600; - font-size: 1rem; - background-color: var(--main-bg); - } - - & .mantine-Tabs-panel { - padding: 1.5rem 0.5rem; - } - - & .mantine-Tabs-tab { - padding: 1rem; - color: var(--btn-subtle-fg); - border-radius: 0; - - &:hover { - color: var(--btn-subtle-fg-hover); - background: var(--btn-subtle-bg-hover); + & .mantine-Tabs-tabsList { + padding-right: 1rem; } - transition: background 0.2s ease-in-out, color 0.2s ease-in-out; - } - - button[data-active] { - color: var(--btn-subtle-fg); - background: none; - border-color: var(--primary-color); - - &:hover { - background: none; + &.mantine-Tabs-tab { + padding: 0.5rem 1rem; + font-weight: 600; + font-size: 1rem; + background-color: var(--main-bg); + } + + & .mantine-Tabs-panel { + padding: 1.5rem 0.5rem; + } + + & .mantine-Tabs-tab { + padding: 1rem; + color: var(--btn-subtle-fg); + border-radius: 0; + + &:hover { + color: var(--btn-subtle-fg-hover); + background: var(--btn-subtle-bg-hover); + } + + transition: background 0.2s ease-in-out, color 0.2s ease-in-out; + } + + button[data-active] { + color: var(--btn-subtle-fg); + background: none; + border-color: var(--primary-color); + + &:hover { + background: none; + } } - } `; export const Tabs = ({ children, ...props }: TabsProps) => { - return <StyledTabs {...props}>{children}</StyledTabs>; + return <StyledTabs {...props}>{children}</StyledTabs>; }; const Panel = ({ children, ...props }: TabsPanelProps) => { - return ( - <StyledTabs.Panel {...props}> - <Suspense fallback={<></>}>{children}</Suspense> - </StyledTabs.Panel> - ); + return ( + <StyledTabs.Panel {...props}> + <Suspense fallback={<></>}>{children}</Suspense> + </StyledTabs.Panel> + ); }; Tabs.List = StyledTabs.List; diff --git a/src/renderer/components/text-title/index.tsx b/src/renderer/components/text-title/index.tsx index e031c002..5a053cf3 100644 --- a/src/renderer/components/text-title/index.tsx +++ b/src/renderer/components/text-title/index.tsx @@ -7,50 +7,50 @@ import { textEllipsis } from '/@/renderer/styles'; type MantineTextTitleDivProps = MantineTitleProps & ComponentPropsWithoutRef<'div'>; interface TextTitleProps extends MantineTextTitleDivProps { - $link?: boolean; - $noSelect?: boolean; - $secondary?: boolean; - children?: ReactNode; - overflow?: 'hidden' | 'visible'; - to?: string; - weight?: number; + $link?: boolean; + $noSelect?: boolean; + $secondary?: boolean; + children?: ReactNode; + overflow?: 'hidden' | 'visible'; + to?: string; + weight?: number; } const StyledTextTitle = styled(MantineHeader)<TextTitleProps>` - overflow: ${(props) => props.overflow}; - color: ${(props) => (props.$secondary ? 'var(--main-fg-secondary)' : 'var(--main-fg)')}; - cursor: ${(props) => props.$link && 'cursor'}; - transition: color 0.2s ease-in-out; - user-select: ${(props) => (props.$noSelect ? 'none' : 'auto')}; - ${(props) => props.overflow === 'hidden' && !props.lineClamp && textEllipsis} + overflow: ${(props) => props.overflow}; + color: ${(props) => (props.$secondary ? 'var(--main-fg-secondary)' : 'var(--main-fg)')}; + cursor: ${(props) => props.$link && 'cursor'}; + transition: color 0.2s ease-in-out; + user-select: ${(props) => (props.$noSelect ? 'none' : 'auto')}; + ${(props) => props.overflow === 'hidden' && !props.lineClamp && textEllipsis} - &:hover { - color: ${(props) => props.$link && 'var(--main-fg)'}; - text-decoration: ${(props) => (props.$link ? 'underline' : 'none')}; - } + &:hover { + color: ${(props) => props.$link && 'var(--main-fg)'}; + text-decoration: ${(props) => (props.$link ? 'underline' : 'none')}; + } `; const _TextTitle = ({ children, $secondary, overflow, $noSelect, ...rest }: TextTitleProps) => { - return ( - <StyledTextTitle - $noSelect={$noSelect} - $secondary={$secondary} - overflow={overflow} - {...rest} - > - {children} - </StyledTextTitle> - ); + return ( + <StyledTextTitle + $noSelect={$noSelect} + $secondary={$secondary} + overflow={overflow} + {...rest} + > + {children} + </StyledTextTitle> + ); }; export const TextTitle = createPolymorphicComponent<'div', TextTitleProps>(_TextTitle); _TextTitle.defaultProps = { - $link: false, - $noSelect: false, - $secondary: false, - font: undefined, - overflow: 'visible', - to: '', - weight: 400, + $link: false, + $noSelect: false, + $secondary: false, + font: undefined, + overflow: 'visible', + to: '', + weight: 400, }; diff --git a/src/renderer/components/text/index.tsx b/src/renderer/components/text/index.tsx index 43215016..c531558d 100644 --- a/src/renderer/components/text/index.tsx +++ b/src/renderer/components/text/index.tsx @@ -8,52 +8,52 @@ import { textEllipsis } from '/@/renderer/styles'; type MantineTextDivProps = MantineTextProps & ComponentPropsWithoutRef<'div'>; interface TextProps extends MantineTextDivProps { - $link?: boolean; - $noSelect?: boolean; - $secondary?: boolean; - children?: ReactNode; - font?: Font; - overflow?: 'hidden' | 'visible'; - to?: string; - weight?: number; + $link?: boolean; + $noSelect?: boolean; + $secondary?: boolean; + children?: ReactNode; + font?: Font; + overflow?: 'hidden' | 'visible'; + to?: string; + weight?: number; } const StyledText = styled(MantineText)<TextProps>` - overflow: ${(props) => props.overflow}; - color: ${(props) => (props.$secondary ? 'var(--main-fg-secondary)' : 'var(--main-fg)')}; - font-family: ${(props) => props.font}; - cursor: ${(props) => props.$link && 'cursor'}; - user-select: ${(props) => (props.$noSelect ? 'none' : 'auto')}; - ${(props) => props.overflow === 'hidden' && !props.lineClamp && textEllipsis} + overflow: ${(props) => props.overflow}; + color: ${(props) => (props.$secondary ? 'var(--main-fg-secondary)' : 'var(--main-fg)')}; + font-family: ${(props) => props.font}; + cursor: ${(props) => props.$link && 'cursor'}; + user-select: ${(props) => (props.$noSelect ? 'none' : 'auto')}; + ${(props) => props.overflow === 'hidden' && !props.lineClamp && textEllipsis} - &:hover { - color: ${(props) => props.$link && 'var(--main-fg)'}; - text-decoration: ${(props) => (props.$link ? 'underline' : 'none')}; - } + &:hover { + color: ${(props) => props.$link && 'var(--main-fg)'}; + text-decoration: ${(props) => (props.$link ? 'underline' : 'none')}; + } `; export const _Text = ({ children, $secondary, overflow, font, $noSelect, ...rest }: TextProps) => { - return ( - <StyledText - $noSelect={$noSelect} - $secondary={$secondary} - font={font} - overflow={overflow} - {...rest} - > - {children} - </StyledText> - ); + return ( + <StyledText + $noSelect={$noSelect} + $secondary={$secondary} + font={font} + overflow={overflow} + {...rest} + > + {children} + </StyledText> + ); }; export const Text = createPolymorphicComponent<'div', TextProps>(_Text); _Text.defaultProps = { - $link: false, - $noSelect: false, - $secondary: false, - font: undefined, - overflow: 'visible', - to: '', - weight: 400, + $link: false, + $noSelect: false, + $secondary: false, + font: undefined, + overflow: 'visible', + to: '', + weight: 400, }; diff --git a/src/renderer/components/toast/index.tsx b/src/renderer/components/toast/index.tsx index f9fd3456..088616f1 100644 --- a/src/renderer/components/toast/index.tsx +++ b/src/renderer/components/toast/index.tsx @@ -1,76 +1,76 @@ import type { NotificationProps as MantineNotificationProps } from '@mantine/notifications'; import { - showNotification, - updateNotification, - hideNotification, - cleanNotifications, - cleanNotificationsQueue, + showNotification, + updateNotification, + hideNotification, + cleanNotifications, + cleanNotificationsQueue, } from '@mantine/notifications'; interface NotificationProps extends MantineNotificationProps { - type?: 'success' | 'error' | 'warning' | 'info'; + type?: 'success' | 'error' | 'warning' | 'info'; } const showToast = ({ type, ...props }: NotificationProps) => { - const color = - type === 'success' - ? 'var(--success-color)' - : type === 'warning' - ? 'var(--warning-color)' - : type === 'error' - ? 'var(--danger-color)' - : 'var(--primary-color)'; + const color = + type === 'success' + ? 'var(--success-color)' + : type === 'warning' + ? 'var(--warning-color)' + : type === 'error' + ? 'var(--danger-color)' + : 'var(--primary-color)'; - const defaultTitle = - type === 'success' - ? 'Success' - : type === 'warning' - ? 'Warning' - : type === 'error' - ? 'Error' - : 'Info'; + const defaultTitle = + type === 'success' + ? 'Success' + : type === 'warning' + ? 'Warning' + : type === 'error' + ? 'Error' + : 'Info'; - const defaultDuration = type === 'error' ? 2000 : 1000; + const defaultDuration = type === 'error' ? 2000 : 1000; - return showNotification({ - autoClose: defaultDuration, - styles: () => ({ - closeButton: { - '&:hover': { - background: 'transparent', - }, - }, - description: { - color: 'var(--toast-description-fg)', - fontSize: '1rem', - }, - loader: { - margin: '1rem', - }, - root: { - '&::before': { backgroundColor: color }, - background: 'var(--toast-bg)', - border: '2px solid var(--generic-border-color)', - bottom: '90px', - }, - title: { - color: 'var(--toast-title-fg)', - fontSize: '1.3rem', - }, - }), - title: defaultTitle, - ...props, - }); + return showNotification({ + autoClose: defaultDuration, + styles: () => ({ + closeButton: { + '&:hover': { + background: 'transparent', + }, + }, + description: { + color: 'var(--toast-description-fg)', + fontSize: '1rem', + }, + loader: { + margin: '1rem', + }, + root: { + '&::before': { backgroundColor: color }, + background: 'var(--toast-bg)', + border: '2px solid var(--generic-border-color)', + bottom: '90px', + }, + title: { + color: 'var(--toast-title-fg)', + fontSize: '1.3rem', + }, + }), + title: defaultTitle, + ...props, + }); }; export const toast = { - clean: cleanNotifications, - cleanQueue: cleanNotificationsQueue, - error: (props: NotificationProps) => showToast({ type: 'error', ...props }), - hide: hideNotification, - info: (props: NotificationProps) => showToast({ type: 'info', ...props }), - show: showToast, - success: (props: NotificationProps) => showToast({ type: 'success', ...props }), - update: updateNotification, - warn: (props: NotificationProps) => showToast({ type: 'warning', ...props }), + clean: cleanNotifications, + cleanQueue: cleanNotificationsQueue, + error: (props: NotificationProps) => showToast({ type: 'error', ...props }), + hide: hideNotification, + info: (props: NotificationProps) => showToast({ type: 'info', ...props }), + show: showToast, + success: (props: NotificationProps) => showToast({ type: 'success', ...props }), + update: updateNotification, + warn: (props: NotificationProps) => showToast({ type: 'warning', ...props }), }; diff --git a/src/renderer/components/tooltip/index.tsx b/src/renderer/components/tooltip/index.tsx index 8c3822af..cd4e90a5 100644 --- a/src/renderer/components/tooltip/index.tsx +++ b/src/renderer/components/tooltip/index.tsx @@ -3,44 +3,44 @@ import { Tooltip as MantineTooltip } from '@mantine/core'; import styled from 'styled-components'; const StyledTooltip = styled(MantineTooltip)` - & .mantine-Tooltip-tooltip { - margin: 20px; - } + & .mantine-Tooltip-tooltip { + margin: 20px; + } `; export const Tooltip = ({ children, ...rest }: TooltipProps) => { - return ( - <StyledTooltip - multiline - withinPortal - pl={10} - pr={10} - py={5} - radius="xs" - styles={{ - tooltip: { - background: 'var(--tooltip-bg)', - boxShadow: '4px 4px 10px 0px rgba(0,0,0,0.2)', - color: 'var(--tooltip-fg)', - fontSize: '1.1rem', - fontWeight: 550, - maxWidth: '250px', - }, - }} - transitionProps={{ - duration: 250, - transition: 'fade', - }} - {...rest} - > - {children} - </StyledTooltip> - ); + return ( + <StyledTooltip + multiline + withinPortal + pl={10} + pr={10} + py={5} + radius="xs" + styles={{ + tooltip: { + background: 'var(--tooltip-bg)', + boxShadow: '4px 4px 10px 0px rgba(0,0,0,0.2)', + color: 'var(--tooltip-fg)', + fontSize: '1.1rem', + fontWeight: 550, + maxWidth: '250px', + }, + }} + transitionProps={{ + duration: 250, + transition: 'fade', + }} + {...rest} + > + {children} + </StyledTooltip> + ); }; Tooltip.defaultProps = { - openDelay: 0, - position: 'top', - withArrow: true, - withinPortal: true, + openDelay: 0, + position: 'top', + withArrow: true, + withinPortal: true, }; diff --git a/src/renderer/components/virtual-grid/grid-card/default-card.tsx b/src/renderer/components/virtual-grid/grid-card/default-card.tsx index a67ca701..f0b30ef3 100644 --- a/src/renderer/components/virtual-grid/grid-card/default-card.tsx +++ b/src/renderer/components/virtual-grid/grid-card/default-card.tsx @@ -11,87 +11,91 @@ import { GridCardControls } from '/@/renderer/components/virtual-grid/grid-card/ import { CardRow, PlayQueueAddOptions, Play, CardRoute } from '/@/renderer/types'; interface BaseGridCardProps { - columnIndex: number; - controls: { - cardRows: CardRow<Album | AlbumArtist | Artist>[]; - handleFavorite: (options: { id: string[]; isFavorite: boolean; itemType: LibraryItem }) => void; - handlePlayQueueAdd: (options: PlayQueueAddOptions) => void; - itemType: LibraryItem; - playButtonBehavior: Play; - route: CardRoute; - }; - data: any; - isHidden?: boolean; - listChildProps: Omit<ListChildComponentProps, 'data' | 'style'>; + columnIndex: number; + controls: { + cardRows: CardRow<Album | AlbumArtist | Artist>[]; + handleFavorite: (options: { + id: string[]; + isFavorite: boolean; + itemType: LibraryItem; + }) => void; + handlePlayQueueAdd: (options: PlayQueueAddOptions) => void; + itemType: LibraryItem; + playButtonBehavior: Play; + route: CardRoute; + }; + data: any; + isHidden?: boolean; + listChildProps: Omit<ListChildComponentProps, 'data' | 'style'>; } const DefaultCardContainer = styled.div<{ $isHidden?: boolean }>` - display: flex; - flex-direction: column; - width: 100%; - height: calc(100% - 2rem); - margin: 0.5rem; - overflow: hidden; - background: var(--card-default-bg); - border-radius: var(--card-default-radius); - cursor: pointer; - opacity: ${({ $isHidden }) => ($isHidden ? 0 : 1)}; - pointer-events: auto; + display: flex; + flex-direction: column; + width: 100%; + height: calc(100% - 2rem); + margin: 0.5rem; + overflow: hidden; + background: var(--card-default-bg); + border-radius: var(--card-default-radius); + cursor: pointer; + opacity: ${({ $isHidden }) => ($isHidden ? 0 : 1)}; + pointer-events: auto; - &:hover { - background: var(--card-default-bg-hover); - } + &:hover { + background: var(--card-default-bg-hover); + } `; const InnerCardContainer = styled.div` - display: flex; - flex-direction: column; - width: 100%; - height: 100%; - padding: 1rem; - overflow: hidden; + display: flex; + flex-direction: column; + width: 100%; + height: 100%; + padding: 1rem; + overflow: hidden; - .card-controls { - opacity: 0; - } - - &:hover .card-controls { - opacity: 1; - } - - &:hover * { - &::before { - opacity: 0.5; + .card-controls { + opacity: 0; + } + + &:hover .card-controls { + opacity: 1; + } + + &:hover * { + &::before { + opacity: 0.5; + } } - } `; const ImageContainer = styled.div<{ $isFavorite?: boolean }>` - position: relative; - display: flex; - align-items: center; - height: 100%; - aspect-ratio: 1/1; - overflow: hidden; - background: var(--placeholder-bg); - border-radius: var(--card-default-radius); - - &::before { - position: absolute; - top: 0; - left: 0; - z-index: 1; - width: 100%; + position: relative; + display: flex; + align-items: center; height: 100%; - background: linear-gradient(0deg, rgba(0, 0, 0, 100%) 35%, rgba(0, 0, 0, 0%) 100%); - opacity: 0; - transition: all 0.2s ease-in-out; - content: ''; - user-select: none; - } - ${(props) => - props.$isFavorite && - ` + aspect-ratio: 1/1; + overflow: hidden; + background: var(--placeholder-bg); + border-radius: var(--card-default-radius); + + &::before { + position: absolute; + top: 0; + left: 0; + z-index: 1; + width: 100%; + height: 100%; + background: linear-gradient(0deg, rgba(0, 0, 0, 100%) 35%, rgba(0, 0, 0, 0%) 100%); + opacity: 0; + transition: all 0.2s ease-in-out; + content: ''; + user-select: none; + } + ${(props) => + props.$isFavorite && + ` &::after { position: absolute; top: -50px; @@ -108,134 +112,134 @@ const ImageContainer = styled.div<{ $isFavorite?: boolean }>` `; const Image = styled(SimpleImg)` - width: 100%; - max-width: 100%; - height: 100% !important; - max-height: 100%; - border: 0; + width: 100%; + max-width: 100%; + height: 100% !important; + max-height: 100%; + border: 0; - img { - height: 100%; - object-fit: cover; - } + img { + height: 100%; + object-fit: cover; + } `; const DetailContainer = styled.div` - margin-top: 0.5rem; + margin-top: 0.5rem; `; export const DefaultCard = ({ - listChildProps, - data, - columnIndex, - controls, - isHidden, + listChildProps, + data, + columnIndex, + controls, + isHidden, }: BaseGridCardProps) => { - const navigate = useNavigate(); + const navigate = useNavigate(); - if (data) { - const path = generatePath( - controls.route.route, - controls.route.slugs?.reduce((acc, slug) => { - return { - ...acc, - [slug.slugProperty]: data[slug.idProperty], - }; - }, {}), - ); + if (data) { + const path = generatePath( + controls.route.route, + controls.route.slugs?.reduce((acc, slug) => { + return { + ...acc, + [slug.slugProperty]: data[slug.idProperty], + }; + }, {}), + ); - let Placeholder = RiAlbumFill; + let Placeholder = RiAlbumFill; - switch (controls.itemType) { - case LibraryItem.ALBUM: - Placeholder = RiAlbumFill; - break; - case LibraryItem.ARTIST: - Placeholder = RiUserVoiceFill; - break; - case LibraryItem.ALBUM_ARTIST: - Placeholder = RiUserVoiceFill; - break; - case LibraryItem.PLAYLIST: - Placeholder = RiPlayListFill; - break; - default: - Placeholder = RiAlbumFill; - break; + switch (controls.itemType) { + case LibraryItem.ALBUM: + Placeholder = RiAlbumFill; + break; + case LibraryItem.ARTIST: + Placeholder = RiUserVoiceFill; + break; + case LibraryItem.ALBUM_ARTIST: + Placeholder = RiUserVoiceFill; + break; + case LibraryItem.PLAYLIST: + Placeholder = RiPlayListFill; + break; + default: + Placeholder = RiAlbumFill; + break; + } + + return ( + <DefaultCardContainer + key={`card-${columnIndex}-${listChildProps.index}`} + onClick={() => navigate(path)} + > + <InnerCardContainer> + <ImageContainer $isFavorite={data?.userFavorite}> + {data?.imageUrl ? ( + <Image + importance="auto" + placeholder={data?.imagePlaceholderUrl || 'var(--placeholder-bg)'} + src={data?.imageUrl} + /> + ) : ( + <Center + sx={{ + background: 'var(--placeholder-bg)', + borderRadius: 'var(--card-default-radius)', + height: '100%', + width: '100%', + }} + > + <Placeholder + color="var(--placeholder-fg)" + size={35} + /> + </Center> + )} + + <GridCardControls + handleFavorite={controls.handleFavorite} + handlePlayQueueAdd={controls.handlePlayQueueAdd} + itemData={data} + itemType={controls.itemType} + /> + </ImageContainer> + <DetailContainer> + <CardRows + data={data} + rows={controls.cardRows} + /> + </DetailContainer> + </InnerCardContainer> + </DefaultCardContainer> + ); } return ( - <DefaultCardContainer - key={`card-${columnIndex}-${listChildProps.index}`} - onClick={() => navigate(path)} - > - <InnerCardContainer> - <ImageContainer $isFavorite={data?.userFavorite}> - {data?.imageUrl ? ( - <Image - importance="auto" - placeholder={data?.imagePlaceholderUrl || 'var(--placeholder-bg)'} - src={data?.imageUrl} - /> - ) : ( - <Center - sx={{ - background: 'var(--placeholder-bg)', - borderRadius: 'var(--card-default-radius)', - height: '100%', - width: '100%', - }} - > - <Placeholder - color="var(--placeholder-fg)" - size={35} - /> - </Center> - )} - - <GridCardControls - handleFavorite={controls.handleFavorite} - handlePlayQueueAdd={controls.handlePlayQueueAdd} - itemData={data} - itemType={controls.itemType} - /> - </ImageContainer> - <DetailContainer> - <CardRows - data={data} - rows={controls.cardRows} - /> - </DetailContainer> - </InnerCardContainer> - </DefaultCardContainer> + <DefaultCardContainer + key={`card-${columnIndex}-${listChildProps.index}`} + $isHidden={isHidden} + > + <InnerCardContainer> + <ImageContainer> + <Skeleton + visible + radius="sm" + /> + </ImageContainer> + <DetailContainer> + <Stack spacing="sm"> + {controls.cardRows.map((row, index) => ( + <Skeleton + key={`${index}-${columnIndex}-${row.arrayProperty}`} + visible + height={14} + radius="sm" + /> + ))} + </Stack> + </DetailContainer> + </InnerCardContainer> + </DefaultCardContainer> ); - } - - return ( - <DefaultCardContainer - key={`card-${columnIndex}-${listChildProps.index}`} - $isHidden={isHidden} - > - <InnerCardContainer> - <ImageContainer> - <Skeleton - visible - radius="sm" - /> - </ImageContainer> - <DetailContainer> - <Stack spacing="sm"> - {controls.cardRows.map((row, index) => ( - <Skeleton - key={`${index}-${columnIndex}-${row.arrayProperty}`} - visible - height={14} - radius="sm" - /> - ))} - </Stack> - </DetailContainer> - </InnerCardContainer> - </DefaultCardContainer> - ); }; diff --git a/src/renderer/components/virtual-grid/grid-card/grid-card-controls.tsx b/src/renderer/components/virtual-grid/grid-card/grid-card-controls.tsx index 50d505ac..70c21252 100644 --- a/src/renderer/components/virtual-grid/grid-card/grid-card-controls.tsx +++ b/src/renderer/components/virtual-grid/grid-card/grid-card-controls.tsx @@ -9,197 +9,197 @@ import { usePlayButtonBehavior } from '/@/renderer/store/settings.store'; import { LibraryItem } from '/@/renderer/api/types'; import { useHandleGeneralContextMenu } from '/@/renderer/features/context-menu/hooks/use-handle-context-menu'; import { - ALBUM_CONTEXT_MENU_ITEMS, - ARTIST_CONTEXT_MENU_ITEMS, + ALBUM_CONTEXT_MENU_ITEMS, + ARTIST_CONTEXT_MENU_ITEMS, } from '/@/renderer/features/context-menu/context-menu-items'; type PlayButtonType = UnstyledButtonProps & React.ComponentPropsWithoutRef<'button'>; const PlayButton = styled.button<PlayButtonType>` - position: absolute; - display: flex; - align-items: center; - justify-content: center; - width: 50px; - height: 50px; - background-color: rgb(255, 255, 255); - border: none; - border-radius: 50%; - opacity: 0.8; - transition: opacity 0.2s ease-in-out; - transition: scale 0.1s ease-in-out; + position: absolute; + display: flex; + align-items: center; + justify-content: center; + width: 50px; + height: 50px; + background-color: rgb(255, 255, 255); + border: none; + border-radius: 50%; + opacity: 0.8; + transition: opacity 0.2s ease-in-out; + transition: scale 0.1s ease-in-out; - &:hover { - opacity: 1; - scale: 1.1; - } + &:hover { + opacity: 1; + scale: 1.1; + } - &:active { - opacity: 1; - scale: 1; - } + &:active { + opacity: 1; + scale: 1; + } - svg { - fill: rgb(0, 0, 0); - stroke: rgb(0, 0, 0); - } + svg { + fill: rgb(0, 0, 0); + stroke: rgb(0, 0, 0); + } `; const SecondaryButton = styled(_Button)` - opacity: 0.8; - transition: opacity 0.2s ease-in-out; - transition: scale 0.2s linear; + opacity: 0.8; + transition: opacity 0.2s ease-in-out; + transition: scale 0.2s linear; - &:hover { - opacity: 1; - scale: 1.1; - } + &:hover { + opacity: 1; + scale: 1.1; + } - &:active { - opacity: 1; - scale: 1; - } + &:active { + opacity: 1; + scale: 1; + } `; const GridCardControlsContainer = styled.div<{ $isFavorite?: boolean }>` - position: absolute; - z-index: 100; - display: flex; - flex-direction: column; - align-items: center; - justify-content: center; - width: 100%; - height: 100%; + position: absolute; + z-index: 100; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; `; const FavoriteBanner = styled.div` - position: absolute; - top: -50px; - left: -50px; - width: 80px; - height: 80px; - background-color: var(--primary-color); - box-shadow: 0 0 10px 8px rgba(0, 0, 0, 80%); - transform: rotate(-45deg); - content: ''; - pointer-events: none; + position: absolute; + top: -50px; + left: -50px; + width: 80px; + height: 80px; + background-color: var(--primary-color); + box-shadow: 0 0 10px 8px rgba(0, 0, 0, 80%); + transform: rotate(-45deg); + content: ''; + pointer-events: none; `; const ControlsRow = styled.div` - width: 100%; - height: calc(100% / 3); + width: 100%; + height: calc(100% / 3); `; const BottomControls = styled(ControlsRow)` - position: absolute; - bottom: 0; - display: flex; - gap: 0.5rem; - align-items: flex-end; - justify-content: flex-end; - padding: 1rem 0.5rem; + position: absolute; + bottom: 0; + display: flex; + gap: 0.5rem; + align-items: flex-end; + justify-content: flex-end; + padding: 1rem 0.5rem; `; const FavoriteWrapper = styled.span<{ isFavorite: boolean }>` - svg { - fill: ${(props) => props.isFavorite && 'var(--primary-color)'}; - } + svg { + fill: ${(props) => props.isFavorite && 'var(--primary-color)'}; + } `; export const GridCardControls = ({ - itemData, - itemType, - handlePlayQueueAdd, - handleFavorite, -}: { - handleFavorite: (options: { - id: string[]; - isFavorite: boolean; - itemType: LibraryItem; - serverId: string; - }) => void; - handlePlayQueueAdd?: (options: PlayQueueAddOptions) => void; - itemData: any; - itemType: LibraryItem; -}) => { - const [isFavorite, setIsFavorite] = useState(itemData?.userFavorite); - const playButtonBehavior = usePlayButtonBehavior(); - - const handlePlay = async (e: MouseEvent<HTMLButtonElement>, playType?: Play) => { - e.preventDefault(); - e.stopPropagation(); - - handlePlayQueueAdd?.({ - byItemType: { - id: [itemData.id], - type: itemType, - }, - playType: playType || playButtonBehavior, - }); - }; - - const handleFavorites = async (e: MouseEvent<HTMLButtonElement>, serverId: string) => { - e.preventDefault(); - e.stopPropagation(); - - handleFavorite?.({ - id: [itemData.id], - isFavorite: itemData.userFavorite, - itemType, - serverId, - }); - - setIsFavorite(!isFavorite); - }; - - const handleContextMenu = useHandleGeneralContextMenu( + itemData, itemType, - itemType === LibraryItem.ALBUM ? ALBUM_CONTEXT_MENU_ITEMS : ARTIST_CONTEXT_MENU_ITEMS, - ); + handlePlayQueueAdd, + handleFavorite, +}: { + handleFavorite: (options: { + id: string[]; + isFavorite: boolean; + itemType: LibraryItem; + serverId: string; + }) => void; + handlePlayQueueAdd?: (options: PlayQueueAddOptions) => void; + itemData: any; + itemType: LibraryItem; +}) => { + const [isFavorite, setIsFavorite] = useState(itemData?.userFavorite); + const playButtonBehavior = usePlayButtonBehavior(); - return ( - <> - {isFavorite ? <FavoriteBanner /> : null} - <GridCardControlsContainer - $isFavorite - className="card-controls" - > - <PlayButton onClick={handlePlay}> - <RiPlayFill size={25} /> - </PlayButton> - <BottomControls> - <SecondaryButton - p={5} - variant="subtle" - onClick={(e) => handleFavorites(e, itemData?.serverId)} - > - <FavoriteWrapper isFavorite={itemData?.isFavorite}> - {isFavorite ? ( - <RiHeartFill size={20} /> - ) : ( - <RiHeartLine - color="white" - size={20} - /> - )} - </FavoriteWrapper> - </SecondaryButton> - <SecondaryButton - p={5} - variant="subtle" - onClick={(e) => { - e.preventDefault(); - e.stopPropagation(); - handleContextMenu(e, [itemData]); - }} - > - <RiMoreFill - color="white" - size={20} - /> - </SecondaryButton> - </BottomControls> - </GridCardControlsContainer> - </> - ); + const handlePlay = async (e: MouseEvent<HTMLButtonElement>, playType?: Play) => { + e.preventDefault(); + e.stopPropagation(); + + handlePlayQueueAdd?.({ + byItemType: { + id: [itemData.id], + type: itemType, + }, + playType: playType || playButtonBehavior, + }); + }; + + const handleFavorites = async (e: MouseEvent<HTMLButtonElement>, serverId: string) => { + e.preventDefault(); + e.stopPropagation(); + + handleFavorite?.({ + id: [itemData.id], + isFavorite: itemData.userFavorite, + itemType, + serverId, + }); + + setIsFavorite(!isFavorite); + }; + + const handleContextMenu = useHandleGeneralContextMenu( + itemType, + itemType === LibraryItem.ALBUM ? ALBUM_CONTEXT_MENU_ITEMS : ARTIST_CONTEXT_MENU_ITEMS, + ); + + return ( + <> + {isFavorite ? <FavoriteBanner /> : null} + <GridCardControlsContainer + $isFavorite + className="card-controls" + > + <PlayButton onClick={handlePlay}> + <RiPlayFill size={25} /> + </PlayButton> + <BottomControls> + <SecondaryButton + p={5} + variant="subtle" + onClick={(e) => handleFavorites(e, itemData?.serverId)} + > + <FavoriteWrapper isFavorite={itemData?.isFavorite}> + {isFavorite ? ( + <RiHeartFill size={20} /> + ) : ( + <RiHeartLine + color="white" + size={20} + /> + )} + </FavoriteWrapper> + </SecondaryButton> + <SecondaryButton + p={5} + variant="subtle" + onClick={(e) => { + e.preventDefault(); + e.stopPropagation(); + handleContextMenu(e, [itemData]); + }} + > + <RiMoreFill + color="white" + size={20} + /> + </SecondaryButton> + </BottomControls> + </GridCardControlsContainer> + </> + ); }; diff --git a/src/renderer/components/virtual-grid/grid-card/index.tsx b/src/renderer/components/virtual-grid/grid-card/index.tsx index 11c2e9de..adbbc902 100644 --- a/src/renderer/components/virtual-grid/grid-card/index.tsx +++ b/src/renderer/components/virtual-grid/grid-card/index.tsx @@ -6,58 +6,58 @@ import { PosterCard } from '/@/renderer/components/virtual-grid/grid-card/poster import { GridCardData, ListDisplayType } from '/@/renderer/types'; export const GridCard = memo(({ data, index, style }: ListChildComponentProps) => { - const { - columnCount, - itemCount, - cardRows, - itemData, - itemType, - playButtonBehavior, - handlePlayQueueAdd, - handleFavorite, - route, - display, - } = data as GridCardData; + const { + columnCount, + itemCount, + cardRows, + itemData, + itemType, + playButtonBehavior, + handlePlayQueueAdd, + handleFavorite, + route, + display, + } = data as GridCardData; - const cards = []; - const startIndex = index * columnCount; - const stopIndex = Math.min(itemCount - 1, startIndex + columnCount - 1); + const cards = []; + const startIndex = index * columnCount; + const stopIndex = Math.min(itemCount - 1, startIndex + columnCount - 1); - const columnCountInRow = stopIndex - startIndex + 1; - let columnCountToAdd = 0; - if (columnCountInRow !== columnCount) { - columnCountToAdd = columnCount - columnCountInRow; - } - const View = display === ListDisplayType.CARD ? DefaultCard : PosterCard; + const columnCountInRow = stopIndex - startIndex + 1; + let columnCountToAdd = 0; + if (columnCountInRow !== columnCount) { + columnCountToAdd = columnCount - columnCountInRow; + } + const View = display === ListDisplayType.CARD ? DefaultCard : PosterCard; - for (let i = startIndex; i <= stopIndex + columnCountToAdd; i += 1) { - cards.push( - <View - key={`card-${i}-${index}`} - columnIndex={i} - controls={{ - cardRows, - handleFavorite, - handlePlayQueueAdd, - itemType, - playButtonBehavior, - route, - }} - data={itemData[i]} - isHidden={i > stopIndex} - listChildProps={{ index }} - />, + for (let i = startIndex; i <= stopIndex + columnCountToAdd; i += 1) { + cards.push( + <View + key={`card-${i}-${index}`} + columnIndex={i} + controls={{ + cardRows, + handleFavorite, + handlePlayQueueAdd, + itemType, + playButtonBehavior, + route, + }} + data={itemData[i]} + isHidden={i > stopIndex} + listChildProps={{ index }} + />, + ); + } + + return ( + <div + style={{ + ...style, + display: 'flex', + }} + > + {cards} + </div> ); - } - - return ( - <div - style={{ - ...style, - display: 'flex', - }} - > - {cards} - </div> - ); }, areEqual); diff --git a/src/renderer/components/virtual-grid/grid-card/poster-card.tsx b/src/renderer/components/virtual-grid/grid-card/poster-card.tsx index fcc8cb37..e0a1dcde 100644 --- a/src/renderer/components/virtual-grid/grid-card/poster-card.tsx +++ b/src/renderer/components/virtual-grid/grid-card/poster-card.tsx @@ -11,65 +11,69 @@ import { GridCardControls } from '/@/renderer/components/virtual-grid/grid-card/ import { CardRow, PlayQueueAddOptions, Play, CardRoute } from '/@/renderer/types'; interface BaseGridCardProps { - columnIndex: number; - controls: { - cardRows: CardRow<Album | AlbumArtist | Artist>[]; - handleFavorite: (options: { id: string[]; isFavorite: boolean; itemType: LibraryItem }) => void; - handlePlayQueueAdd: (options: PlayQueueAddOptions) => void; - itemType: LibraryItem; - playButtonBehavior: Play; - route: CardRoute; - }; - data: any; - isHidden?: boolean; - listChildProps: Omit<ListChildComponentProps, 'data' | 'style'>; + columnIndex: number; + controls: { + cardRows: CardRow<Album | AlbumArtist | Artist>[]; + handleFavorite: (options: { + id: string[]; + isFavorite: boolean; + itemType: LibraryItem; + }) => void; + handlePlayQueueAdd: (options: PlayQueueAddOptions) => void; + itemType: LibraryItem; + playButtonBehavior: Play; + route: CardRoute; + }; + data: any; + isHidden?: boolean; + listChildProps: Omit<ListChildComponentProps, 'data' | 'style'>; } const PosterCardContainer = styled.div<{ $isHidden?: boolean }>` - display: flex; - flex-direction: column; - width: 100%; - height: 100%; - margin: 1rem; - overflow: hidden; - opacity: ${({ $isHidden }) => ($isHidden ? 0 : 1)}; - pointer-events: auto; + display: flex; + flex-direction: column; + width: 100%; + height: 100%; + margin: 1rem; + overflow: hidden; + opacity: ${({ $isHidden }) => ($isHidden ? 0 : 1)}; + pointer-events: auto; - .card-controls { - opacity: 0; - } + .card-controls { + opacity: 0; + } `; const LinkContainer = styled.div` - cursor: pointer; + cursor: pointer; `; const ImageContainer = styled.div<{ $isFavorite?: boolean }>` - position: relative; - display: flex; - align-items: center; - aspect-ratio: 1/1; - overflow: hidden; - background: var(--card-default-bg); - border-radius: var(--card-poster-radius); + position: relative; + display: flex; + align-items: center; + aspect-ratio: 1/1; + overflow: hidden; + background: var(--card-default-bg); + border-radius: var(--card-poster-radius); - &::before { - position: absolute; - top: 0; - left: 0; - z-index: 1; - width: 100%; - height: 100%; - background: linear-gradient(0deg, rgba(0, 0, 0, 100%) 35%, rgba(0, 0, 0, 0%) 100%); - opacity: 0; - transition: all 0.2s ease-in-out; - content: ''; - user-select: none; - } + &::before { + position: absolute; + top: 0; + left: 0; + z-index: 1; + width: 100%; + height: 100%; + background: linear-gradient(0deg, rgba(0, 0, 0, 100%) 35%, rgba(0, 0, 0, 0%) 100%); + opacity: 0; + transition: all 0.2s ease-in-out; + content: ''; + user-select: none; + } - ${(props) => - props.$isFavorite && - ` + ${(props) => + props.$isFavorite && + ` &::after { position: absolute; top: -50px; @@ -84,140 +88,140 @@ const ImageContainer = styled.div<{ $isFavorite?: boolean }>` } `} - &:hover { - &::before { - opacity: 0.5; + &:hover { + &::before { + opacity: 0.5; + } } - } - &:hover .card-controls { - opacity: 1; - } + &:hover .card-controls { + opacity: 1; + } `; const Image = styled(SimpleImg)` - width: 100%; - max-width: 100%; - height: 100% !important; - max-height: 100%; - border: 0; + width: 100%; + max-width: 100%; + height: 100% !important; + max-height: 100%; + border: 0; - img { - height: 100%; - object-fit: cover; - } + img { + height: 100%; + object-fit: cover; + } `; const DetailContainer = styled.div` - margin-top: 0.5rem; + margin-top: 0.5rem; `; export const PosterCard = ({ - listChildProps, - data, - columnIndex, - controls, - isHidden, + listChildProps, + data, + columnIndex, + controls, + isHidden, }: BaseGridCardProps) => { - const navigate = useNavigate(); + const navigate = useNavigate(); - if (data) { - const path = generatePath( - controls.route.route, - controls.route.slugs?.reduce((acc, slug) => { - return { - ...acc, - [slug.slugProperty]: data[slug.idProperty], - }; - }, {}), - ); + if (data) { + const path = generatePath( + controls.route.route, + controls.route.slugs?.reduce((acc, slug) => { + return { + ...acc, + [slug.slugProperty]: data[slug.idProperty], + }; + }, {}), + ); - let Placeholder = RiAlbumFill; + let Placeholder = RiAlbumFill; - switch (controls.itemType) { - case LibraryItem.ALBUM: - Placeholder = RiAlbumFill; - break; - case LibraryItem.ARTIST: - Placeholder = RiUserVoiceFill; - break; - case LibraryItem.ALBUM_ARTIST: - Placeholder = RiUserVoiceFill; - break; - case LibraryItem.PLAYLIST: - Placeholder = RiPlayListFill; - break; - default: - Placeholder = RiAlbumFill; - break; + switch (controls.itemType) { + case LibraryItem.ALBUM: + Placeholder = RiAlbumFill; + break; + case LibraryItem.ARTIST: + Placeholder = RiUserVoiceFill; + break; + case LibraryItem.ALBUM_ARTIST: + Placeholder = RiUserVoiceFill; + break; + case LibraryItem.PLAYLIST: + Placeholder = RiPlayListFill; + break; + default: + Placeholder = RiAlbumFill; + break; + } + + return ( + <PosterCardContainer key={`card-${columnIndex}-${listChildProps.index}`}> + <LinkContainer onClick={() => navigate(path)}> + <ImageContainer $isFavorite={data?.userFavorite}> + {data?.imageUrl ? ( + <Image + importance="auto" + placeholder={data?.imagePlaceholderUrl || 'var(--card-default-bg)'} + src={data?.imageUrl} + /> + ) : ( + <Center + sx={{ + background: 'var(--placeholder-bg)', + borderRadius: 'var(--card-default-radius)', + height: '100%', + width: '100%', + }} + > + <Placeholder + color="var(--placeholder-fg)" + size={35} + /> + </Center> + )} + <GridCardControls + handleFavorite={controls.handleFavorite} + handlePlayQueueAdd={controls.handlePlayQueueAdd} + itemData={data} + itemType={controls.itemType} + /> + </ImageContainer> + </LinkContainer> + <DetailContainer> + <CardRows + data={data} + rows={controls.cardRows} + /> + </DetailContainer> + </PosterCardContainer> + ); } return ( - <PosterCardContainer key={`card-${columnIndex}-${listChildProps.index}`}> - <LinkContainer onClick={() => navigate(path)}> - <ImageContainer $isFavorite={data?.userFavorite}> - {data?.imageUrl ? ( - <Image - importance="auto" - placeholder={data?.imagePlaceholderUrl || 'var(--card-default-bg)'} - src={data?.imageUrl} - /> - ) : ( - <Center - sx={{ - background: 'var(--placeholder-bg)', - borderRadius: 'var(--card-default-radius)', - height: '100%', - width: '100%', - }} - > - <Placeholder - color="var(--placeholder-fg)" - size={35} - /> - </Center> - )} - <GridCardControls - handleFavorite={controls.handleFavorite} - handlePlayQueueAdd={controls.handlePlayQueueAdd} - itemData={data} - itemType={controls.itemType} - /> - </ImageContainer> - </LinkContainer> - <DetailContainer> - <CardRows - data={data} - rows={controls.cardRows} - /> - </DetailContainer> - </PosterCardContainer> - ); - } - - return ( - <PosterCardContainer - key={`card-${columnIndex}-${listChildProps.index}`} - $isHidden={isHidden} - > - <Skeleton - visible - radius="sm" - > - <ImageContainer /> - </Skeleton> - <DetailContainer> - <Stack spacing="sm"> - {controls.cardRows.map((row, index) => ( + <PosterCardContainer + key={`card-${columnIndex}-${listChildProps.index}`} + $isHidden={isHidden} + > <Skeleton - key={`${index}-${columnIndex}-${row.arrayProperty}`} - visible - height={14} - radius="sm" - /> - ))} - </Stack> - </DetailContainer> - </PosterCardContainer> - ); + visible + radius="sm" + > + <ImageContainer /> + </Skeleton> + <DetailContainer> + <Stack spacing="sm"> + {controls.cardRows.map((row, index) => ( + <Skeleton + key={`${index}-${columnIndex}-${row.arrayProperty}`} + visible + height={14} + radius="sm" + /> + ))} + </Stack> + </DetailContainer> + </PosterCardContainer> + ); }; diff --git a/src/renderer/components/virtual-grid/virtual-grid-wrapper.tsx b/src/renderer/components/virtual-grid/virtual-grid-wrapper.tsx index ba6ff77b..f235159f 100644 --- a/src/renderer/components/virtual-grid/virtual-grid-wrapper.tsx +++ b/src/renderer/components/virtual-grid/virtual-grid-wrapper.tsx @@ -9,119 +9,123 @@ import type { CardRow, ListDisplayType, CardRoute, PlayQueueAddOptions } from '/ import { Album, AlbumArtist, Artist, LibraryItem } from '/@/renderer/api/types'; const createItemData = memoize( - ( - cardRows, - columnCount, - display, - itemCount, - itemData, - itemGap, - itemHeight, - itemType, - itemWidth, - route, - handlePlayQueueAdd, - handleFavorite, - ) => ({ - cardRows, - columnCount, - display, - handleFavorite, - handlePlayQueueAdd, - itemCount, - itemData, - itemGap, - itemHeight, - itemType, - itemWidth, - route, - }), + ( + cardRows, + columnCount, + display, + itemCount, + itemData, + itemGap, + itemHeight, + itemType, + itemWidth, + route, + handlePlayQueueAdd, + handleFavorite, + ) => ({ + cardRows, + columnCount, + display, + handleFavorite, + handlePlayQueueAdd, + itemCount, + itemData, + itemGap, + itemHeight, + itemType, + itemWidth, + route, + }), ); const createScrollHandler = memoize((onScroll) => debounce(onScroll, 250)); export const VirtualGridWrapper = ({ - refInstance, - cardRows, - itemGap, - itemType, - itemWidth, - display, - itemHeight, - itemCount, - columnCount, - rowCount, - initialScrollOffset, - handleFavorite, - handlePlayQueueAdd, - itemData, - route, - onScroll, - height, - width, - ...rest -}: Omit<FixedSizeListProps, 'ref' | 'itemSize' | 'children' | 'height' | 'width'> & { - cardRows: CardRow<Album | AlbumArtist | Artist>[]; - columnCount: number; - display: ListDisplayType; - handleFavorite?: (options: { id: string[]; isFavorite: boolean; itemType: LibraryItem }) => void; - handlePlayQueueAdd?: (options: PlayQueueAddOptions) => void; - height?: number; - itemData: any[]; - itemGap: number; - itemHeight: number; - itemType: LibraryItem; - itemWidth: number; - refInstance: Ref<any>; - route?: CardRoute; - rowCount: number; - width?: number; -}) => { - const memoizedItemData = createItemData( + refInstance, cardRows, - columnCount, - display, - itemCount, - itemData, itemGap, - itemHeight, itemType, itemWidth, - route, - handlePlayQueueAdd, + display, + itemHeight, + itemCount, + columnCount, + rowCount, + initialScrollOffset, handleFavorite, - ); + handlePlayQueueAdd, + itemData, + route, + onScroll, + height, + width, + ...rest +}: Omit<FixedSizeListProps, 'ref' | 'itemSize' | 'children' | 'height' | 'width'> & { + cardRows: CardRow<Album | AlbumArtist | Artist>[]; + columnCount: number; + display: ListDisplayType; + handleFavorite?: (options: { + id: string[]; + isFavorite: boolean; + itemType: LibraryItem; + }) => void; + handlePlayQueueAdd?: (options: PlayQueueAddOptions) => void; + height?: number; + itemData: any[]; + itemGap: number; + itemHeight: number; + itemType: LibraryItem; + itemWidth: number; + refInstance: Ref<any>; + route?: CardRoute; + rowCount: number; + width?: number; +}) => { + const memoizedItemData = createItemData( + cardRows, + columnCount, + display, + itemCount, + itemData, + itemGap, + itemHeight, + itemType, + itemWidth, + route, + handlePlayQueueAdd, + handleFavorite, + ); - const memoizedOnScroll = createScrollHandler(onScroll); + const memoizedOnScroll = createScrollHandler(onScroll); - return ( - <FixedSizeList - ref={refInstance} - {...rest} - height={(height && Number(height)) || 0} - initialScrollOffset={initialScrollOffset} - itemCount={rowCount} - itemData={memoizedItemData} - itemSize={itemHeight} - overscanCount={5} - width={(width && Number(width)) || 0} - onScroll={memoizedOnScroll} - > - {GridCard} - </FixedSizeList> - ); + return ( + <FixedSizeList + ref={refInstance} + {...rest} + height={(height && Number(height)) || 0} + initialScrollOffset={initialScrollOffset} + itemCount={rowCount} + itemData={memoizedItemData} + itemSize={itemHeight} + overscanCount={5} + width={(width && Number(width)) || 0} + onScroll={memoizedOnScroll} + > + {GridCard} + </FixedSizeList> + ); }; VirtualGridWrapper.defaultProps = { - route: undefined, + route: undefined, }; export const VirtualGridContainer = styled.div` - display: flex; - flex-direction: column; - height: 100%; + display: flex; + flex-direction: column; + height: 100%; `; export const VirtualGridAutoSizerContainer = styled.div` - flex: 1; + flex: 1; `; diff --git a/src/renderer/components/virtual-grid/virtual-infinite-grid.tsx b/src/renderer/components/virtual-grid/virtual-infinite-grid.tsx index b9611a13..d3ca5e46 100644 --- a/src/renderer/components/virtual-grid/virtual-infinite-grid.tsx +++ b/src/renderer/components/virtual-grid/virtual-infinite-grid.tsx @@ -1,11 +1,11 @@ import { - useState, - useRef, - useMemo, - useCallback, - forwardRef, - Ref, - useImperativeHandle, + useState, + useRef, + useMemo, + useCallback, + forwardRef, + Ref, + useImperativeHandle, } from 'react'; import debounce from 'lodash/debounce'; import type { FixedSizeListProps } from 'react-window'; @@ -16,167 +16,171 @@ import { ListDisplayType } from '/@/renderer/types'; import { LibraryItem } from '/@/renderer/api/types'; export type VirtualInfiniteGridRef = { - resetLoadMoreItemsCache: () => void; - scrollTo: (index: number) => void; - setItemData: (data: any[]) => void; + resetLoadMoreItemsCache: () => void; + scrollTo: (index: number) => void; + setItemData: (data: any[]) => void; }; interface VirtualGridProps - extends Omit<FixedSizeListProps, 'children' | 'itemSize' | 'height' | 'width'> { - cardRows: CardRow<any>[]; - display?: ListDisplayType; - fetchFn: (options: { columnCount: number; skip: number; take: number }) => Promise<any>; - handleFavorite?: (options: { id: string[]; isFavorite: boolean; itemType: LibraryItem }) => void; - handlePlayQueueAdd?: (options: PlayQueueAddOptions) => void; - height?: number; - itemGap: number; - itemSize: number; - itemType: LibraryItem; - loading?: boolean; - minimumBatchSize?: number; - route?: CardRoute; - width?: number; + extends Omit<FixedSizeListProps, 'children' | 'itemSize' | 'height' | 'width'> { + cardRows: CardRow<any>[]; + display?: ListDisplayType; + fetchFn: (options: { columnCount: number; skip: number; take: number }) => Promise<any>; + handleFavorite?: (options: { + id: string[]; + isFavorite: boolean; + itemType: LibraryItem; + }) => void; + handlePlayQueueAdd?: (options: PlayQueueAddOptions) => void; + height?: number; + itemGap: number; + itemSize: number; + itemType: LibraryItem; + loading?: boolean; + minimumBatchSize?: number; + route?: CardRoute; + width?: number; } export const VirtualInfiniteGrid = forwardRef( - ( - { - itemCount, - itemGap, - itemSize, - itemType, - cardRows, - route, - onScroll, - display, - handlePlayQueueAdd, - minimumBatchSize, - fetchFn, - loading, - initialScrollOffset, - handleFavorite, - height, - width, - }: VirtualGridProps, - ref: Ref<VirtualInfiniteGridRef>, - ) => { - const listRef = useRef<any>(null); - const loader = useRef<InfiniteLoader>(null); + ( + { + itemCount, + itemGap, + itemSize, + itemType, + cardRows, + route, + onScroll, + display, + handlePlayQueueAdd, + minimumBatchSize, + fetchFn, + loading, + initialScrollOffset, + handleFavorite, + height, + width, + }: VirtualGridProps, + ref: Ref<VirtualInfiniteGridRef>, + ) => { + const listRef = useRef<any>(null); + const loader = useRef<InfiniteLoader>(null); - const [itemData, setItemData] = useState<any[]>([]); + const [itemData, setItemData] = useState<any[]>([]); - const { itemHeight, rowCount, columnCount } = useMemo(() => { - const itemsPerRow = itemSize; - const widthPerItem = Number(width) / itemsPerRow; - const itemHeight = widthPerItem + cardRows.length * 26; + const { itemHeight, rowCount, columnCount } = useMemo(() => { + const itemsPerRow = itemSize; + const widthPerItem = Number(width) / itemsPerRow; + const itemHeight = widthPerItem + cardRows.length * 26; - return { - columnCount: itemsPerRow, - itemHeight, - rowCount: Math.ceil(itemCount / itemsPerRow), - }; - }, [cardRows.length, itemCount, itemSize, width]); + return { + columnCount: itemsPerRow, + itemHeight, + rowCount: Math.ceil(itemCount / itemsPerRow), + }; + }, [cardRows.length, itemCount, itemSize, width]); - const isItemLoaded = useCallback( - (index: number) => { - const itemIndex = index * columnCount; + const isItemLoaded = useCallback( + (index: number) => { + const itemIndex = index * columnCount; - return itemData[itemIndex] !== undefined; - }, - [columnCount, itemData], - ); + return itemData[itemIndex] !== undefined; + }, + [columnCount, itemData], + ); - const loadMoreItems = useCallback( - async (startIndex: number, stopIndex: number) => { - // Fixes a caching bug(?) when switching between filters and the itemCount increases - if (startIndex === 1) return; + const loadMoreItems = useCallback( + async (startIndex: number, stopIndex: number) => { + // Fixes a caching bug(?) when switching between filters and the itemCount increases + if (startIndex === 1) return; - // Need to multiply by columnCount due to the grid layout - const start = startIndex * columnCount; - const end = stopIndex * columnCount + columnCount; + // Need to multiply by columnCount due to the grid layout + const start = startIndex * columnCount; + const end = stopIndex * columnCount + columnCount; - const data = await fetchFn({ - columnCount, - skip: start, - take: end - start, - }); + const data = await fetchFn({ + columnCount, + skip: start, + take: end - start, + }); - const newData: any[] = [...itemData]; + const newData: any[] = [...itemData]; - let itemIndex = 0; - for (let rowIndex = start; rowIndex < end; rowIndex += 1) { - newData[rowIndex] = data.items[itemIndex]; - itemIndex += 1; - } + let itemIndex = 0; + for (let rowIndex = start; rowIndex < end; rowIndex += 1) { + newData[rowIndex] = data.items[itemIndex]; + itemIndex += 1; + } - setItemData(newData); - }, - [columnCount, fetchFn, itemData, setItemData], - ); + setItemData(newData); + }, + [columnCount, fetchFn, itemData, setItemData], + ); - const debouncedLoadMoreItems = debounce(loadMoreItems, 500); + const debouncedLoadMoreItems = debounce(loadMoreItems, 500); - useImperativeHandle(ref, () => ({ - resetLoadMoreItemsCache: () => { - if (loader.current) { - loader.current.resetloadMoreItemsCache(false); - setItemData([]); - } - }, - scrollTo: (index: number) => { - listRef?.current?.scrollToItem(index); - }, - setItemData: (data: any[]) => { - setItemData(data); - }, - })); + useImperativeHandle(ref, () => ({ + resetLoadMoreItemsCache: () => { + if (loader.current) { + loader.current.resetloadMoreItemsCache(false); + setItemData([]); + } + }, + scrollTo: (index: number) => { + listRef?.current?.scrollToItem(index); + }, + setItemData: (data: any[]) => { + setItemData(data); + }, + })); - if (loading) return null; + if (loading) return null; - return ( - <> - <InfiniteLoader - ref={loader} - isItemLoaded={(index) => isItemLoaded(index)} - itemCount={itemCount || 0} - loadMoreItems={debouncedLoadMoreItems} - minimumBatchSize={minimumBatchSize} - threshold={30} - > - {({ onItemsRendered, ref: infiniteLoaderRef }) => ( - <VirtualGridWrapper - cardRows={cardRows} - columnCount={columnCount} - display={display || ListDisplayType.CARD} - handleFavorite={handleFavorite} - handlePlayQueueAdd={handlePlayQueueAdd} - height={height} - initialScrollOffset={initialScrollOffset} - itemCount={itemCount || 0} - itemData={itemData} - itemGap={itemGap} - itemHeight={itemHeight} - itemType={itemType} - itemWidth={itemSize} - refInstance={(list) => { - infiniteLoaderRef(list); - listRef.current = list; - }} - route={route} - rowCount={rowCount} - width={width} - onItemsRendered={onItemsRendered} - onScroll={onScroll} - /> - )} - </InfiniteLoader> - </> - ); - }, + return ( + <> + <InfiniteLoader + ref={loader} + isItemLoaded={(index) => isItemLoaded(index)} + itemCount={itemCount || 0} + loadMoreItems={debouncedLoadMoreItems} + minimumBatchSize={minimumBatchSize} + threshold={30} + > + {({ onItemsRendered, ref: infiniteLoaderRef }) => ( + <VirtualGridWrapper + cardRows={cardRows} + columnCount={columnCount} + display={display || ListDisplayType.CARD} + handleFavorite={handleFavorite} + handlePlayQueueAdd={handlePlayQueueAdd} + height={height} + initialScrollOffset={initialScrollOffset} + itemCount={itemCount || 0} + itemData={itemData} + itemGap={itemGap} + itemHeight={itemHeight} + itemType={itemType} + itemWidth={itemSize} + refInstance={(list) => { + infiniteLoaderRef(list); + listRef.current = list; + }} + route={route} + rowCount={rowCount} + width={width} + onItemsRendered={onItemsRendered} + onScroll={onScroll} + /> + )} + </InfiniteLoader> + </> + ); + }, ); VirtualInfiniteGrid.defaultProps = { - display: ListDisplayType.CARD, - minimumBatchSize: 20, - route: undefined, + display: ListDisplayType.CARD, + minimumBatchSize: 20, + route: undefined, }; diff --git a/src/renderer/components/virtual-table/cells/album-artist-cell.tsx b/src/renderer/components/virtual-table/cells/album-artist-cell.tsx index 921d5e09..82320444 100644 --- a/src/renderer/components/virtual-table/cells/album-artist-cell.tsx +++ b/src/renderer/components/virtual-table/cells/album-artist-cell.tsx @@ -9,60 +9,60 @@ import { AppRoute } from '/@/renderer/router/routes'; import { Skeleton } from '/@/renderer/components/skeleton'; export const AlbumArtistCell = ({ value, data }: ICellRendererParams) => { - if (value === undefined) { - return ( - <CellContainer position="left"> - <Skeleton - height="1rem" - width="80%" - /> - </CellContainer> - ); - } + if (value === undefined) { + return ( + <CellContainer position="left"> + <Skeleton + height="1rem" + width="80%" + /> + </CellContainer> + ); + } - return ( - <CellContainer position="left"> - <Text - $secondary - overflow="hidden" - size="md" - > - {value?.map((item: Artist | AlbumArtist, index: number) => ( - <React.Fragment key={`row-${item.id}-${data.uniqueId}`}> - {index > 0 && ( - <Text - $secondary - size="md" - style={{ display: 'inline-block' }} - > - , - </Text> - )}{' '} - {item.id ? ( - <Text - $link - $secondary - component={Link} - overflow="hidden" - size="md" - to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, { - albumArtistId: item.id, - })} - > - {item.name || '—'} - </Text> - ) : ( - <Text + return ( + <CellContainer position="left"> + <Text $secondary overflow="hidden" size="md" - > - {item.name || '—'} - </Text> - )} - </React.Fragment> - ))} - </Text> - </CellContainer> - ); + > + {value?.map((item: Artist | AlbumArtist, index: number) => ( + <React.Fragment key={`row-${item.id}-${data.uniqueId}`}> + {index > 0 && ( + <Text + $secondary + size="md" + style={{ display: 'inline-block' }} + > + , + </Text> + )}{' '} + {item.id ? ( + <Text + $link + $secondary + component={Link} + overflow="hidden" + size="md" + to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, { + albumArtistId: item.id, + })} + > + {item.name || '—'} + </Text> + ) : ( + <Text + $secondary + overflow="hidden" + size="md" + > + {item.name || '—'} + </Text> + )} + </React.Fragment> + ))} + </Text> + </CellContainer> + ); }; diff --git a/src/renderer/components/virtual-table/cells/artist-cell.tsx b/src/renderer/components/virtual-table/cells/artist-cell.tsx index 3c0ea589..87c23d35 100644 --- a/src/renderer/components/virtual-table/cells/artist-cell.tsx +++ b/src/renderer/components/virtual-table/cells/artist-cell.tsx @@ -9,60 +9,60 @@ import { AppRoute } from '/@/renderer/router/routes'; import { Skeleton } from '/@/renderer/components/skeleton'; export const ArtistCell = ({ value, data }: ICellRendererParams) => { - if (value === undefined) { - return ( - <CellContainer position="left"> - <Skeleton - height="1rem" - width="80%" - /> - </CellContainer> - ); - } + if (value === undefined) { + return ( + <CellContainer position="left"> + <Skeleton + height="1rem" + width="80%" + /> + </CellContainer> + ); + } - return ( - <CellContainer position="left"> - <Text - $secondary - overflow="hidden" - size="md" - > - {value?.map((item: Artist | AlbumArtist, index: number) => ( - <React.Fragment key={`row-${item.id}-${data.uniqueId}`}> - {index > 0 && ( - <Text - $secondary - size="md" - style={{ display: 'inline-block' }} - > - , - </Text> - )}{' '} - {item.id ? ( - <Text - $link - $secondary - component={Link} - overflow="hidden" - size="md" - to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, { - albumArtistId: item.id, - })} - > - {item.name || '—'} - </Text> - ) : ( - <Text + return ( + <CellContainer position="left"> + <Text $secondary overflow="hidden" size="md" - > - {item.name || '—'} - </Text> - )} - </React.Fragment> - ))} - </Text> - </CellContainer> - ); + > + {value?.map((item: Artist | AlbumArtist, index: number) => ( + <React.Fragment key={`row-${item.id}-${data.uniqueId}`}> + {index > 0 && ( + <Text + $secondary + size="md" + style={{ display: 'inline-block' }} + > + , + </Text> + )}{' '} + {item.id ? ( + <Text + $link + $secondary + component={Link} + overflow="hidden" + size="md" + to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, { + albumArtistId: item.id, + })} + > + {item.name || '—'} + </Text> + ) : ( + <Text + $secondary + overflow="hidden" + size="md" + > + {item.name || '—'} + </Text> + )} + </React.Fragment> + ))} + </Text> + </CellContainer> + ); }; diff --git a/src/renderer/components/virtual-table/cells/combined-title-cell.tsx b/src/renderer/components/virtual-table/cells/combined-title-cell.tsx index 628078f7..63d86068 100644 --- a/src/renderer/components/virtual-table/cells/combined-title-cell.tsx +++ b/src/renderer/components/virtual-table/cells/combined-title-cell.tsx @@ -13,140 +13,140 @@ import { ServerType } from '/@/renderer/types'; import { Skeleton } from '/@/renderer/components/skeleton'; const CellContainer = styled(motion.div)<{ height: number }>` - display: grid; - grid-auto-columns: 1fr; - grid-template-areas: 'image info'; - grid-template-rows: 1fr; - grid-template-columns: ${(props) => props.height}px minmax(0, 1fr); - gap: 0.5rem; - width: 100%; - max-width: 100%; - height: 100%; - letter-spacing: 0.5px; + display: grid; + grid-auto-columns: 1fr; + grid-template-areas: 'image info'; + grid-template-rows: 1fr; + grid-template-columns: ${(props) => props.height}px minmax(0, 1fr); + gap: 0.5rem; + width: 100%; + max-width: 100%; + height: 100%; + letter-spacing: 0.5px; `; const ImageWrapper = styled.div` - display: flex; - grid-area: image; - align-items: center; - justify-content: center; - height: 100%; + display: flex; + grid-area: image; + align-items: center; + justify-content: center; + height: 100%; `; const MetadataWrapper = styled.div` - display: flex; - flex-direction: column; - grid-area: info; - justify-content: center; - width: 100%; + display: flex; + flex-direction: column; + grid-area: info; + justify-content: center; + width: 100%; `; const StyledImage = styled.img` - object-fit: cover; + object-fit: cover; `; export const CombinedTitleCell = ({ value, rowIndex, node }: ICellRendererParams) => { - const artists = useMemo(() => { - if (!value) return null; - return value?.type === ServerType.JELLYFIN ? value.artists : value.albumArtists; - }, [value]); + const artists = useMemo(() => { + if (!value) return null; + return value?.type === ServerType.JELLYFIN ? value.artists : value.albumArtists; + }, [value]); + + if (value === undefined) { + return ( + <CellContainer height={node.rowHeight || 40}> + <Skeleton> + <ImageWrapper /> + </Skeleton> + <MetadataWrapper> + <Skeleton + height="1rem" + width="80%" + /> + <Skeleton + height="1rem" + mt="0.5rem" + width="60%" + /> + </MetadataWrapper> + </CellContainer> + ); + } - if (value === undefined) { return ( - <CellContainer height={node.rowHeight || 40}> - <Skeleton> - <ImageWrapper /> - </Skeleton> - <MetadataWrapper> - <Skeleton - height="1rem" - width="80%" - /> - <Skeleton - height="1rem" - mt="0.5rem" - width="60%" - /> - </MetadataWrapper> - </CellContainer> - ); - } - - return ( - <CellContainer height={node.rowHeight || 40}> - <ImageWrapper> - {value.imageUrl ? ( - <StyledImage - alt="cover" - height={(node.rowHeight || 40) - 10} - placeholder={value.imagePlaceholderUrl || 'var(--placeholder-bg)'} - src={value.imageUrl} - style={{}} - width={(node.rowHeight || 40) - 10} - /> - ) : ( - <Center - sx={{ - background: 'var(--placeholder-bg)', - borderRadius: 'var(--card-default-radius)', - height: `${(node.rowHeight || 40) - 10}px`, - width: `${(node.rowHeight || 40) - 10}px`, - }} - > - <RiAlbumFill - color="var(--placeholder-fg)" - size={35} - /> - </Center> - )} - </ImageWrapper> - <MetadataWrapper> - <Text - overflow="hidden" - size="md" - > - {value.name} - </Text> - <Text - $secondary - overflow="hidden" - size="md" - > - {artists?.length ? ( - artists.map((artist: Artist | AlbumArtist, index: number) => ( - <React.Fragment key={`queue-${rowIndex}-artist-${artist.id}`}> - {index > 0 ? ', ' : null} - {artist.id ? ( - <Text - $link - $secondary - component={Link} - overflow="hidden" - size="md" - sx={{ width: 'fit-content' }} - to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, { - albumArtistId: artist.id, - })} - > - {artist.name} - </Text> + <CellContainer height={node.rowHeight || 40}> + <ImageWrapper> + {value.imageUrl ? ( + <StyledImage + alt="cover" + height={(node.rowHeight || 40) - 10} + placeholder={value.imagePlaceholderUrl || 'var(--placeholder-bg)'} + src={value.imageUrl} + style={{}} + width={(node.rowHeight || 40) - 10} + /> ) : ( - <Text + <Center + sx={{ + background: 'var(--placeholder-bg)', + borderRadius: 'var(--card-default-radius)', + height: `${(node.rowHeight || 40) - 10}px`, + width: `${(node.rowHeight || 40) - 10}px`, + }} + > + <RiAlbumFill + color="var(--placeholder-fg)" + size={35} + /> + </Center> + )} + </ImageWrapper> + <MetadataWrapper> + <Text + overflow="hidden" + size="md" + > + {value.name} + </Text> + <Text $secondary overflow="hidden" size="md" - sx={{ width: 'fit-content' }} - > - {artist.name} - </Text> - )} - </React.Fragment> - )) - ) : ( - <Text $secondary>—</Text> - )} - </Text> - </MetadataWrapper> - </CellContainer> - ); + > + {artists?.length ? ( + artists.map((artist: Artist | AlbumArtist, index: number) => ( + <React.Fragment key={`queue-${rowIndex}-artist-${artist.id}`}> + {index > 0 ? ', ' : null} + {artist.id ? ( + <Text + $link + $secondary + component={Link} + overflow="hidden" + size="md" + sx={{ width: 'fit-content' }} + to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, { + albumArtistId: artist.id, + })} + > + {artist.name} + </Text> + ) : ( + <Text + $secondary + overflow="hidden" + size="md" + sx={{ width: 'fit-content' }} + > + {artist.name} + </Text> + )} + </React.Fragment> + )) + ) : ( + <Text $secondary>—</Text> + )} + </Text> + </MetadataWrapper> + </CellContainer> + ); }; diff --git a/src/renderer/components/virtual-table/cells/favorite-cell.tsx b/src/renderer/components/virtual-table/cells/favorite-cell.tsx index 0f668da2..1078f619 100644 --- a/src/renderer/components/virtual-table/cells/favorite-cell.tsx +++ b/src/renderer/components/virtual-table/cells/favorite-cell.tsx @@ -6,61 +6,61 @@ import { CellContainer } from '/@/renderer/components/virtual-table/cells/generi import { useCreateFavorite, useDeleteFavorite } from '/@/renderer/features/shared'; export const FavoriteCell = ({ value, data, node }: ICellRendererParams) => { - const createMutation = useCreateFavorite({}); - const deleteMutation = useDeleteFavorite({}); + const createMutation = useCreateFavorite({}); + const deleteMutation = useDeleteFavorite({}); - const handleToggleFavorite = () => { - const newFavoriteValue = !value; + const handleToggleFavorite = () => { + const newFavoriteValue = !value; - if (newFavoriteValue) { - createMutation.mutate( - { - query: { - id: [data.id], - type: data.itemType, - }, - serverId: data.serverId, - }, - { - onSuccess: () => { - node.setData({ ...data, userFavorite: newFavoriteValue }); - }, - }, - ); - } else { - deleteMutation.mutate( - { - query: { - id: [data.id], - type: data.itemType, - }, - serverId: data.serverId, - }, - { - onSuccess: () => { - node.setData({ ...data, userFavorite: newFavoriteValue }); - }, - }, - ); - } - }; + if (newFavoriteValue) { + createMutation.mutate( + { + query: { + id: [data.id], + type: data.itemType, + }, + serverId: data.serverId, + }, + { + onSuccess: () => { + node.setData({ ...data, userFavorite: newFavoriteValue }); + }, + }, + ); + } else { + deleteMutation.mutate( + { + query: { + id: [data.id], + type: data.itemType, + }, + serverId: data.serverId, + }, + { + onSuccess: () => { + node.setData({ ...data, userFavorite: newFavoriteValue }); + }, + }, + ); + } + }; - return ( - <CellContainer position="center"> - <Button - compact - sx={{ - svg: { - fill: !value - ? 'var(--main-fg-secondary) !important' - : 'var(--primary-color) !important', - }, - }} - variant="subtle" - onClick={handleToggleFavorite} - > - {!value ? <RiHeartLine size="1.3em" /> : <RiHeartFill size="1.3em" />} - </Button> - </CellContainer> - ); + return ( + <CellContainer position="center"> + <Button + compact + sx={{ + svg: { + fill: !value + ? 'var(--main-fg-secondary) !important' + : 'var(--primary-color) !important', + }, + }} + variant="subtle" + onClick={handleToggleFavorite} + > + {!value ? <RiHeartLine size="1.3em" /> : <RiHeartFill size="1.3em" />} + </Button> + </CellContainer> + ); }; diff --git a/src/renderer/components/virtual-table/cells/full-width-disc-cell.tsx b/src/renderer/components/virtual-table/cells/full-width-disc-cell.tsx index 5119d1a9..92ab32fe 100644 --- a/src/renderer/components/virtual-table/cells/full-width-disc-cell.tsx +++ b/src/renderer/components/virtual-table/cells/full-width-disc-cell.tsx @@ -8,38 +8,38 @@ import { Paper } from '/@/renderer/components/paper'; import { getNodesByDiscNumber, setNodeSelection } from '../utils'; const Container = styled(Paper)` - padding: 0.5rem 1rem; - border: 1px solid transparent; + padding: 0.5rem 1rem; + border: 1px solid transparent; `; export const FullWidthDiscCell = ({ node, data, api }: ICellRendererParams) => { - const [isSelected, setIsSelected] = useState(false); + const [isSelected, setIsSelected] = useState(false); - const handleToggleDiscNodes = () => { - if (!data) return; - const discNumber = Number(node.data.id.split('-')[1]); - const nodes = getNodesByDiscNumber({ api, discNumber }); + const handleToggleDiscNodes = () => { + if (!data) return; + const discNumber = Number(node.data.id.split('-')[1]); + const nodes = getNodesByDiscNumber({ api, discNumber }); - setNodeSelection({ isSelected: !isSelected, nodes }); - setIsSelected((prev) => !prev); - }; + setNodeSelection({ isSelected: !isSelected, nodes }); + setIsSelected((prev) => !prev); + }; - return ( - <Container> - <Group - position="apart" - w="100%" - > - <Button - compact - leftIcon={isSelected ? <RiCheckboxLine /> : <RiCheckboxBlankLine />} - size="md" - variant="subtle" - onClick={handleToggleDiscNodes} - > - {data.name} - </Button> - </Group> - </Container> - ); + return ( + <Container> + <Group + position="apart" + w="100%" + > + <Button + compact + leftIcon={isSelected ? <RiCheckboxLine /> : <RiCheckboxBlankLine />} + size="md" + variant="subtle" + onClick={handleToggleDiscNodes} + > + {data.name} + </Button> + </Group> + </Container> + ); }; diff --git a/src/renderer/components/virtual-table/cells/generic-cell.tsx b/src/renderer/components/virtual-table/cells/generic-cell.tsx index f9d758d2..e61e9e01 100644 --- a/src/renderer/components/virtual-table/cells/generic-cell.tsx +++ b/src/renderer/components/virtual-table/cells/generic-cell.tsx @@ -6,79 +6,79 @@ import { Skeleton } from '/@/renderer/components/skeleton'; import { Text } from '/@/renderer/components/text'; export const CELL_VARIANTS: Variants = { - animate: { - opacity: 1, - }, - initial: { - opacity: 0, - }, + animate: { + opacity: 1, + }, + initial: { + opacity: 0, + }, }; export const CellContainer = styled(motion.div)<{ position?: 'left' | 'center' | 'right' }>` - display: flex; - align-items: center; - justify-content: ${(props) => - props.position === 'right' - ? 'flex-end' - : props.position === 'center' - ? 'center' - : 'flex-start'}; - width: 100%; - height: 100%; - letter-spacing: 0.5px; + display: flex; + align-items: center; + justify-content: ${(props) => + props.position === 'right' + ? 'flex-end' + : props.position === 'center' + ? 'center' + : 'flex-start'}; + width: 100%; + height: 100%; + letter-spacing: 0.5px; `; type Options = { - array?: boolean; - isArray?: boolean; - isLink?: boolean; - position?: 'left' | 'center' | 'right'; - primary?: boolean; + array?: boolean; + isArray?: boolean; + isLink?: boolean; + position?: 'left' | 'center' | 'right'; + primary?: boolean; }; export const GenericCell = ( - { value, valueFormatted }: ICellRendererParams, - { position, primary, isLink }: Options, + { value, valueFormatted }: ICellRendererParams, + { position, primary, isLink }: Options, ) => { - const displayedValue = valueFormatted || value; + const displayedValue = valueFormatted || value; + + if (value === undefined) { + return ( + <CellContainer position={position || 'left'}> + <Skeleton + height="1rem" + width="80%" + /> + </CellContainer> + ); + } - if (value === undefined) { return ( - <CellContainer position={position || 'left'}> - <Skeleton - height="1rem" - width="80%" - /> - </CellContainer> + <CellContainer position={position || 'left'}> + {isLink ? ( + <Text + $link={isLink} + $secondary={!primary} + component={Link} + overflow="hidden" + size="md" + to={displayedValue.link} + > + {isLink ? displayedValue.value : displayedValue} + </Text> + ) : ( + <Text + $secondary={!primary} + overflow="hidden" + size="md" + > + {displayedValue} + </Text> + )} + </CellContainer> ); - } - - return ( - <CellContainer position={position || 'left'}> - {isLink ? ( - <Text - $link={isLink} - $secondary={!primary} - component={Link} - overflow="hidden" - size="md" - to={displayedValue.link} - > - {isLink ? displayedValue.value : displayedValue} - </Text> - ) : ( - <Text - $secondary={!primary} - overflow="hidden" - size="md" - > - {displayedValue} - </Text> - )} - </CellContainer> - ); }; GenericCell.defaultProps = { - position: undefined, + position: undefined, }; diff --git a/src/renderer/components/virtual-table/cells/genre-cell.tsx b/src/renderer/components/virtual-table/cells/genre-cell.tsx index e0cb5b36..8fa66013 100644 --- a/src/renderer/components/virtual-table/cells/genre-cell.tsx +++ b/src/renderer/components/virtual-table/cells/genre-cell.tsx @@ -6,37 +6,37 @@ import { Text } from '/@/renderer/components/text'; import { CellContainer } from '/@/renderer/components/virtual-table/cells/generic-cell'; export const GenreCell = ({ value, data }: ICellRendererParams) => { - return ( - <CellContainer position="left"> - <Text - $secondary - overflow="hidden" - size="md" - > - {value?.map((item: Artist | AlbumArtist, index: number) => ( - <React.Fragment key={`row-${item.id}-${data.uniqueId}`}> - {index > 0 && ( - <Text - $secondary - size="md" - style={{ display: 'inline-block' }} - > - , - </Text> - )}{' '} + return ( + <CellContainer position="left"> <Text - $link - $secondary - component={Link} - overflow="hidden" - size="md" - to="/" + $secondary + overflow="hidden" + size="md" > - {item.name || '—'} + {value?.map((item: Artist | AlbumArtist, index: number) => ( + <React.Fragment key={`row-${item.id}-${data.uniqueId}`}> + {index > 0 && ( + <Text + $secondary + size="md" + style={{ display: 'inline-block' }} + > + , + </Text> + )}{' '} + <Text + $link + $secondary + component={Link} + overflow="hidden" + size="md" + to="/" + > + {item.name || '—'} + </Text> + </React.Fragment> + ))} </Text> - </React.Fragment> - ))} - </Text> - </CellContainer> - ); + </CellContainer> + ); }; diff --git a/src/renderer/components/virtual-table/cells/rating-cell.tsx b/src/renderer/components/virtual-table/cells/rating-cell.tsx index a6695540..e3b02368 100644 --- a/src/renderer/components/virtual-table/cells/rating-cell.tsx +++ b/src/renderer/components/virtual-table/cells/rating-cell.tsx @@ -6,54 +6,54 @@ import { CellContainer } from '/@/renderer/components/virtual-table/cells/generi import { useSetRating } from '/@/renderer/features/shared'; export const RatingCell = ({ value, node }: ICellRendererParams) => { - const updateRatingMutation = useSetRating({}); + const updateRatingMutation = useSetRating({}); - const handleUpdateRating = (rating: number) => { - if (!value) return; + const handleUpdateRating = (rating: number) => { + if (!value) return; - updateRatingMutation.mutate( - { - query: { - item: [value], - rating, - }, - serverId: value?.serverId, - }, - { - onSuccess: () => { - node.setData({ ...node.data, userRating: rating }); - }, - }, + updateRatingMutation.mutate( + { + query: { + item: [value], + rating, + }, + serverId: value?.serverId, + }, + { + onSuccess: () => { + node.setData({ ...node.data, userRating: rating }); + }, + }, + ); + }; + + const handleClearRating = (e: MouseEvent<HTMLDivElement>) => { + e.preventDefault(); + e.stopPropagation(); + updateRatingMutation.mutate( + { + query: { + item: [value], + rating: 0, + }, + serverId: value?.serverId, + }, + { + onSuccess: () => { + node.setData({ ...node.data, userRating: 0 }); + }, + }, + ); + }; + + return ( + <CellContainer position="center"> + <Rating + size="xs" + value={value?.userRating} + onChange={handleUpdateRating} + onClick={handleClearRating} + /> + </CellContainer> ); - }; - - const handleClearRating = (e: MouseEvent<HTMLDivElement>) => { - e.preventDefault(); - e.stopPropagation(); - updateRatingMutation.mutate( - { - query: { - item: [value], - rating: 0, - }, - serverId: value?.serverId, - }, - { - onSuccess: () => { - node.setData({ ...node.data, userRating: 0 }); - }, - }, - ); - }; - - return ( - <CellContainer position="center"> - <Rating - size="xs" - value={value?.userRating} - onChange={handleUpdateRating} - onClick={handleClearRating} - /> - </CellContainer> - ); }; diff --git a/src/renderer/components/virtual-table/headers/duration-header.tsx b/src/renderer/components/virtual-table/headers/duration-header.tsx index 8ec38b8c..3963e10d 100644 --- a/src/renderer/components/virtual-table/headers/duration-header.tsx +++ b/src/renderer/components/virtual-table/headers/duration-header.tsx @@ -2,9 +2,9 @@ import type { IHeaderParams } from '@ag-grid-community/core'; import { FiClock } from 'react-icons/fi'; export interface ICustomHeaderParams extends IHeaderParams { - menuIcon: string; + menuIcon: string; } export const DurationHeader = () => { - return <FiClock size={15} />; + return <FiClock size={15} />; }; diff --git a/src/renderer/components/virtual-table/headers/generic-table-header.tsx b/src/renderer/components/virtual-table/headers/generic-table-header.tsx index 62d55c0b..ce209102 100644 --- a/src/renderer/components/virtual-table/headers/generic-table-header.tsx +++ b/src/renderer/components/virtual-table/headers/generic-table-header.tsx @@ -9,84 +9,84 @@ import { _Text } from '/@/renderer/components/text'; type Presets = 'duration' | 'rowIndex' | 'userFavorite' | 'userRating'; type Options = { - children?: ReactNode; - position?: 'left' | 'center' | 'right'; - preset?: Presets; + children?: ReactNode; + position?: 'left' | 'center' | 'right'; + preset?: Presets; }; const HeaderWrapper = styled.div<{ position: Options['position'] }>` - display: flex; - justify-content: ${(props) => - props.position === 'right' - ? 'flex-end' - : props.position === 'center' - ? 'center' - : 'flex-start'}; - width: 100%; - font-family: var(--content-font-family); - text-transform: uppercase; + display: flex; + justify-content: ${(props) => + props.position === 'right' + ? 'flex-end' + : props.position === 'center' + ? 'center' + : 'flex-start'}; + width: 100%; + font-family: var(--content-font-family); + text-transform: uppercase; `; const TextHeaderWrapper = styled(_Text)<{ position: Options['position'] }>` - width: 100%; - color: var(--ag-header-foreground-color); - font-weight: 500; - text-align: ${(props) => - props.position === 'right' - ? 'flex-end' - : props.position === 'center' - ? 'center' - : 'flex-start'}; - text-transform: uppercase; + width: 100%; + color: var(--ag-header-foreground-color); + font-weight: 500; + text-align: ${(props) => + props.position === 'right' + ? 'flex-end' + : props.position === 'center' + ? 'center' + : 'flex-start'}; + text-transform: uppercase; `; const headerPresets = { - duration: ( - <FiClock - color="var(--ag-header-foreground-color)" - size="1em" - /> - ), - rowIndex: ( - <AiOutlineNumber - color="var(--ag-header-foreground-color)" - size="1em" - /> - ), - userFavorite: ( - <RiHeartLine - color="var(--ag-header-foreground-color)" - size="1em" - /> - ), - userRating: ( - <RiStarLine - color="var(--ag-header-foreground-color)" - size="1em" - /> - ), + duration: ( + <FiClock + color="var(--ag-header-foreground-color)" + size="1em" + /> + ), + rowIndex: ( + <AiOutlineNumber + color="var(--ag-header-foreground-color)" + size="1em" + /> + ), + userFavorite: ( + <RiHeartLine + color="var(--ag-header-foreground-color)" + size="1em" + /> + ), + userRating: ( + <RiStarLine + color="var(--ag-header-foreground-color)" + size="1em" + /> + ), }; export const GenericTableHeader = ( - { displayName }: IHeaderParams, - { preset, children, position }: Options, + { displayName }: IHeaderParams, + { preset, children, position }: Options, ) => { - if (preset) { - return <HeaderWrapper position={position}>{headerPresets[preset]}</HeaderWrapper>; - } + if (preset) { + return <HeaderWrapper position={position}>{headerPresets[preset]}</HeaderWrapper>; + } - return ( - <TextHeaderWrapper - overflow="hidden" - position={position} - weight={500} - > - {children || displayName} - </TextHeaderWrapper> - ); + return ( + <TextHeaderWrapper + overflow="hidden" + position={position} + weight={500} + > + {children || displayName} + </TextHeaderWrapper> + ); }; GenericTableHeader.defaultProps = { - position: 'left', - preset: undefined, + position: 'left', + preset: undefined, }; diff --git a/src/renderer/components/virtual-table/hooks/use-click-outside-deselect.tsx b/src/renderer/components/virtual-table/hooks/use-click-outside-deselect.tsx index c0f21108..1a8f959a 100644 --- a/src/renderer/components/virtual-table/hooks/use-click-outside-deselect.tsx +++ b/src/renderer/components/virtual-table/hooks/use-click-outside-deselect.tsx @@ -3,13 +3,13 @@ import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/li import { useClickOutside } from '@mantine/hooks'; export const useClickOutsideDeselect = (tableRef: MutableRefObject<AgGridReactType | null>) => { - const handleDeselect = () => { - if (tableRef.current) { - tableRef.current.api.deselectAll(); - } - }; + const handleDeselect = () => { + if (tableRef.current) { + tableRef.current.api.deselectAll(); + } + }; - const ref = useClickOutside(handleDeselect); + const ref = useClickOutside(handleDeselect); - return ref; + return ref; }; diff --git a/src/renderer/components/virtual-table/hooks/use-fixed-table-header.tsx b/src/renderer/components/virtual-table/hooks/use-fixed-table-header.tsx index eaa829c2..b2d23c09 100644 --- a/src/renderer/components/virtual-table/hooks/use-fixed-table-header.tsx +++ b/src/renderer/components/virtual-table/hooks/use-fixed-table-header.tsx @@ -4,39 +4,39 @@ import { useWindowSettings } from '/@/renderer/store/settings.store'; import { Platform } from '/@/renderer/types'; export const useFixedTableHeader = () => { - const intersectRef = useRef<HTMLDivElement | null>(null); - const tableContainerRef = useRef<HTMLDivElement | null>(null); - const { windowBarStyle } = useWindowSettings(); + const intersectRef = useRef<HTMLDivElement | null>(null); + const tableContainerRef = useRef<HTMLDivElement | null>(null); + const { windowBarStyle } = useWindowSettings(); - const isNotPastTableIntersection = useInView(intersectRef, { - margin: - windowBarStyle === Platform.WEB || windowBarStyle === Platform.LINUX - ? '-68px 0px 0px 0px' - : '-98px 0px 0px 0px', - }); + const isNotPastTableIntersection = useInView(intersectRef, { + margin: + windowBarStyle === Platform.WEB || windowBarStyle === Platform.LINUX + ? '-68px 0px 0px 0px' + : '-98px 0px 0px 0px', + }); - const tableInView = useInView(tableContainerRef, { - margin: '-128px 0px 0px 0px', - }); + const tableInView = useInView(tableContainerRef, { + margin: '-128px 0px 0px 0px', + }); - useEffect(() => { - const header = document.querySelector('main .ag-header'); - const root = document.querySelector('main .ag-root'); + useEffect(() => { + const header = document.querySelector('main .ag-header'); + const root = document.querySelector('main .ag-root'); - if (isNotPastTableIntersection || !tableInView) { - if (windowBarStyle === Platform.WINDOWS || windowBarStyle === Platform.MACOS) { - header?.classList.remove('window-frame'); - } - header?.classList.remove('ag-header-fixed'); - root?.classList.remove('ag-header-fixed-margin'); - } else { - if (windowBarStyle === Platform.WINDOWS || windowBarStyle === Platform.MACOS) { - header?.classList.add('window-frame'); - } - header?.classList.add('ag-header-fixed'); - root?.classList.add('ag-header-fixed-margin'); - } - }, [isNotPastTableIntersection, tableInView, windowBarStyle]); + if (isNotPastTableIntersection || !tableInView) { + if (windowBarStyle === Platform.WINDOWS || windowBarStyle === Platform.MACOS) { + header?.classList.remove('window-frame'); + } + header?.classList.remove('ag-header-fixed'); + root?.classList.remove('ag-header-fixed-margin'); + } else { + if (windowBarStyle === Platform.WINDOWS || windowBarStyle === Platform.MACOS) { + header?.classList.add('window-frame'); + } + header?.classList.add('ag-header-fixed'); + root?.classList.add('ag-header-fixed-margin'); + } + }, [isNotPastTableIntersection, tableInView, windowBarStyle]); - return { intersectRef, tableContainerRef }; + return { intersectRef, tableContainerRef }; }; diff --git a/src/renderer/components/virtual-table/hooks/use-rating.ts b/src/renderer/components/virtual-table/hooks/use-rating.ts index 9543dcfa..6cc1a35d 100644 --- a/src/renderer/components/virtual-table/hooks/use-rating.ts +++ b/src/renderer/components/virtual-table/hooks/use-rating.ts @@ -5,121 +5,126 @@ import { NDAlbumDetail, NDAlbumArtistDetail } from '/@/renderer/api/navidrome.ty import { queryKeys } from '/@/renderer/api/query-keys'; import { SSAlbumDetail, SSAlbumArtistDetail } from '/@/renderer/api/subsonic.types'; import { - SetRatingArgs, - Album, - AlbumArtist, - LibraryItem, - AnyLibraryItems, - RatingResponse, + SetRatingArgs, + Album, + AlbumArtist, + LibraryItem, + AnyLibraryItems, + RatingResponse, } from '/@/renderer/api/types'; import { useSetAlbumListItemDataById, useSetQueueRating, getServerById } from '/@/renderer/store'; import { ServerType } from '/@/renderer/types'; export const useUpdateRating = () => { - const queryClient = useQueryClient(); - const setAlbumListData = useSetAlbumListItemDataById(); - const setQueueRating = useSetQueueRating(); + const queryClient = useQueryClient(); + const setAlbumListData = useSetAlbumListItemDataById(); + const setQueueRating = useSetQueueRating(); - return useMutation< - RatingResponse, - AxiosError, - Omit<SetRatingArgs, 'server' | 'apiClientProps'>, - { previous: { items: AnyLibraryItems } | undefined } - >({ - mutationFn: (args) => { - const server = getServerById(args.serverId); - if (!server) throw new Error('Server not found'); - return api.controller.updateRating({ ...args, apiClientProps: { server } }); - }, - onError: (_error, _variables, context) => { - for (const item of context?.previous?.items || []) { - switch (item.itemType) { - case LibraryItem.ALBUM: - setAlbumListData(item.id, { userRating: item.userRating }); - break; - case LibraryItem.SONG: - setQueueRating([item.id], item.userRating); - break; - } - } - }, - onMutate: (variables) => { - for (const item of variables.query.item) { - switch (item.itemType) { - case LibraryItem.ALBUM: - setAlbumListData(item.id, { userRating: variables.query.rating }); - break; - case LibraryItem.SONG: - setQueueRating([item.id], variables.query.rating); - break; - } - } + return useMutation< + RatingResponse, + AxiosError, + Omit<SetRatingArgs, 'server' | 'apiClientProps'>, + { previous: { items: AnyLibraryItems } | undefined } + >({ + mutationFn: (args) => { + const server = getServerById(args.serverId); + if (!server) throw new Error('Server not found'); + return api.controller.updateRating({ ...args, apiClientProps: { server } }); + }, + onError: (_error, _variables, context) => { + for (const item of context?.previous?.items || []) { + switch (item.itemType) { + case LibraryItem.ALBUM: + setAlbumListData(item.id, { userRating: item.userRating }); + break; + case LibraryItem.SONG: + setQueueRating([item.id], item.userRating); + break; + } + } + }, + onMutate: (variables) => { + for (const item of variables.query.item) { + switch (item.itemType) { + case LibraryItem.ALBUM: + setAlbumListData(item.id, { userRating: variables.query.rating }); + break; + case LibraryItem.SONG: + setQueueRating([item.id], variables.query.rating); + break; + } + } - return { previous: { items: variables.query.item } }; - }, - onSuccess: (_data, variables) => { - // We only need to set if we're already on the album detail page - const isAlbumDetailPage = - variables.query.item.length === 1 && variables.query.item[0].itemType === LibraryItem.ALBUM; + return { previous: { items: variables.query.item } }; + }, + onSuccess: (_data, variables) => { + // We only need to set if we're already on the album detail page + const isAlbumDetailPage = + variables.query.item.length === 1 && + variables.query.item[0].itemType === LibraryItem.ALBUM; - if (isAlbumDetailPage) { - const { serverType, id: albumId, serverId } = variables.query.item[0] as Album; + if (isAlbumDetailPage) { + const { serverType, id: albumId, serverId } = variables.query.item[0] as Album; - const queryKey = queryKeys.albums.detail(serverId || '', { id: albumId }); - const previous = queryClient.getQueryData<any>(queryKey); - if (previous) { - switch (serverType) { - case ServerType.NAVIDROME: - queryClient.setQueryData<NDAlbumDetail>(queryKey, { - ...previous, - userRating: variables.query.rating, - }); - break; - case ServerType.SUBSONIC: - queryClient.setQueryData<SSAlbumDetail>(queryKey, { - ...previous, - userRating: variables.query.rating, - }); - break; - case ServerType.JELLYFIN: - // Jellyfin does not support ratings - break; - } - } - } + const queryKey = queryKeys.albums.detail(serverId || '', { id: albumId }); + const previous = queryClient.getQueryData<any>(queryKey); + if (previous) { + switch (serverType) { + case ServerType.NAVIDROME: + queryClient.setQueryData<NDAlbumDetail>(queryKey, { + ...previous, + userRating: variables.query.rating, + }); + break; + case ServerType.SUBSONIC: + queryClient.setQueryData<SSAlbumDetail>(queryKey, { + ...previous, + userRating: variables.query.rating, + }); + break; + case ServerType.JELLYFIN: + // Jellyfin does not support ratings + break; + } + } + } - // We only need to set if we're already on the album detail page - const isAlbumArtistDetailPage = - variables.query.item.length === 1 && - variables.query.item[0].itemType === LibraryItem.ALBUM_ARTIST; + // We only need to set if we're already on the album detail page + const isAlbumArtistDetailPage = + variables.query.item.length === 1 && + variables.query.item[0].itemType === LibraryItem.ALBUM_ARTIST; - if (isAlbumArtistDetailPage) { - const { serverType, id: albumArtistId, serverId } = variables.query.item[0] as AlbumArtist; + if (isAlbumArtistDetailPage) { + const { + serverType, + id: albumArtistId, + serverId, + } = variables.query.item[0] as AlbumArtist; - const queryKey = queryKeys.albumArtists.detail(serverId || '', { - id: albumArtistId, - }); - const previous = queryClient.getQueryData<any>(queryKey); - if (previous) { - switch (serverType) { - case ServerType.NAVIDROME: - queryClient.setQueryData<NDAlbumArtistDetail>(queryKey, { - ...previous, - userRating: variables.query.rating, - }); - break; - case ServerType.SUBSONIC: - queryClient.setQueryData<SSAlbumArtistDetail>(queryKey, { - ...previous, - userRating: variables.query.rating, - }); - break; - case ServerType.JELLYFIN: - // Jellyfin does not support ratings - break; - } - } - } - }, - }); + const queryKey = queryKeys.albumArtists.detail(serverId || '', { + id: albumArtistId, + }); + const previous = queryClient.getQueryData<any>(queryKey); + if (previous) { + switch (serverType) { + case ServerType.NAVIDROME: + queryClient.setQueryData<NDAlbumArtistDetail>(queryKey, { + ...previous, + userRating: variables.query.rating, + }); + break; + case ServerType.SUBSONIC: + queryClient.setQueryData<SSAlbumArtistDetail>(queryKey, { + ...previous, + userRating: variables.query.rating, + }); + break; + case ServerType.JELLYFIN: + // Jellyfin does not support ratings + break; + } + } + } + }, + }); }; diff --git a/src/renderer/components/virtual-table/index.tsx b/src/renderer/components/virtual-table/index.tsx index 16f74bd4..dfd24304 100644 --- a/src/renderer/components/virtual-table/index.tsx +++ b/src/renderer/components/virtual-table/index.tsx @@ -1,16 +1,16 @@ /* eslint-disable import/no-cycle */ import { Ref, forwardRef, useRef, useEffect, useCallback, useMemo } from 'react'; import type { - ICellRendererParams, - ValueGetterParams, - IHeaderParams, - ValueFormatterParams, - ColDef, - ColumnMovedEvent, - NewColumnsLoadedEvent, - GridReadyEvent, - GridSizeChangedEvent, - ModelUpdatedEvent, + ICellRendererParams, + ValueGetterParams, + IHeaderParams, + ValueFormatterParams, + ColDef, + ColumnMovedEvent, + NewColumnsLoadedEvent, + GridReadyEvent, + GridSizeChangedEvent, + ModelUpdatedEvent, } from '@ag-grid-community/core'; import type { AgGridReactProps } from '@ag-grid-community/react'; import { AgGridReact } from '@ag-grid-community/react'; @@ -40,428 +40,453 @@ export * from './hooks/use-click-outside-deselect'; export * from './utils'; const TableWrapper = styled.div` - display: flex; - flex-direction: column; - width: 100%; - height: 100%; + display: flex; + flex-direction: column; + width: 100%; + height: 100%; `; dayjs.extend(relativeTime); const tableColumns: { [key: string]: ColDef } = { - album: { - cellRenderer: (params: ICellRendererParams) => - GenericCell(params, { isLink: true, position: 'left' }), - colId: TableColumn.ALBUM, - headerName: 'Album', - valueGetter: (params: ValueGetterParams) => - params.data - ? { - link: generatePath(AppRoute.LIBRARY_ALBUMS_DETAIL, { - albumId: params.data?.albumId || '', - }), - value: params.data?.album, - } - : undefined, - width: 200, - }, - albumArtist: { - cellRenderer: AlbumArtistCell, - colId: TableColumn.ALBUM_ARTIST, - headerName: 'Album Artist', - valueGetter: (params: ValueGetterParams) => - params.data ? params.data.albumArtists : undefined, - width: 150, - }, - albumCount: { - cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), - colId: TableColumn.ALBUM_COUNT, - field: 'albumCount', - headerComponent: (params: IHeaderParams) => GenericTableHeader(params, { position: 'center' }), - headerName: 'Albums', - suppressSizeToFit: true, - valueGetter: (params: ValueGetterParams) => (params.data ? params.data.albumCount : undefined), - width: 80, - }, - artist: { - cellRenderer: ArtistCell, - colId: TableColumn.ARTIST, - headerName: 'Artist', - valueGetter: (params: ValueGetterParams) => (params.data ? params.data.artists : undefined), - width: 150, - }, - biography: { - cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'left' }), - colId: TableColumn.BIOGRAPHY, - field: 'biography', - headerName: 'Biography', - valueGetter: (params: ValueGetterParams) => (params.data ? params.data.biography : ''), - width: 200, - }, - bitRate: { - cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), - colId: TableColumn.BIT_RATE, - field: 'bitRate', - headerComponent: (params: IHeaderParams) => GenericTableHeader(params, { position: 'center' }), - suppressSizeToFit: true, - valueFormatter: (params: ValueFormatterParams) => `${params.value} kbps`, - valueGetter: (params: ValueGetterParams) => (params.data ? params.data.bitRate : undefined), - width: 90, - }, - bpm: { - cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), - colId: TableColumn.BPM, - headerComponent: (params: IHeaderParams) => GenericTableHeader(params, { position: 'center' }), - headerName: 'BPM', - suppressSizeToFit: true, - valueGetter: (params: ValueGetterParams) => (params.data ? params.data.bpm : undefined), - width: 60, - }, - channels: { - cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), - colId: TableColumn.CHANNELS, - field: 'channels', - headerComponent: (params: IHeaderParams) => GenericTableHeader(params, { position: 'center' }), - valueGetter: (params: ValueGetterParams) => (params.data ? params.data.channels : undefined), - width: 100, - }, - comment: { - cellRenderer: GenericCell, - colId: TableColumn.COMMENT, - headerName: 'Note', - valueGetter: (params: ValueGetterParams) => (params.data ? params.data.comment : undefined), - width: 150, - }, - dateAdded: { - cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), - colId: TableColumn.DATE_ADDED, - field: 'createdAt', - headerComponent: (params: IHeaderParams) => GenericTableHeader(params, { position: 'center' }), - headerName: 'Date Added', - suppressSizeToFit: true, - valueFormatter: (params: ValueFormatterParams) => - params.value ? dayjs(params.value).format('MMM D, YYYY') : '', - valueGetter: (params: ValueGetterParams) => (params.data ? params.data.createdAt : undefined), - width: 130, - }, - discNumber: { - cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), - colId: TableColumn.DISC_NUMBER, - field: 'discNumber', - headerComponent: (params: IHeaderParams) => GenericTableHeader(params, { position: 'center' }), - headerName: 'Disc', - suppressSizeToFit: true, - valueGetter: (params: ValueGetterParams) => (params.data ? params.data.discNumber : undefined), - width: 60, - }, - duration: { - cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), - colId: TableColumn.DURATION, - field: 'duration', - headerComponent: (params: IHeaderParams) => - GenericTableHeader(params, { position: 'center', preset: 'duration' }), - suppressSizeToFit: true, - valueFormatter: (params: ValueFormatterParams) => formatDuration(params.value * 1000), - valueGetter: (params: ValueGetterParams) => (params.data ? params.data.duration : undefined), - width: 70, - }, - genre: { - cellRenderer: GenreCell, - colId: TableColumn.GENRE, - headerName: 'Genre', - valueGetter: (params: ValueGetterParams) => (params.data ? params.data.genres : undefined), - width: 100, - }, - lastPlayedAt: { - cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), - colId: TableColumn.LAST_PLAYED, - headerComponent: (params: IHeaderParams) => GenericTableHeader(params, { position: 'center' }), - headerName: 'Last Played', - valueFormatter: (params: ValueFormatterParams) => - params.value ? dayjs(params.value).fromNow() : '', - valueGetter: (params: ValueGetterParams) => - params.data ? params.data.lastPlayedAt : undefined, - width: 130, - }, - path: { - cellRenderer: GenericCell, - colId: TableColumn.PATH, - headerName: 'Path', - valueGetter: (params: ValueGetterParams) => (params.data ? params.data.path : undefined), - width: 200, - }, - playCount: { - cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), - colId: TableColumn.PLAY_COUNT, - field: 'playCount', - headerComponent: (params: IHeaderParams) => GenericTableHeader(params, { position: 'center' }), - headerName: 'Plays', - suppressSizeToFit: true, - valueGetter: (params: ValueGetterParams) => (params.data ? params.data.playCount : undefined), - width: 90, - }, - releaseDate: { - cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), - colId: TableColumn.RELEASE_DATE, - field: 'releaseDate', - headerComponent: (params: IHeaderParams) => GenericTableHeader(params, { position: 'center' }), - headerName: 'Release Date', - suppressSizeToFit: true, - valueFormatter: (params: ValueFormatterParams) => - params.value ? dayjs(params.value).format('MMM D, YYYY') : '', - valueGetter: (params: ValueGetterParams) => (params.data ? params.data.releaseDate : undefined), - width: 130, - }, - releaseYear: { - cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), - colId: TableColumn.YEAR, - field: 'releaseYear', - headerComponent: (params: IHeaderParams) => GenericTableHeader(params, { position: 'center' }), - headerName: 'Year', - suppressSizeToFit: true, - valueGetter: (params: ValueGetterParams) => (params.data ? params.data.releaseYear : undefined), - width: 80, - }, - rowIndex: { - cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'right' }), - colId: TableColumn.ROW_INDEX, - headerComponent: (params: IHeaderParams) => - GenericTableHeader(params, { position: 'right', preset: 'rowIndex' }), - suppressSizeToFit: true, - valueGetter: (params) => { - return (params.node?.rowIndex || 0) + 1; + album: { + cellRenderer: (params: ICellRendererParams) => + GenericCell(params, { isLink: true, position: 'left' }), + colId: TableColumn.ALBUM, + headerName: 'Album', + valueGetter: (params: ValueGetterParams) => + params.data + ? { + link: generatePath(AppRoute.LIBRARY_ALBUMS_DETAIL, { + albumId: params.data?.albumId || '', + }), + value: params.data?.album, + } + : undefined, + width: 200, + }, + albumArtist: { + cellRenderer: AlbumArtistCell, + colId: TableColumn.ALBUM_ARTIST, + headerName: 'Album Artist', + valueGetter: (params: ValueGetterParams) => + params.data ? params.data.albumArtists : undefined, + width: 150, + }, + albumCount: { + cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), + colId: TableColumn.ALBUM_COUNT, + field: 'albumCount', + headerComponent: (params: IHeaderParams) => + GenericTableHeader(params, { position: 'center' }), + headerName: 'Albums', + suppressSizeToFit: true, + valueGetter: (params: ValueGetterParams) => + params.data ? params.data.albumCount : undefined, + width: 80, + }, + artist: { + cellRenderer: ArtistCell, + colId: TableColumn.ARTIST, + headerName: 'Artist', + valueGetter: (params: ValueGetterParams) => (params.data ? params.data.artists : undefined), + width: 150, + }, + biography: { + cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'left' }), + colId: TableColumn.BIOGRAPHY, + field: 'biography', + headerName: 'Biography', + valueGetter: (params: ValueGetterParams) => (params.data ? params.data.biography : ''), + width: 200, + }, + bitRate: { + cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), + colId: TableColumn.BIT_RATE, + field: 'bitRate', + headerComponent: (params: IHeaderParams) => + GenericTableHeader(params, { position: 'center' }), + suppressSizeToFit: true, + valueFormatter: (params: ValueFormatterParams) => `${params.value} kbps`, + valueGetter: (params: ValueGetterParams) => (params.data ? params.data.bitRate : undefined), + width: 90, + }, + bpm: { + cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), + colId: TableColumn.BPM, + headerComponent: (params: IHeaderParams) => + GenericTableHeader(params, { position: 'center' }), + headerName: 'BPM', + suppressSizeToFit: true, + valueGetter: (params: ValueGetterParams) => (params.data ? params.data.bpm : undefined), + width: 60, + }, + channels: { + cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), + colId: TableColumn.CHANNELS, + field: 'channels', + headerComponent: (params: IHeaderParams) => + GenericTableHeader(params, { position: 'center' }), + valueGetter: (params: ValueGetterParams) => + params.data ? params.data.channels : undefined, + width: 100, + }, + comment: { + cellRenderer: GenericCell, + colId: TableColumn.COMMENT, + headerName: 'Note', + valueGetter: (params: ValueGetterParams) => (params.data ? params.data.comment : undefined), + width: 150, + }, + dateAdded: { + cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), + colId: TableColumn.DATE_ADDED, + field: 'createdAt', + headerComponent: (params: IHeaderParams) => + GenericTableHeader(params, { position: 'center' }), + headerName: 'Date Added', + suppressSizeToFit: true, + valueFormatter: (params: ValueFormatterParams) => + params.value ? dayjs(params.value).format('MMM D, YYYY') : '', + valueGetter: (params: ValueGetterParams) => + params.data ? params.data.createdAt : undefined, + width: 130, + }, + discNumber: { + cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), + colId: TableColumn.DISC_NUMBER, + field: 'discNumber', + headerComponent: (params: IHeaderParams) => + GenericTableHeader(params, { position: 'center' }), + headerName: 'Disc', + suppressSizeToFit: true, + valueGetter: (params: ValueGetterParams) => + params.data ? params.data.discNumber : undefined, + width: 60, + }, + duration: { + cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), + colId: TableColumn.DURATION, + field: 'duration', + headerComponent: (params: IHeaderParams) => + GenericTableHeader(params, { position: 'center', preset: 'duration' }), + suppressSizeToFit: true, + valueFormatter: (params: ValueFormatterParams) => formatDuration(params.value * 1000), + valueGetter: (params: ValueGetterParams) => + params.data ? params.data.duration : undefined, + width: 70, + }, + genre: { + cellRenderer: GenreCell, + colId: TableColumn.GENRE, + headerName: 'Genre', + valueGetter: (params: ValueGetterParams) => (params.data ? params.data.genres : undefined), + width: 100, + }, + lastPlayedAt: { + cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), + colId: TableColumn.LAST_PLAYED, + headerComponent: (params: IHeaderParams) => + GenericTableHeader(params, { position: 'center' }), + headerName: 'Last Played', + valueFormatter: (params: ValueFormatterParams) => + params.value ? dayjs(params.value).fromNow() : '', + valueGetter: (params: ValueGetterParams) => + params.data ? params.data.lastPlayedAt : undefined, + width: 130, + }, + path: { + cellRenderer: GenericCell, + colId: TableColumn.PATH, + headerName: 'Path', + valueGetter: (params: ValueGetterParams) => (params.data ? params.data.path : undefined), + width: 200, + }, + playCount: { + cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), + colId: TableColumn.PLAY_COUNT, + field: 'playCount', + headerComponent: (params: IHeaderParams) => + GenericTableHeader(params, { position: 'center' }), + headerName: 'Plays', + suppressSizeToFit: true, + valueGetter: (params: ValueGetterParams) => + params.data ? params.data.playCount : undefined, + width: 90, + }, + releaseDate: { + cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), + colId: TableColumn.RELEASE_DATE, + field: 'releaseDate', + headerComponent: (params: IHeaderParams) => + GenericTableHeader(params, { position: 'center' }), + headerName: 'Release Date', + suppressSizeToFit: true, + valueFormatter: (params: ValueFormatterParams) => + params.value ? dayjs(params.value).format('MMM D, YYYY') : '', + valueGetter: (params: ValueGetterParams) => + params.data ? params.data.releaseDate : undefined, + width: 130, + }, + releaseYear: { + cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), + colId: TableColumn.YEAR, + field: 'releaseYear', + headerComponent: (params: IHeaderParams) => + GenericTableHeader(params, { position: 'center' }), + headerName: 'Year', + suppressSizeToFit: true, + valueGetter: (params: ValueGetterParams) => + params.data ? params.data.releaseYear : undefined, + width: 80, + }, + rowIndex: { + cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'right' }), + colId: TableColumn.ROW_INDEX, + headerComponent: (params: IHeaderParams) => + GenericTableHeader(params, { position: 'right', preset: 'rowIndex' }), + suppressSizeToFit: true, + valueGetter: (params) => { + return (params.node?.rowIndex || 0) + 1; + }, + width: 65, + }, + songCount: { + cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), + colId: TableColumn.SONG_COUNT, + field: 'songCount', + headerComponent: (params: IHeaderParams) => + GenericTableHeader(params, { position: 'center' }), + headerName: 'Songs', + suppressSizeToFit: true, + valueGetter: (params: ValueGetterParams) => + params.data ? params.data.songCount : undefined, + width: 80, + }, + title: { + cellRenderer: (params: ICellRendererParams) => + GenericCell(params, { position: 'left', primary: true }), + colId: TableColumn.TITLE, + field: 'name', + headerName: 'Title', + valueGetter: (params: ValueGetterParams) => (params.data ? params.data.name : undefined), + width: 250, + }, + titleCombined: { + cellRenderer: CombinedTitleCell, + colId: TableColumn.TITLE_COMBINED, + headerName: 'Title', + initialWidth: 500, + minWidth: 150, + valueGetter: (params: ValueGetterParams) => + params.data + ? { + albumArtists: params.data?.albumArtists, + artists: params.data?.artists, + imagePlaceholderUrl: params.data?.imagePlaceholderUrl, + imageUrl: params.data?.imageUrl, + name: params.data?.name, + rowHeight: params.node?.rowHeight, + type: params.data?.serverType, + } + : undefined, + width: 250, + }, + trackNumber: { + cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), + colId: TableColumn.TRACK_NUMBER, + field: 'trackNumber', + headerComponent: (params: IHeaderParams) => + GenericTableHeader(params, { position: 'center' }), + headerName: 'Track', + suppressSizeToFit: true, + valueGetter: (params: ValueGetterParams) => + params.data ? params.data.trackNumber : undefined, + width: 80, + }, + userFavorite: { + cellClass: (params) => (params.value ? 'visible ag-cell-favorite' : 'ag-cell-favorite'), + cellRenderer: FavoriteCell, + colId: TableColumn.USER_FAVORITE, + field: 'userFavorite', + headerComponent: (params: IHeaderParams) => + GenericTableHeader(params, { position: 'center', preset: 'userFavorite' }), + headerName: 'Favorite', + suppressSizeToFit: true, + valueGetter: (params: ValueGetterParams) => + params.data ? params.data.userFavorite : undefined, + width: 50, + }, + userRating: { + cellClass: (params) => + params.value?.userRating ? 'visible ag-cell-rating' : 'ag-cell-rating', + cellRenderer: RatingCell, + colId: TableColumn.USER_RATING, + field: 'userRating', + headerComponent: (params: IHeaderParams) => + GenericTableHeader(params, { position: 'center', preset: 'userRating' }), + headerName: 'Rating', + suppressSizeToFit: true, + valueGetter: (params: ValueGetterParams) => (params.data ? params.data : undefined), + width: 95, }, - width: 65, - }, - songCount: { - cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), - colId: TableColumn.SONG_COUNT, - field: 'songCount', - headerComponent: (params: IHeaderParams) => GenericTableHeader(params, { position: 'center' }), - headerName: 'Songs', - suppressSizeToFit: true, - valueGetter: (params: ValueGetterParams) => (params.data ? params.data.songCount : undefined), - width: 80, - }, - title: { - cellRenderer: (params: ICellRendererParams) => - GenericCell(params, { position: 'left', primary: true }), - colId: TableColumn.TITLE, - field: 'name', - headerName: 'Title', - valueGetter: (params: ValueGetterParams) => (params.data ? params.data.name : undefined), - width: 250, - }, - titleCombined: { - cellRenderer: CombinedTitleCell, - colId: TableColumn.TITLE_COMBINED, - headerName: 'Title', - initialWidth: 500, - minWidth: 150, - valueGetter: (params: ValueGetterParams) => - params.data - ? { - albumArtists: params.data?.albumArtists, - artists: params.data?.artists, - imagePlaceholderUrl: params.data?.imagePlaceholderUrl, - imageUrl: params.data?.imageUrl, - name: params.data?.name, - rowHeight: params.node?.rowHeight, - type: params.data?.serverType, - } - : undefined, - width: 250, - }, - trackNumber: { - cellRenderer: (params: ICellRendererParams) => GenericCell(params, { position: 'center' }), - colId: TableColumn.TRACK_NUMBER, - field: 'trackNumber', - headerComponent: (params: IHeaderParams) => GenericTableHeader(params, { position: 'center' }), - headerName: 'Track', - suppressSizeToFit: true, - valueGetter: (params: ValueGetterParams) => (params.data ? params.data.trackNumber : undefined), - width: 80, - }, - userFavorite: { - cellClass: (params) => (params.value ? 'visible ag-cell-favorite' : 'ag-cell-favorite'), - cellRenderer: FavoriteCell, - colId: TableColumn.USER_FAVORITE, - field: 'userFavorite', - headerComponent: (params: IHeaderParams) => - GenericTableHeader(params, { position: 'center', preset: 'userFavorite' }), - headerName: 'Favorite', - suppressSizeToFit: true, - valueGetter: (params: ValueGetterParams) => - params.data ? params.data.userFavorite : undefined, - width: 50, - }, - userRating: { - cellClass: (params) => (params.value?.userRating ? 'visible ag-cell-rating' : 'ag-cell-rating'), - cellRenderer: RatingCell, - colId: TableColumn.USER_RATING, - field: 'userRating', - headerComponent: (params: IHeaderParams) => - GenericTableHeader(params, { position: 'center', preset: 'userRating' }), - headerName: 'Rating', - suppressSizeToFit: true, - valueGetter: (params: ValueGetterParams) => (params.data ? params.data : undefined), - width: 95, - }, }; export const getColumnDef = (column: TableColumn) => { - return tableColumns[column as keyof typeof tableColumns]; + return tableColumns[column as keyof typeof tableColumns]; }; export const getColumnDefs = (columns: PersistedTableColumn[]) => { - const columnDefs: ColDef[] = []; - for (const column of columns) { - const presetColumn = tableColumns[column.column as keyof typeof tableColumns]; - if (presetColumn) { - columnDefs.push({ - ...presetColumn, - initialWidth: column.width, - ...column.extraProps, - }); + const columnDefs: ColDef[] = []; + for (const column of columns) { + const presetColumn = tableColumns[column.column as keyof typeof tableColumns]; + if (presetColumn) { + columnDefs.push({ + ...presetColumn, + initialWidth: column.width, + ...column.extraProps, + }); + } } - } - return columnDefs; + return columnDefs; }; interface VirtualTableProps extends AgGridReactProps { - autoFitColumns?: boolean; - autoHeight?: boolean; - deselectOnClickOutside?: boolean; - transparentHeader?: boolean; + autoFitColumns?: boolean; + autoHeight?: boolean; + deselectOnClickOutside?: boolean; + transparentHeader?: boolean; } export const VirtualTable = forwardRef( - ( - { - autoFitColumns, - deselectOnClickOutside, - autoHeight, - transparentHeader, - onColumnMoved, - onNewColumnsLoaded, - onGridReady, - onGridSizeChanged, - ...rest - }: VirtualTableProps, - ref: Ref<AgGridReactType | null>, - ) => { - const tableRef = useRef<AgGridReactType | null>(null); + ( + { + autoFitColumns, + deselectOnClickOutside, + autoHeight, + transparentHeader, + onColumnMoved, + onNewColumnsLoaded, + onGridReady, + onGridSizeChanged, + ...rest + }: VirtualTableProps, + ref: Ref<AgGridReactType | null>, + ) => { + const tableRef = useRef<AgGridReactType | null>(null); - const mergedRef = useMergedRef(ref, tableRef); + const mergedRef = useMergedRef(ref, tableRef); - const deselectRef = useClickOutside(() => { - if (tableRef?.current?.api && deselectOnClickOutside) { - tableRef?.current?.api?.deselectAll(); - } - }); + const deselectRef = useClickOutside(() => { + if (tableRef?.current?.api && deselectOnClickOutside) { + tableRef?.current?.api?.deselectAll(); + } + }); - const defaultColumnDefs: ColDef = useMemo(() => { - return { - lockPinned: true, - lockVisible: true, - resizable: true, - }; - }, []); + const defaultColumnDefs: ColDef = useMemo(() => { + return { + lockPinned: true, + lockVisible: true, + resizable: true, + }; + }, []); - // Auto fit columns on column change - useEffect(() => { - if (!tableRef?.current?.api) return; - if (autoFitColumns && tableRef?.current?.api) { - tableRef?.current?.api?.sizeColumnsToFit?.(); - } - }, [autoFitColumns]); + // Auto fit columns on column change + useEffect(() => { + if (!tableRef?.current?.api) return; + if (autoFitColumns && tableRef?.current?.api) { + tableRef?.current?.api?.sizeColumnsToFit?.(); + } + }, [autoFitColumns]); - // Reset row heights on row height change - useEffect(() => { - if (!tableRef?.current?.api) return; - tableRef?.current?.api?.resetRowHeights(); - tableRef?.current?.api?.redrawRows(); - }, [rest.rowHeight]); + // Reset row heights on row height change + useEffect(() => { + if (!tableRef?.current?.api) return; + tableRef?.current?.api?.resetRowHeights(); + tableRef?.current?.api?.redrawRows(); + }, [rest.rowHeight]); - const handleColumnMoved = useCallback( - (e: ColumnMovedEvent) => { - if (!e?.api) return; - onColumnMoved?.(e); - if (autoFitColumns) e.api?.sizeColumnsToFit?.(); - }, - [autoFitColumns, onColumnMoved], - ); + const handleColumnMoved = useCallback( + (e: ColumnMovedEvent) => { + if (!e?.api) return; + onColumnMoved?.(e); + if (autoFitColumns) e.api?.sizeColumnsToFit?.(); + }, + [autoFitColumns, onColumnMoved], + ); - const handleNewColumnsLoaded = useCallback( - (e: NewColumnsLoadedEvent) => { - if (!e?.api) return; - onNewColumnsLoaded?.(e); - if (autoFitColumns) e.api?.sizeColumnsToFit?.(); - }, - [autoFitColumns, onNewColumnsLoaded], - ); + const handleNewColumnsLoaded = useCallback( + (e: NewColumnsLoadedEvent) => { + if (!e?.api) return; + onNewColumnsLoaded?.(e); + if (autoFitColumns) e.api?.sizeColumnsToFit?.(); + }, + [autoFitColumns, onNewColumnsLoaded], + ); - const handleGridReady = useCallback( - (e: GridReadyEvent) => { - if (!e?.api) return; - onGridReady?.(e); - if (autoHeight) e.api.setDomLayout('autoHeight'); - if (autoFitColumns) e.api?.sizeColumnsToFit?.(); - }, - [autoHeight, autoFitColumns, onGridReady], - ); + const handleGridReady = useCallback( + (e: GridReadyEvent) => { + if (!e?.api) return; + onGridReady?.(e); + if (autoHeight) e.api.setDomLayout('autoHeight'); + if (autoFitColumns) e.api?.sizeColumnsToFit?.(); + }, + [autoHeight, autoFitColumns, onGridReady], + ); - const handleGridSizeChanged = useCallback( - (e: GridSizeChangedEvent) => { - if (!e?.api) return; - onGridSizeChanged?.(e); - if (autoFitColumns) e.api?.sizeColumnsToFit?.(); - }, - [autoFitColumns, onGridSizeChanged], - ); + const handleGridSizeChanged = useCallback( + (e: GridSizeChangedEvent) => { + if (!e?.api) return; + onGridSizeChanged?.(e); + if (autoFitColumns) e.api?.sizeColumnsToFit?.(); + }, + [autoFitColumns, onGridSizeChanged], + ); - const handleModelUpdated = useCallback( - (e: ModelUpdatedEvent) => { - if (!e?.api) return; - if (autoFitColumns) e.api?.sizeColumnsToFit?.(); - }, - [autoFitColumns], - ); + const handleModelUpdated = useCallback( + (e: ModelUpdatedEvent) => { + if (!e?.api) return; + if (autoFitColumns) e.api?.sizeColumnsToFit?.(); + }, + [autoFitColumns], + ); - return ( - <TableWrapper - ref={deselectRef} - className={ - transparentHeader ? 'ag-header-transparent ag-theme-alpine-dark' : 'ag-theme-alpine-dark' - } - > - <AgGridReact - ref={mergedRef} - animateRows - maintainColumnOrder - suppressAsyncEvents - suppressContextMenu - suppressCopyRowsToClipboard - suppressMoveWhenRowDragging - suppressPaginationPanel - suppressScrollOnNewData - blockLoadDebounceMillis={200} - cacheBlockSize={300} - cacheOverflowSize={1} - defaultColDef={defaultColumnDefs} - enableCellChangeFlash={false} - headerHeight={36} - rowBuffer={30} - rowSelection="multiple" - {...rest} - onColumnMoved={handleColumnMoved} - onGridReady={handleGridReady} - onGridSizeChanged={handleGridSizeChanged} - onModelUpdated={handleModelUpdated} - onNewColumnsLoaded={handleNewColumnsLoaded} - /> - </TableWrapper> - ); - }, + return ( + <TableWrapper + ref={deselectRef} + className={ + transparentHeader + ? 'ag-header-transparent ag-theme-alpine-dark' + : 'ag-theme-alpine-dark' + } + > + <AgGridReact + ref={mergedRef} + animateRows + maintainColumnOrder + suppressAsyncEvents + suppressContextMenu + suppressCopyRowsToClipboard + suppressMoveWhenRowDragging + suppressPaginationPanel + suppressScrollOnNewData + blockLoadDebounceMillis={200} + cacheBlockSize={300} + cacheOverflowSize={1} + defaultColDef={defaultColumnDefs} + enableCellChangeFlash={false} + headerHeight={36} + rowBuffer={30} + rowSelection="multiple" + {...rest} + onColumnMoved={handleColumnMoved} + onGridReady={handleGridReady} + onGridSizeChanged={handleGridSizeChanged} + onModelUpdated={handleModelUpdated} + onNewColumnsLoaded={handleNewColumnsLoaded} + /> + </TableWrapper> + ); + }, ); diff --git a/src/renderer/components/virtual-table/table-config-dropdown.tsx b/src/renderer/components/virtual-table/table-config-dropdown.tsx index 45c4f03d..3b73c6b9 100644 --- a/src/renderer/components/virtual-table/table-config-dropdown.tsx +++ b/src/renderer/components/virtual-table/table-config-dropdown.tsx @@ -3,256 +3,256 @@ import { MultiSelect } from '/@/renderer/components/select'; import { Slider } from '/@/renderer/components/slider'; import { Switch } from '/@/renderer/components/switch'; import { - useSettingsStoreActions, - useSettingsStore, - useLyricsSettings, + useSettingsStoreActions, + useSettingsStore, + useLyricsSettings, } from '/@/renderer/store/settings.store'; import { TableColumn, TableType } from '/@/renderer/types'; import { Option } from '/@/renderer/components/option'; import { NumberInput } from '/@/renderer/components/input'; export const SONG_TABLE_COLUMNS = [ - { label: 'Row Index', value: TableColumn.ROW_INDEX }, - { label: 'Title', value: TableColumn.TITLE }, - { label: 'Title (Combined)', value: TableColumn.TITLE_COMBINED }, - { label: 'Duration', value: TableColumn.DURATION }, - { label: 'Album', value: TableColumn.ALBUM }, - { label: 'Album Artist', value: TableColumn.ALBUM_ARTIST }, - { label: 'Artist', value: TableColumn.ARTIST }, - { label: 'Genre', value: TableColumn.GENRE }, - { label: 'Year', value: TableColumn.YEAR }, - { label: 'Release Date', value: TableColumn.RELEASE_DATE }, - { label: 'Disc Number', value: TableColumn.DISC_NUMBER }, - { label: 'Track Number', value: TableColumn.TRACK_NUMBER }, - { label: 'Bitrate', value: TableColumn.BIT_RATE }, - { label: 'Last Played', value: TableColumn.LAST_PLAYED }, - { label: 'Note', value: TableColumn.COMMENT }, - { label: 'Channels', value: TableColumn.CHANNELS }, - { label: 'BPM', value: TableColumn.BPM }, - { label: 'Date Added', value: TableColumn.DATE_ADDED }, - { label: 'Path', value: TableColumn.PATH }, - { label: 'Plays', value: TableColumn.PLAY_COUNT }, - { label: 'Size', value: TableColumn.SIZE }, - { label: 'Favorite', value: TableColumn.USER_FAVORITE }, - { label: 'Rating', value: TableColumn.USER_RATING }, - // { label: 'Skip', value: TableColumn.SKIP }, + { label: 'Row Index', value: TableColumn.ROW_INDEX }, + { label: 'Title', value: TableColumn.TITLE }, + { label: 'Title (Combined)', value: TableColumn.TITLE_COMBINED }, + { label: 'Duration', value: TableColumn.DURATION }, + { label: 'Album', value: TableColumn.ALBUM }, + { label: 'Album Artist', value: TableColumn.ALBUM_ARTIST }, + { label: 'Artist', value: TableColumn.ARTIST }, + { label: 'Genre', value: TableColumn.GENRE }, + { label: 'Year', value: TableColumn.YEAR }, + { label: 'Release Date', value: TableColumn.RELEASE_DATE }, + { label: 'Disc Number', value: TableColumn.DISC_NUMBER }, + { label: 'Track Number', value: TableColumn.TRACK_NUMBER }, + { label: 'Bitrate', value: TableColumn.BIT_RATE }, + { label: 'Last Played', value: TableColumn.LAST_PLAYED }, + { label: 'Note', value: TableColumn.COMMENT }, + { label: 'Channels', value: TableColumn.CHANNELS }, + { label: 'BPM', value: TableColumn.BPM }, + { label: 'Date Added', value: TableColumn.DATE_ADDED }, + { label: 'Path', value: TableColumn.PATH }, + { label: 'Plays', value: TableColumn.PLAY_COUNT }, + { label: 'Size', value: TableColumn.SIZE }, + { label: 'Favorite', value: TableColumn.USER_FAVORITE }, + { label: 'Rating', value: TableColumn.USER_RATING }, + // { label: 'Skip', value: TableColumn.SKIP }, ]; export const ALBUM_TABLE_COLUMNS = [ - { label: 'Row Index', value: TableColumn.ROW_INDEX }, - { label: 'Title', value: TableColumn.TITLE }, - { label: 'Title (Combined)', value: TableColumn.TITLE_COMBINED }, - { label: 'Duration', value: TableColumn.DURATION }, - { label: 'Album Artist', value: TableColumn.ALBUM_ARTIST }, - { label: 'Artist', value: TableColumn.ARTIST }, - { label: 'Genre', value: TableColumn.GENRE }, - { label: 'Year', value: TableColumn.YEAR }, - { label: 'Release Date', value: TableColumn.RELEASE_DATE }, - { label: 'Last Played', value: TableColumn.LAST_PLAYED }, - { label: 'Date Added', value: TableColumn.DATE_ADDED }, - { label: 'Plays', value: TableColumn.PLAY_COUNT }, - { label: 'Favorite', value: TableColumn.USER_FAVORITE }, - { label: 'Rating', value: TableColumn.USER_RATING }, + { label: 'Row Index', value: TableColumn.ROW_INDEX }, + { label: 'Title', value: TableColumn.TITLE }, + { label: 'Title (Combined)', value: TableColumn.TITLE_COMBINED }, + { label: 'Duration', value: TableColumn.DURATION }, + { label: 'Album Artist', value: TableColumn.ALBUM_ARTIST }, + { label: 'Artist', value: TableColumn.ARTIST }, + { label: 'Genre', value: TableColumn.GENRE }, + { label: 'Year', value: TableColumn.YEAR }, + { label: 'Release Date', value: TableColumn.RELEASE_DATE }, + { label: 'Last Played', value: TableColumn.LAST_PLAYED }, + { label: 'Date Added', value: TableColumn.DATE_ADDED }, + { label: 'Plays', value: TableColumn.PLAY_COUNT }, + { label: 'Favorite', value: TableColumn.USER_FAVORITE }, + { label: 'Rating', value: TableColumn.USER_RATING }, ]; export const ALBUMARTIST_TABLE_COLUMNS = [ - { label: 'Row Index', value: TableColumn.ROW_INDEX }, - { label: 'Title', value: TableColumn.TITLE }, - { label: 'Title (Combined)', value: TableColumn.TITLE_COMBINED }, - { label: 'Duration', value: TableColumn.DURATION }, - { label: 'Biography', value: TableColumn.BIOGRAPHY }, - { label: 'Genre', value: TableColumn.GENRE }, - { label: 'Last Played', value: TableColumn.LAST_PLAYED }, - { label: 'Plays', value: TableColumn.PLAY_COUNT }, - { label: 'Album Count', value: TableColumn.ALBUM_COUNT }, - { label: 'Song Count', value: TableColumn.SONG_COUNT }, - { label: 'Favorite', value: TableColumn.USER_FAVORITE }, - { label: 'Rating', value: TableColumn.USER_RATING }, + { label: 'Row Index', value: TableColumn.ROW_INDEX }, + { label: 'Title', value: TableColumn.TITLE }, + { label: 'Title (Combined)', value: TableColumn.TITLE_COMBINED }, + { label: 'Duration', value: TableColumn.DURATION }, + { label: 'Biography', value: TableColumn.BIOGRAPHY }, + { label: 'Genre', value: TableColumn.GENRE }, + { label: 'Last Played', value: TableColumn.LAST_PLAYED }, + { label: 'Plays', value: TableColumn.PLAY_COUNT }, + { label: 'Album Count', value: TableColumn.ALBUM_COUNT }, + { label: 'Song Count', value: TableColumn.SONG_COUNT }, + { label: 'Favorite', value: TableColumn.USER_FAVORITE }, + { label: 'Rating', value: TableColumn.USER_RATING }, ]; export const PLAYLIST_TABLE_COLUMNS = [ - { label: 'Row Index', value: TableColumn.ROW_INDEX }, - { label: 'Title', value: TableColumn.TITLE }, - { label: 'Title (Combined)', value: TableColumn.TITLE_COMBINED }, - { label: 'Duration', value: TableColumn.DURATION }, - { label: 'Owner', value: TableColumn.OWNER }, - // { label: 'Genre', value: TableColumn.GENRE }, - { label: 'Song Count', value: TableColumn.SONG_COUNT }, + { label: 'Row Index', value: TableColumn.ROW_INDEX }, + { label: 'Title', value: TableColumn.TITLE }, + { label: 'Title (Combined)', value: TableColumn.TITLE_COMBINED }, + { label: 'Duration', value: TableColumn.DURATION }, + { label: 'Owner', value: TableColumn.OWNER }, + // { label: 'Genre', value: TableColumn.GENRE }, + { label: 'Song Count', value: TableColumn.SONG_COUNT }, ]; interface TableConfigDropdownProps { - type: TableType; + type: TableType; } export const TableConfigDropdown = ({ type }: TableConfigDropdownProps) => { - const { setSettings } = useSettingsStoreActions(); - const tableConfig = useSettingsStore((state) => state.tables); - const lyricConfig = useLyricsSettings(); + const { setSettings } = useSettingsStoreActions(); + const tableConfig = useSettingsStore((state) => state.tables); + const lyricConfig = useLyricsSettings(); - const handleAddOrRemoveColumns = (values: TableColumn[]) => { - const existingColumns = tableConfig[type].columns; + const handleAddOrRemoveColumns = (values: TableColumn[]) => { + const existingColumns = tableConfig[type].columns; - if (values.length === 0) { - setSettings({ - tables: { - ...useSettingsStore.getState().tables, - [type]: { - ...useSettingsStore.getState().tables[type], - columns: [], - }, - }, - }); - return; - } + if (values.length === 0) { + setSettings({ + tables: { + ...useSettingsStore.getState().tables, + [type]: { + ...useSettingsStore.getState().tables[type], + columns: [], + }, + }, + }); + return; + } - // If adding a column - if (values.length > existingColumns.length) { - const newColumn = { column: values[values.length - 1] }; - setSettings({ - tables: { - ...useSettingsStore.getState().tables, - [type]: { - ...useSettingsStore.getState().tables[type], - columns: [...existingColumns, newColumn], - }, - }, - }); - } - // If removing a column - else { - const removed = existingColumns.filter((column) => !values.includes(column.column)); + // If adding a column + if (values.length > existingColumns.length) { + const newColumn = { column: values[values.length - 1] }; + setSettings({ + tables: { + ...useSettingsStore.getState().tables, + [type]: { + ...useSettingsStore.getState().tables[type], + columns: [...existingColumns, newColumn], + }, + }, + }); + } + // If removing a column + else { + const removed = existingColumns.filter((column) => !values.includes(column.column)); - const newColumns = existingColumns.filter((column) => !removed.includes(column)); + const newColumns = existingColumns.filter((column) => !removed.includes(column)); - setSettings({ - tables: { - ...useSettingsStore.getState().tables, - [type]: { - ...useSettingsStore.getState().tables[type], - columns: newColumns, - }, - }, - }); - } - }; + setSettings({ + tables: { + ...useSettingsStore.getState().tables, + [type]: { + ...useSettingsStore.getState().tables[type], + columns: newColumns, + }, + }, + }); + } + }; - const handleUpdateRowHeight = (value: number) => { - setSettings({ - tables: { - ...useSettingsStore.getState().tables, - [type]: { - ...useSettingsStore.getState().tables[type], - rowHeight: value, - }, - }, - }); - }; + const handleUpdateRowHeight = (value: number) => { + setSettings({ + tables: { + ...useSettingsStore.getState().tables, + [type]: { + ...useSettingsStore.getState().tables[type], + rowHeight: value, + }, + }, + }); + }; - const handleUpdateAutoFit = (e: ChangeEvent<HTMLInputElement>) => { - setSettings({ - tables: { - ...useSettingsStore.getState().tables, - [type]: { - ...useSettingsStore.getState().tables[type], - autoFit: e.currentTarget.checked, - }, - }, - }); - }; + const handleUpdateAutoFit = (e: ChangeEvent<HTMLInputElement>) => { + setSettings({ + tables: { + ...useSettingsStore.getState().tables, + [type]: { + ...useSettingsStore.getState().tables[type], + autoFit: e.currentTarget.checked, + }, + }, + }); + }; - const handleUpdateFollow = (e: ChangeEvent<HTMLInputElement>) => { - setSettings({ - tables: { - ...useSettingsStore.getState().tables, - [type]: { - ...useSettingsStore.getState().tables[type], - followCurrentSong: e.currentTarget.checked, - }, - }, - }); - }; + const handleUpdateFollow = (e: ChangeEvent<HTMLInputElement>) => { + setSettings({ + tables: { + ...useSettingsStore.getState().tables, + [type]: { + ...useSettingsStore.getState().tables[type], + followCurrentSong: e.currentTarget.checked, + }, + }, + }); + }; - const handleLyricFollow = (e: ChangeEvent<HTMLInputElement>) => { - setSettings({ - lyrics: { - ...useSettingsStore.getState().lyrics, - follow: e.currentTarget.checked, - }, - }); - }; + const handleLyricFollow = (e: ChangeEvent<HTMLInputElement>) => { + setSettings({ + lyrics: { + ...useSettingsStore.getState().lyrics, + follow: e.currentTarget.checked, + }, + }); + }; - const handleLyricOffset = (e: ChangeEvent<HTMLInputElement>) => { - setSettings({ - lyrics: { - ...useSettingsStore.getState().lyrics, - delayMs: Number(e.currentTarget.value), - }, - }); - }; + const handleLyricOffset = (e: ChangeEvent<HTMLInputElement>) => { + setSettings({ + lyrics: { + ...useSettingsStore.getState().lyrics, + delayMs: Number(e.currentTarget.value), + }, + }); + }; - return ( - <> - <Option> - <Option.Label>Auto-fit Columns</Option.Label> - <Option.Control> - <Switch - defaultChecked={tableConfig[type]?.autoFit} - onChange={handleUpdateAutoFit} - /> - </Option.Control> - </Option> - <Option> - <Option.Label>Follow current song</Option.Label> - <Option.Control> - <Switch - defaultChecked={tableConfig[type]?.followCurrentSong} - onChange={handleUpdateFollow} - /> - </Option.Control> - </Option> - <Option> - <Option.Label>Follow current lyrics</Option.Label> - <Option.Control> - <Switch - defaultChecked={lyricConfig.follow} - onChange={handleLyricFollow} - /> - </Option.Control> - </Option> - <Option> - <Option.Label>Lyric offset (ms)</Option.Label> - <Option.Control> - <NumberInput - defaultValue={lyricConfig.delayMs} - step={10} - onBlur={handleLyricOffset} - /> - </Option.Control> - </Option> - <Option> - <Option.Control> - <Slider - defaultValue={tableConfig[type]?.rowHeight} - label={(value) => `Item size: ${value}`} - max={100} - min={25} - w="100%" - onChangeEnd={handleUpdateRowHeight} - /> - </Option.Control> - </Option> - <Option> - <Option.Control> - <MultiSelect - clearable - data={SONG_TABLE_COLUMNS} - defaultValue={tableConfig[type]?.columns.map((column) => column.column)} - dropdownPosition="bottom" - width={300} - onChange={handleAddOrRemoveColumns} - /> - </Option.Control> - </Option> - </> - ); + return ( + <> + <Option> + <Option.Label>Auto-fit Columns</Option.Label> + <Option.Control> + <Switch + defaultChecked={tableConfig[type]?.autoFit} + onChange={handleUpdateAutoFit} + /> + </Option.Control> + </Option> + <Option> + <Option.Label>Follow current song</Option.Label> + <Option.Control> + <Switch + defaultChecked={tableConfig[type]?.followCurrentSong} + onChange={handleUpdateFollow} + /> + </Option.Control> + </Option> + <Option> + <Option.Label>Follow current lyrics</Option.Label> + <Option.Control> + <Switch + defaultChecked={lyricConfig.follow} + onChange={handleLyricFollow} + /> + </Option.Control> + </Option> + <Option> + <Option.Label>Lyric offset (ms)</Option.Label> + <Option.Control> + <NumberInput + defaultValue={lyricConfig.delayMs} + step={10} + onBlur={handleLyricOffset} + /> + </Option.Control> + </Option> + <Option> + <Option.Control> + <Slider + defaultValue={tableConfig[type]?.rowHeight} + label={(value) => `Item size: ${value}`} + max={100} + min={25} + w="100%" + onChangeEnd={handleUpdateRowHeight} + /> + </Option.Control> + </Option> + <Option> + <Option.Control> + <MultiSelect + clearable + data={SONG_TABLE_COLUMNS} + defaultValue={tableConfig[type]?.columns.map((column) => column.column)} + dropdownPosition="bottom" + width={300} + onChange={handleAddOrRemoveColumns} + /> + </Option.Control> + </Option> + </> + ); }; diff --git a/src/renderer/components/virtual-table/table-pagination.tsx b/src/renderer/components/virtual-table/table-pagination.tsx index ed49c086..e5f6605b 100644 --- a/src/renderer/components/virtual-table/table-pagination.tsx +++ b/src/renderer/components/virtual-table/table-pagination.tsx @@ -15,140 +15,144 @@ import { TablePagination as TablePaginationType } from '/@/renderer/types'; import { ListKey } from '/@/renderer/store'; interface TablePaginationProps { - pageKey: ListKey; - pagination: TablePaginationType; - setIdPagination?: (id: string, pagination: Partial<TablePaginationType>) => void; - setPagination?: (args: { data: Partial<TablePaginationType>; key: ListKey }) => void; - tableRef: MutableRefObject<AgGridReactType | null>; + pageKey: ListKey; + pagination: TablePaginationType; + setIdPagination?: (id: string, pagination: Partial<TablePaginationType>) => void; + setPagination?: (args: { data: Partial<TablePaginationType>; key: ListKey }) => void; + tableRef: MutableRefObject<AgGridReactType | null>; } export const TablePagination = ({ - pageKey, - tableRef, - pagination, - setPagination, - setIdPagination, + pageKey, + tableRef, + pagination, + setPagination, + setIdPagination, }: TablePaginationProps) => { - const [isGoToPageOpen, handlers] = useDisclosure(false); - const containerQuery = useContainerQuery(); + const [isGoToPageOpen, handlers] = useDisclosure(false); + const containerQuery = useContainerQuery(); - const goToForm = useForm({ - initialValues: { - pageNumber: undefined, - }, - }); + const goToForm = useForm({ + initialValues: { + pageNumber: undefined, + }, + }); - const handlePagination = (index: number) => { - const newPage = index - 1; - tableRef.current?.api.paginationGoToPage(newPage); - setPagination?.({ data: { currentPage: newPage }, key: pageKey }); - setIdPagination?.(pageKey || '', { currentPage: newPage }); - }; + const handlePagination = (index: number) => { + const newPage = index - 1; + tableRef.current?.api.paginationGoToPage(newPage); + setPagination?.({ data: { currentPage: newPage }, key: pageKey }); + setIdPagination?.(pageKey || '', { currentPage: newPage }); + }; - const handleGoSubmit = goToForm.onSubmit((values) => { - handlers.close(); - if (!values.pageNumber || values.pageNumber < 1 || values.pageNumber > pagination.totalPages) { - return; - } + const handleGoSubmit = goToForm.onSubmit((values) => { + handlers.close(); + if ( + !values.pageNumber || + values.pageNumber < 1 || + values.pageNumber > pagination.totalPages + ) { + return; + } - const newPage = values.pageNumber - 1; - tableRef.current?.api.paginationGoToPage(newPage); - setPagination?.({ data: { currentPage: newPage }, key: pageKey }); - setIdPagination?.(pageKey || '', { currentPage: newPage }); - }); + const newPage = values.pageNumber - 1; + tableRef.current?.api.paginationGoToPage(newPage); + setPagination?.({ data: { currentPage: newPage }, key: pageKey }); + setIdPagination?.(pageKey || '', { currentPage: newPage }); + }); - const currentPageStartIndex = pagination.currentPage * pagination.itemsPerPage + 1; - const currentPageMaxIndex = (pagination.currentPage + 1) * pagination.itemsPerPage; - const currentPageStopIndex = - currentPageMaxIndex > pagination.totalItems ? pagination.totalItems : currentPageMaxIndex; + const currentPageStartIndex = pagination.currentPage * pagination.itemsPerPage + 1; + const currentPageMaxIndex = (pagination.currentPage + 1) * pagination.itemsPerPage; + const currentPageStopIndex = + currentPageMaxIndex > pagination.totalItems ? pagination.totalItems : currentPageMaxIndex; - return ( - <MotionFlex - ref={containerQuery.ref} - layout - align="center" - animate={{ y: 0 }} - exit={{ y: 50 }} - initial={{ y: 50 }} - justify="space-between" - p="1rem" - sx={{ borderTop: '1px solid var(--generic-border-color)' }} - > - <Text - $secondary - size="md" - > - {containerQuery.isMd ? ( - <> - Showing <b>{currentPageStartIndex}</b> - <b>{currentPageStopIndex}</b> of{' '} - <b>{pagination.totalItems}</b> items - </> - ) : containerQuery.isSm ? ( - <> - <b>{currentPageStartIndex}</b> - <b>{currentPageStopIndex}</b> of{' '} - <b>{pagination.totalItems}</b> items - </> - ) : ( - <> - <b>{currentPageStartIndex}</b> - <b>{currentPageStopIndex}</b> of{' '} - <b>{pagination.totalItems}</b> - </> - )} - </Text> - <Group - ref={containerQuery.ref} - noWrap - spacing="sm" - > - <Popover - trapFocus - opened={isGoToPageOpen} - position="bottom-start" - onClose={() => handlers.close()} + return ( + <MotionFlex + ref={containerQuery.ref} + layout + align="center" + animate={{ y: 0 }} + exit={{ y: 50 }} + initial={{ y: 50 }} + justify="space-between" + p="1rem" + sx={{ borderTop: '1px solid var(--generic-border-color)' }} > - <Popover.Target> - <Button - radius="sm" - size="sm" - sx={{ height: '26px', padding: '0', width: '26px' }} - tooltip={{ label: 'Go to page' }} - variant="default" - onClick={() => handlers.toggle()} + <Text + $secondary + size="md" > - <RiHashtag size={15} /> - </Button> - </Popover.Target> - <Popover.Dropdown> - <form onSubmit={handleGoSubmit}> - <Group> - <NumberInput - {...goToForm.getInputProps('pageNumber')} - hideControls={false} - max={pagination.totalPages} - min={1} - width={70} - /> - <Button - type="submit" - variant="filled" + {containerQuery.isMd ? ( + <> + Showing <b>{currentPageStartIndex}</b> - <b>{currentPageStopIndex}</b> of{' '} + <b>{pagination.totalItems}</b> items + </> + ) : containerQuery.isSm ? ( + <> + <b>{currentPageStartIndex}</b> - <b>{currentPageStopIndex}</b> of{' '} + <b>{pagination.totalItems}</b> items + </> + ) : ( + <> + <b>{currentPageStartIndex}</b> - <b>{currentPageStopIndex}</b> of{' '} + <b>{pagination.totalItems}</b> + </> + )} + </Text> + <Group + ref={containerQuery.ref} + noWrap + spacing="sm" + > + <Popover + trapFocus + opened={isGoToPageOpen} + position="bottom-start" + onClose={() => handlers.close()} > - Go - </Button> - </Group> - </form> - </Popover.Dropdown> - </Popover> - <Pagination - noWrap - $hideDividers={!containerQuery.isSm} - boundaries={1} - radius="sm" - siblings={containerQuery.isMd ? 2 : containerQuery.isSm ? 1 : 0} - total={pagination.totalPages - 1} - value={pagination.currentPage + 1} - onChange={handlePagination} - /> - </Group> - </MotionFlex> - ); + <Popover.Target> + <Button + radius="sm" + size="sm" + sx={{ height: '26px', padding: '0', width: '26px' }} + tooltip={{ label: 'Go to page' }} + variant="default" + onClick={() => handlers.toggle()} + > + <RiHashtag size={15} /> + </Button> + </Popover.Target> + <Popover.Dropdown> + <form onSubmit={handleGoSubmit}> + <Group> + <NumberInput + {...goToForm.getInputProps('pageNumber')} + hideControls={false} + max={pagination.totalPages} + min={1} + width={70} + /> + <Button + type="submit" + variant="filled" + > + Go + </Button> + </Group> + </form> + </Popover.Dropdown> + </Popover> + <Pagination + noWrap + $hideDividers={!containerQuery.isSm} + boundaries={1} + radius="sm" + siblings={containerQuery.isMd ? 2 : containerQuery.isSm ? 1 : 0} + total={pagination.totalPages - 1} + value={pagination.currentPage + 1} + onChange={handlePagination} + /> + </Group> + </MotionFlex> + ); }; diff --git a/src/renderer/components/virtual-table/utils.ts b/src/renderer/components/virtual-table/utils.ts index d77470dd..80057720 100644 --- a/src/renderer/components/virtual-table/utils.ts +++ b/src/renderer/components/virtual-table/utils.ts @@ -1,36 +1,36 @@ import { GridApi, RowNode } from '@ag-grid-community/core'; export const getNodesByDiscNumber = (args: { api: GridApi; discNumber: number }) => { - const { api, discNumber } = args; + const { api, discNumber } = args; - const nodes: RowNode<any>[] = []; - api.forEachNode((node) => { - if (node.data.discNumber === discNumber) nodes.push(node); - }); + const nodes: RowNode<any>[] = []; + api.forEachNode((node) => { + if (node.data.discNumber === discNumber) nodes.push(node); + }); - return nodes; + return nodes; }; export const setNodeSelection = (args: { - deselectAll?: boolean; - isSelected: boolean; - nodes: RowNode<any>[]; + deselectAll?: boolean; + isSelected: boolean; + nodes: RowNode<any>[]; }) => { - const { nodes, isSelected } = args; + const { nodes, isSelected } = args; - nodes.forEach((node) => { - node.setSelected(isSelected); - }); + nodes.forEach((node) => { + node.setSelected(isSelected); + }); }; export const toggleNodeSelection = (args: { nodes: RowNode<any>[] }) => { - const { nodes } = args; + const { nodes } = args; - nodes.forEach((node) => { - if (node.isSelected()) { - node.setSelected(false); - } else { - node.setSelected(true); - } - }); + nodes.forEach((node) => { + if (node.isSelected()) { + node.setSelected(false); + } else { + node.setSelected(true); + } + }); }; diff --git a/src/renderer/features/action-required/components/action-required-container.tsx b/src/renderer/features/action-required/components/action-required-container.tsx index 280e75c5..355747c2 100644 --- a/src/renderer/features/action-required/components/action-required-container.tsx +++ b/src/renderer/features/action-required/components/action-required-container.tsx @@ -3,24 +3,24 @@ import { RiAlertFill } from 'react-icons/ri'; import { Text } from '/@/renderer/components'; interface ActionRequiredContainerProps { - children: React.ReactNode; - title: string; + children: React.ReactNode; + title: string; } export const ActionRequiredContainer = ({ title, children }: ActionRequiredContainerProps) => ( - <Stack sx={{ cursor: 'default', maxWidth: '700px' }}> - <Group> - <RiAlertFill - color="var(--warning-color)" - size={30} - /> - <Text - size="xl" - sx={{ textTransform: 'uppercase' }} - > - {title} - </Text> - </Group> - <Stack>{children}</Stack> - </Stack> + <Stack sx={{ cursor: 'default', maxWidth: '700px' }}> + <Group> + <RiAlertFill + color="var(--warning-color)" + size={30} + /> + <Text + size="xl" + sx={{ textTransform: 'uppercase' }} + > + {title} + </Text> + </Group> + <Stack>{children}</Stack> + </Stack> ); diff --git a/src/renderer/features/action-required/components/error-fallback.tsx b/src/renderer/features/action-required/components/error-fallback.tsx index 71bee490..6f06a50f 100644 --- a/src/renderer/features/action-required/components/error-fallback.tsx +++ b/src/renderer/features/action-required/components/error-fallback.tsx @@ -6,32 +6,32 @@ import styled from 'styled-components'; import { Button, Text } from '/@/renderer/components'; const Container = styled(Box)` - background: var(--main-bg); + background: var(--main-bg); `; export const ErrorFallback = ({ resetErrorBoundary }: FallbackProps) => { - const error = useRouteError() as any; + const error = useRouteError() as any; - return ( - <Container> - <Center sx={{ height: '100vh' }}> - <Stack sx={{ maxWidth: '50%' }}> - <Group spacing="xs"> - <RiErrorWarningLine - color="var(--danger-color)" - size={30} - /> - <Text size="lg">Something went wrong</Text> - </Group> - <Text>{error.message}</Text> - <Button - variant="filled" - onClick={resetErrorBoundary} - > - Reload - </Button> - </Stack> - </Center> - </Container> - ); + return ( + <Container> + <Center sx={{ height: '100vh' }}> + <Stack sx={{ maxWidth: '50%' }}> + <Group spacing="xs"> + <RiErrorWarningLine + color="var(--danger-color)" + size={30} + /> + <Text size="lg">Something went wrong</Text> + </Group> + <Text>{error.message}</Text> + <Button + variant="filled" + onClick={resetErrorBoundary} + > + Reload + </Button> + </Stack> + </Center> + </Container> + ); }; diff --git a/src/renderer/features/action-required/components/mpv-required.tsx b/src/renderer/features/action-required/components/mpv-required.tsx index 1f7b97ad..7db95f43 100644 --- a/src/renderer/features/action-required/components/mpv-required.tsx +++ b/src/renderer/features/action-required/components/mpv-required.tsx @@ -5,39 +5,39 @@ import { FileInput, Text, Button } from '/@/renderer/components'; const localSettings = isElectron() ? window.electron.localSettings : null; export const MpvRequired = () => { - const [mpvPath, setMpvPath] = useState(''); - const handleSetMpvPath = (e: File) => { - localSettings.set('mpv_path', e.path); - }; - - useEffect(() => { - const getMpvPath = async () => { - if (!isElectron()) return setMpvPath(''); - const mpvPath = localSettings.get('mpv_path') as string; - return setMpvPath(mpvPath); + const [mpvPath, setMpvPath] = useState(''); + const handleSetMpvPath = (e: File) => { + localSettings.set('mpv_path', e.path); }; - getMpvPath(); - }, []); + useEffect(() => { + const getMpvPath = async () => { + if (!isElectron()) return setMpvPath(''); + const mpvPath = localSettings.get('mpv_path') as string; + return setMpvPath(mpvPath); + }; - return ( - <> - <Text>Set your MPV executable location below and restart the application.</Text> - <Text> - MPV is available at the following:{' '} - <a - href="https://mpv.io/installation/" - rel="noreferrer" - target="_blank" - > - https://mpv.io/ - </a> - </Text> - <FileInput - placeholder={mpvPath} - onChange={handleSetMpvPath} - /> - <Button onClick={() => localSettings.restart()}>Restart</Button> - </> - ); + getMpvPath(); + }, []); + + return ( + <> + <Text>Set your MPV executable location below and restart the application.</Text> + <Text> + MPV is available at the following:{' '} + <a + href="https://mpv.io/installation/" + rel="noreferrer" + target="_blank" + > + https://mpv.io/ + </a> + </Text> + <FileInput + placeholder={mpvPath} + onChange={handleSetMpvPath} + /> + <Button onClick={() => localSettings.restart()}>Restart</Button> + </> + ); }; diff --git a/src/renderer/features/action-required/components/route-error-boundary.tsx b/src/renderer/features/action-required/components/route-error-boundary.tsx index a1252838..20d83c8b 100644 --- a/src/renderer/features/action-required/components/route-error-boundary.tsx +++ b/src/renderer/features/action-required/components/route-error-boundary.tsx @@ -6,84 +6,84 @@ import { AppMenu } from '/@/renderer/features/titlebar/components/app-menu'; import { AppRoute } from '/@/renderer/router/routes'; const RouteErrorBoundary = () => { - const navigate = useNavigate(); - const error = useRouteError() as any; - console.log('error', error); + const navigate = useNavigate(); + const error = useRouteError() as any; + console.log('error', error); - const handleReload = () => { - navigate(0); - }; + const handleReload = () => { + navigate(0); + }; - const handleReturn = () => { - navigate(-1); - }; + const handleReturn = () => { + navigate(-1); + }; - const handleHome = () => { - navigate(AppRoute.HOME); - }; + const handleHome = () => { + navigate(AppRoute.HOME); + }; - return ( - <Box bg="var(--main-bg)"> - <Center sx={{ height: '100vh' }}> - <Stack sx={{ maxWidth: '50%' }}> - <Group> - <Button - px={10} - variant="subtle" - onClick={handleReturn} - > - <RiArrowLeftSLine size={20} /> - </Button> - <RiErrorWarningLine - color="var(--danger-color)" - size={30} - /> - <Text size="lg">Something went wrong</Text> - </Group> - <Divider my={5} /> - <Text size="sm">{error?.message}</Text> - <Group - grow - spacing="sm" - > - <Button - leftIcon={<RiHome4Line />} - size="md" - sx={{ flex: 0.5 }} - variant="default" - onClick={handleHome} - > - Go home - </Button> - <DropdownMenu position="bottom-start"> - <DropdownMenu.Target> - <Button - leftIcon={<RiMenuFill />} - size="md" - sx={{ flex: 0.5 }} - variant="default" - > - Menu - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - <AppMenu /> - </DropdownMenu.Dropdown> - </DropdownMenu> - </Group> - <Group grow> - <Button - size="md" - variant="filled" - onClick={handleReload} - > - Reload - </Button> - </Group> - </Stack> - </Center> - </Box> - ); + return ( + <Box bg="var(--main-bg)"> + <Center sx={{ height: '100vh' }}> + <Stack sx={{ maxWidth: '50%' }}> + <Group> + <Button + px={10} + variant="subtle" + onClick={handleReturn} + > + <RiArrowLeftSLine size={20} /> + </Button> + <RiErrorWarningLine + color="var(--danger-color)" + size={30} + /> + <Text size="lg">Something went wrong</Text> + </Group> + <Divider my={5} /> + <Text size="sm">{error?.message}</Text> + <Group + grow + spacing="sm" + > + <Button + leftIcon={<RiHome4Line />} + size="md" + sx={{ flex: 0.5 }} + variant="default" + onClick={handleHome} + > + Go home + </Button> + <DropdownMenu position="bottom-start"> + <DropdownMenu.Target> + <Button + leftIcon={<RiMenuFill />} + size="md" + sx={{ flex: 0.5 }} + variant="default" + > + Menu + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + <AppMenu /> + </DropdownMenu.Dropdown> + </DropdownMenu> + </Group> + <Group grow> + <Button + size="md" + variant="filled" + onClick={handleReload} + > + Reload + </Button> + </Group> + </Stack> + </Center> + </Box> + ); }; export default RouteErrorBoundary; diff --git a/src/renderer/features/action-required/components/server-credential-required.tsx b/src/renderer/features/action-required/components/server-credential-required.tsx index cf5ed90d..2b7101f5 100644 --- a/src/renderer/features/action-required/components/server-credential-required.tsx +++ b/src/renderer/features/action-required/components/server-credential-required.tsx @@ -2,17 +2,18 @@ import { Text } from '/@/renderer/components'; import { useCurrentServer } from '/@/renderer/store'; export const ServerCredentialRequired = () => { - const currentServer = useCurrentServer(); + const currentServer = useCurrentServer(); - return ( - <> - <Text> - The selected server '{currentServer?.name}' requires an additional login to - access. - </Text> - <Text> - Add your credentials in the 'manage servers' menu or switch to a different server. - </Text> - </> - ); + return ( + <> + <Text> + The selected server '{currentServer?.name}' requires an additional login + to access. + </Text> + <Text> + Add your credentials in the 'manage servers' menu or switch to a different + server. + </Text> + </> + ); }; diff --git a/src/renderer/features/action-required/components/server-required.tsx b/src/renderer/features/action-required/components/server-required.tsx index 7a8673ab..4e07353b 100644 --- a/src/renderer/features/action-required/components/server-required.tsx +++ b/src/renderer/features/action-required/components/server-required.tsx @@ -3,22 +3,22 @@ import { Button, DropdownMenu, Text } from '/@/renderer/components'; import { AppMenu } from '/@/renderer/features/titlebar/components/app-menu'; export const ServerRequired = () => { - return ( - <> - <Text>No server selected.</Text> - <DropdownMenu> - <DropdownMenu.Target> - <Button - leftIcon={<RiMenuFill />} - variant="filled" - > - Open menu - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - <AppMenu /> - </DropdownMenu.Dropdown> - </DropdownMenu> - </> - ); + return ( + <> + <Text>No server selected.</Text> + <DropdownMenu> + <DropdownMenu.Target> + <Button + leftIcon={<RiMenuFill />} + variant="filled" + > + Open menu + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + <AppMenu /> + </DropdownMenu.Dropdown> + </DropdownMenu> + </> + ); }; diff --git a/src/renderer/features/action-required/routes/action-required-route.tsx b/src/renderer/features/action-required/routes/action-required-route.tsx index 69575b45..3acbf4a3 100644 --- a/src/renderer/features/action-required/routes/action-required-route.tsx +++ b/src/renderer/features/action-required/routes/action-required-route.tsx @@ -15,91 +15,91 @@ import { useCurrentServer } from '/@/renderer/store'; const localSettings = isElectron() ? window.electron.localSettings : null; const ActionRequiredRoute = () => { - const currentServer = useCurrentServer(); - const [isMpvRequired, setIsMpvRequired] = useState(false); - const isServerRequired = !currentServer; - const isCredentialRequired = false; + const currentServer = useCurrentServer(); + const [isMpvRequired, setIsMpvRequired] = useState(false); + const isServerRequired = !currentServer; + const isCredentialRequired = false; - useEffect(() => { - const getMpvPath = async () => { - if (!isElectron()) return setIsMpvRequired(false); - const mpvPath = await localSettings.get('mpv_path'); + useEffect(() => { + const getMpvPath = async () => { + if (!isElectron()) return setIsMpvRequired(false); + const mpvPath = await localSettings.get('mpv_path'); - if (mpvPath) { - return setIsMpvRequired(false); - } + if (mpvPath) { + return setIsMpvRequired(false); + } - return setIsMpvRequired(true); - }; + return setIsMpvRequired(true); + }; - getMpvPath(); - }, []); + getMpvPath(); + }, []); - const checks = [ - { - component: <MpvRequired />, - title: 'MPV required', - valid: !isMpvRequired, - }, - { - component: <ServerCredentialRequired />, - title: 'Credentials required', - valid: !isCredentialRequired, - }, - { - component: <ServerRequired />, - title: 'Server required', - valid: !isServerRequired, - }, - ]; + const checks = [ + { + component: <MpvRequired />, + title: 'MPV required', + valid: !isMpvRequired, + }, + { + component: <ServerCredentialRequired />, + title: 'Credentials required', + valid: !isCredentialRequired, + }, + { + component: <ServerRequired />, + title: 'Server required', + valid: !isServerRequired, + }, + ]; - const canReturnHome = checks.every((c) => c.valid); - const displayedCheck = checks.find((c) => !c.valid); + const canReturnHome = checks.every((c) => c.valid); + const displayedCheck = checks.find((c) => !c.valid); - return ( - <AnimatedPage> - <PageHeader /> - <Center sx={{ height: '100%', width: '100vw' }}> - <Stack - spacing="xl" - sx={{ maxWidth: '50%' }} - > - <Group noWrap> - {displayedCheck && ( - <ActionRequiredContainer title={displayedCheck.title}> - {displayedCheck?.component} - </ActionRequiredContainer> - )} - </Group> - <Stack mt="2rem"> - {canReturnHome && ( - <> - <Navigate to={AppRoute.HOME} /> - <Group - noWrap - position="center" + return ( + <AnimatedPage> + <PageHeader /> + <Center sx={{ height: '100%', width: '100vw' }}> + <Stack + spacing="xl" + sx={{ maxWidth: '50%' }} > - <RiCheckFill - color="var(--success-color)" - size={30} - /> - <Text size="xl">No issues found</Text> - </Group> - <Button - component={Link} - disabled={!canReturnHome} - to={AppRoute.HOME} - variant="filled" - > - Go back - </Button> - </> - )} - </Stack> - </Stack> - </Center> - </AnimatedPage> - ); + <Group noWrap> + {displayedCheck && ( + <ActionRequiredContainer title={displayedCheck.title}> + {displayedCheck?.component} + </ActionRequiredContainer> + )} + </Group> + <Stack mt="2rem"> + {canReturnHome && ( + <> + <Navigate to={AppRoute.HOME} /> + <Group + noWrap + position="center" + > + <RiCheckFill + color="var(--success-color)" + size={30} + /> + <Text size="xl">No issues found</Text> + </Group> + <Button + component={Link} + disabled={!canReturnHome} + to={AppRoute.HOME} + variant="filled" + > + Go back + </Button> + </> + )} + </Stack> + </Stack> + </Center> + </AnimatedPage> + ); }; export default ActionRequiredRoute; diff --git a/src/renderer/features/action-required/routes/invalid-route.tsx b/src/renderer/features/action-required/routes/invalid-route.tsx index fb79071e..da58f13d 100644 --- a/src/renderer/features/action-required/routes/invalid-route.tsx +++ b/src/renderer/features/action-required/routes/invalid-route.tsx @@ -5,34 +5,34 @@ import { Button, Text } from '/@/renderer/components'; import { AnimatedPage } from '/@/renderer/features/shared'; const InvalidRoute = () => { - const navigate = useNavigate(); - const location = useLocation(); + const navigate = useNavigate(); + const location = useLocation(); - return ( - <AnimatedPage> - <Center sx={{ height: '100%', width: '100%' }}> - <Stack> - <Group - noWrap - position="center" - > - <RiQuestionLine - color="var(--warning-color)" - size={30} - /> - <Text size="xl">Page not found</Text> - </Group> - <Text>{location.pathname}</Text> - <Button - variant="filled" - onClick={() => navigate(-1)} - > - Go back - </Button> - </Stack> - </Center> - </AnimatedPage> - ); + return ( + <AnimatedPage> + <Center sx={{ height: '100%', width: '100%' }}> + <Stack> + <Group + noWrap + position="center" + > + <RiQuestionLine + color="var(--warning-color)" + size={30} + /> + <Text size="xl">Page not found</Text> + </Group> + <Text>{location.pathname}</Text> + <Button + variant="filled" + onClick={() => navigate(-1)} + > + Go back + </Button> + </Stack> + </Center> + </AnimatedPage> + ); }; export default InvalidRoute; diff --git a/src/renderer/features/albums/components/album-detail-content.tsx b/src/renderer/features/albums/components/album-detail-content.tsx index 1e2eb66b..605313a4 100644 --- a/src/renderer/features/albums/components/album-detail-content.tsx +++ b/src/renderer/features/albums/components/album-detail-content.tsx @@ -13,13 +13,13 @@ import { AppRoute } from '/@/renderer/router/routes'; import { useContainerQuery } from '/@/renderer/hooks'; import { PersistedTableColumn, usePlayButtonBehavior } from '/@/renderer/store/settings.store'; import { - useHandleGeneralContextMenu, - useHandleTableContextMenu, + useHandleGeneralContextMenu, + useHandleTableContextMenu, } from '/@/renderer/features/context-menu'; import { Play, ServerType, TableColumn } from '/@/renderer/types'; import { - ALBUM_CONTEXT_MENU_ITEMS, - SONG_CONTEXT_MENU_ITEMS, + ALBUM_CONTEXT_MENU_ITEMS, + SONG_CONTEXT_MENU_ITEMS, } from '/@/renderer/features/context-menu/context-menu-items'; import { PlayButton, useCreateFavorite, useDeleteFavorite } from '/@/renderer/features/shared'; import { useAlbumList } from '/@/renderer/features/albums/queries/album-list-query'; @@ -27,377 +27,393 @@ import { AlbumListSort, LibraryItem, QueueSong, SortOrder } from '/@/renderer/ap import { usePlayQueueAdd } from '/@/renderer/features/player'; import { useCurrentServer } from '/@/renderer/store'; import { - getColumnDefs, - useFixedTableHeader, - VirtualTable, + getColumnDefs, + useFixedTableHeader, + VirtualTable, } from '/@/renderer/components/virtual-table'; import { SwiperGridCarousel } from '/@/renderer/components/grid-carousel'; import { FullWidthDiscCell } from '/@/renderer/components/virtual-table/cells/full-width-disc-cell'; const isFullWidthRow = (node: RowNode) => { - return node.id?.startsWith('disc-'); + return node.id?.startsWith('disc-'); }; const ContentContainer = styled.div` - position: relative; - display: flex; - flex-direction: column; - padding: 1rem 2rem 5rem; - overflow: hidden; + position: relative; + display: flex; + flex-direction: column; + padding: 1rem 2rem 5rem; + overflow: hidden; - .ag-theme-alpine-dark { - --ag-header-background-color: rgba(0, 0, 0, 0%) !important; - } + .ag-theme-alpine-dark { + --ag-header-background-color: rgba(0, 0, 0, 0%) !important; + } - .ag-header { - margin-bottom: 0.5rem; - } + .ag-header { + margin-bottom: 0.5rem; + } `; interface AlbumDetailContentProps { - tableRef: MutableRefObject<AgGridReactType | null>; + tableRef: MutableRefObject<AgGridReactType | null>; } export const AlbumDetailContent = ({ tableRef }: AlbumDetailContentProps) => { - const { albumId } = useParams() as { albumId: string }; - const server = useCurrentServer(); - const detailQuery = useAlbumDetail({ query: { id: albumId }, serverId: server?.id }); - const cq = useContainerQuery(); - const handlePlayQueueAdd = usePlayQueueAdd(); + const { albumId } = useParams() as { albumId: string }; + const server = useCurrentServer(); + const detailQuery = useAlbumDetail({ query: { id: albumId }, serverId: server?.id }); + const cq = useContainerQuery(); + const handlePlayQueueAdd = usePlayQueueAdd(); - // TODO: Make this customizable - const columnDefs: ColDef[] = useMemo(() => { - const userRatingColumn = - detailQuery?.data?.serverType !== ServerType.JELLYFIN - ? [ + // TODO: Make this customizable + const columnDefs: ColDef[] = useMemo(() => { + const userRatingColumn = + detailQuery?.data?.serverType !== ServerType.JELLYFIN + ? [ + { + column: TableColumn.USER_RATING, + width: 0, + }, + ] + : []; + + const cols: PersistedTableColumn[] = [ { - column: TableColumn.USER_RATING, - width: 0, + column: TableColumn.TRACK_NUMBER, + width: 0, + }, + { + column: TableColumn.TITLE_COMBINED, + width: 0, }, - ] - : []; - const cols: PersistedTableColumn[] = [ - { - column: TableColumn.TRACK_NUMBER, - width: 0, - }, - { - column: TableColumn.TITLE_COMBINED, - width: 0, - }, + { + column: TableColumn.DURATION, + width: 0, + }, + { + column: TableColumn.BIT_RATE, + width: 0, + }, + { + column: TableColumn.PLAY_COUNT, + width: 0, + }, + { + column: TableColumn.LAST_PLAYED, + width: 0, + }, + ...userRatingColumn, + { + column: TableColumn.USER_FAVORITE, + width: 0, + }, + ]; + return getColumnDefs(cols).filter((c) => c.colId !== 'album' && c.colId !== 'artist'); + }, [detailQuery?.data?.serverType]); - { - column: TableColumn.DURATION, - width: 0, - }, - { - column: TableColumn.BIT_RATE, - width: 0, - }, - { - column: TableColumn.PLAY_COUNT, - width: 0, - }, - { - column: TableColumn.LAST_PLAYED, - width: 0, - }, - ...userRatingColumn, - { - column: TableColumn.USER_FAVORITE, - width: 0, - }, + const getRowHeight = useCallback((params: RowHeightParams) => { + if (isFullWidthRow(params.node)) { + return 45; + } + + return 60; + }, []); + + const songsRowData = useMemo(() => { + if (!detailQuery.data?.songs) { + return []; + } + + const uniqueDiscNumbers = new Set(detailQuery.data?.songs.map((s) => s.discNumber)); + const rowData: (QueueSong | { id: string; name: string })[] = []; + + for (const discNumber of uniqueDiscNumbers.values()) { + const songsByDiscNumber = detailQuery.data?.songs.filter( + (s) => s.discNumber === discNumber, + ); + rowData.push({ + id: `disc-${discNumber}`, + name: `Disc ${discNumber}`.toLocaleUpperCase(), + }); + rowData.push(...songsByDiscNumber); + } + + return rowData; + }, [detailQuery.data?.songs]); + + const [pagination, setPagination] = useSetState({ + artist: 0, + }); + + const handleNextPage = useCallback( + (key: 'artist') => { + setPagination({ + [key]: pagination[key as keyof typeof pagination] + 1, + }); + }, + [pagination, setPagination], + ); + + const handlePreviousPage = useCallback( + (key: 'artist') => { + setPagination({ + [key]: pagination[key as keyof typeof pagination] - 1, + }); + }, + [pagination, setPagination], + ); + + const itemsPerPage = cq.isXl ? 9 : cq.isLg ? 7 : cq.isMd ? 5 : cq.isSm ? 4 : 3; + + const artistQuery = useAlbumList({ + options: { + cacheTime: 1000 * 60, + enabled: detailQuery?.data?.albumArtists[0]?.id !== undefined, + keepPreviousData: true, + staleTime: 1000 * 60, + }, + query: { + _custom: { + jellyfin: { + AlbumArtistIds: detailQuery?.data?.albumArtists[0]?.id, + ExcludeItemIds: detailQuery?.data?.id, + }, + navidrome: { + artist_id: detailQuery?.data?.albumArtists[0]?.id, + }, + }, + limit: 10, + sortBy: AlbumListSort.YEAR, + sortOrder: SortOrder.DESC, + startIndex: pagination.artist * itemsPerPage, + }, + serverId: server?.id, + }); + + const carousels = [ + { + data: artistQuery?.data?.items, + loading: artistQuery?.isLoading || artistQuery.isFetching, + pagination: { + handleNextPage: () => handleNextPage('artist'), + handlePreviousPage: () => handlePreviousPage('artist'), + hasPreviousPage: pagination.artist > 0, + itemsPerPage, + }, + title: 'More from this artist', + uniqueId: 'mostPlayed', + }, ]; - return getColumnDefs(cols).filter((c) => c.colId !== 'album' && c.colId !== 'artist'); - }, [detailQuery?.data?.serverType]); - const getRowHeight = useCallback((params: RowHeightParams) => { - if (isFullWidthRow(params.node)) { - return 45; - } + const playButtonBehavior = usePlayButtonBehavior(); - return 60; - }, []); + const handlePlay = async (playType?: Play) => { + handlePlayQueueAdd?.({ + byData: detailQuery?.data?.songs, + playType: playType || playButtonBehavior, + }); + }; - const songsRowData = useMemo(() => { - if (!detailQuery.data?.songs) { - return []; - } + const handleContextMenu = useHandleTableContextMenu(LibraryItem.SONG, SONG_CONTEXT_MENU_ITEMS); - const uniqueDiscNumbers = new Set(detailQuery.data?.songs.map((s) => s.discNumber)); - const rowData: (QueueSong | { id: string; name: string })[] = []; + const handleRowDoubleClick = (e: RowDoubleClickedEvent<QueueSong>) => { + if (!e.data || e.node.isFullWidthCell()) return; - for (const discNumber of uniqueDiscNumbers.values()) { - const songsByDiscNumber = detailQuery.data?.songs.filter((s) => s.discNumber === discNumber); - rowData.push({ id: `disc-${discNumber}`, name: `Disc ${discNumber}`.toLocaleUpperCase() }); - rowData.push(...songsByDiscNumber); - } + const rowData: QueueSong[] = []; + e.api.forEachNode((node) => { + if (!node.data || node.isFullWidthCell()) return; + rowData.push(node.data); + }); - return rowData; - }, [detailQuery.data?.songs]); + handlePlayQueueAdd?.({ + byData: rowData, + initialSongId: e.data.id, + playType: playButtonBehavior, + }); + }; - const [pagination, setPagination] = useSetState({ - artist: 0, - }); + const createFavoriteMutation = useCreateFavorite({}); + const deleteFavoriteMutation = useDeleteFavorite({}); - const handleNextPage = useCallback( - (key: 'artist') => { - setPagination({ - [key]: pagination[key as keyof typeof pagination] + 1, - }); - }, - [pagination, setPagination], - ); + const handleFavorite = () => { + if (!detailQuery?.data) return; - const handlePreviousPage = useCallback( - (key: 'artist') => { - setPagination({ - [key]: pagination[key as keyof typeof pagination] - 1, - }); - }, - [pagination, setPagination], - ); + if (detailQuery.data.userFavorite) { + deleteFavoriteMutation.mutate({ + query: { + id: [detailQuery.data.id], + type: LibraryItem.ALBUM, + }, + serverId: detailQuery.data.serverId, + }); + } else { + createFavoriteMutation.mutate({ + query: { + id: [detailQuery.data.id], + type: LibraryItem.ALBUM, + }, + serverId: detailQuery.data.serverId, + }); + } + }; - const itemsPerPage = cq.isXl ? 9 : cq.isLg ? 7 : cq.isMd ? 5 : cq.isSm ? 4 : 3; + const showGenres = detailQuery?.data?.genres ? detailQuery?.data?.genres.length !== 0 : false; - const artistQuery = useAlbumList({ - options: { - cacheTime: 1000 * 60, - enabled: detailQuery?.data?.albumArtists[0]?.id !== undefined, - keepPreviousData: true, - staleTime: 1000 * 60, - }, - query: { - _custom: { - jellyfin: { - AlbumArtistIds: detailQuery?.data?.albumArtists[0]?.id, - ExcludeItemIds: detailQuery?.data?.id, - }, - navidrome: { - artist_id: detailQuery?.data?.albumArtists[0]?.id, - }, - }, - limit: 10, - sortBy: AlbumListSort.YEAR, - sortOrder: SortOrder.DESC, - startIndex: pagination.artist * itemsPerPage, - }, - serverId: server?.id, - }); + const { intersectRef, tableContainerRef } = useFixedTableHeader(); - const carousels = [ - { - data: artistQuery?.data?.items, - loading: artistQuery?.isLoading || artistQuery.isFetching, - pagination: { - handleNextPage: () => handleNextPage('artist'), - handlePreviousPage: () => handlePreviousPage('artist'), - hasPreviousPage: pagination.artist > 0, - itemsPerPage, - }, - title: 'More from this artist', - uniqueId: 'mostPlayed', - }, - ]; + const handleGeneralContextMenu = useHandleGeneralContextMenu( + LibraryItem.ALBUM, + ALBUM_CONTEXT_MENU_ITEMS, + ); - const playButtonBehavior = usePlayButtonBehavior(); - - const handlePlay = async (playType?: Play) => { - handlePlayQueueAdd?.({ - byData: detailQuery?.data?.songs, - playType: playType || playButtonBehavior, - }); - }; - - const handleContextMenu = useHandleTableContextMenu(LibraryItem.SONG, SONG_CONTEXT_MENU_ITEMS); - - const handleRowDoubleClick = (e: RowDoubleClickedEvent<QueueSong>) => { - if (!e.data || e.node.isFullWidthCell()) return; - - const rowData: QueueSong[] = []; - e.api.forEachNode((node) => { - if (!node.data || node.isFullWidthCell()) return; - rowData.push(node.data); - }); - - handlePlayQueueAdd?.({ - byData: rowData, - initialSongId: e.data.id, - playType: playButtonBehavior, - }); - }; - - const createFavoriteMutation = useCreateFavorite({}); - const deleteFavoriteMutation = useDeleteFavorite({}); - - const handleFavorite = () => { - if (!detailQuery?.data) return; - - if (detailQuery.data.userFavorite) { - deleteFavoriteMutation.mutate({ - query: { - id: [detailQuery.data.id], - type: LibraryItem.ALBUM, - }, - serverId: detailQuery.data.serverId, - }); - } else { - createFavoriteMutation.mutate({ - query: { - id: [detailQuery.data.id], - type: LibraryItem.ALBUM, - }, - serverId: detailQuery.data.serverId, - }); - } - }; - - const showGenres = detailQuery?.data?.genres ? detailQuery?.data?.genres.length !== 0 : false; - - const { intersectRef, tableContainerRef } = useFixedTableHeader(); - - const handleGeneralContextMenu = useHandleGeneralContextMenu( - LibraryItem.ALBUM, - ALBUM_CONTEXT_MENU_ITEMS, - ); - - return ( - <ContentContainer> - <Box component="section"> - <Group - ref={showGenres ? null : intersectRef} - className="test" - py="1rem" - spacing="md" - > - <PlayButton onClick={() => handlePlay(playButtonBehavior)} /> - <Group spacing="xs"> - <Button - compact - loading={createFavoriteMutation.isLoading || deleteFavoriteMutation.isLoading} - variant="subtle" - onClick={handleFavorite} + return ( + <ContentContainer> + <Box component="section"> + <Group + ref={showGenres ? null : intersectRef} + className="test" + py="1rem" + spacing="md" + > + <PlayButton onClick={() => handlePlay(playButtonBehavior)} /> + <Group spacing="xs"> + <Button + compact + loading={ + createFavoriteMutation.isLoading || deleteFavoriteMutation.isLoading + } + variant="subtle" + onClick={handleFavorite} + > + {detailQuery?.data?.userFavorite ? ( + <RiHeartFill + color="red" + size={20} + /> + ) : ( + <RiHeartLine size={20} /> + )} + </Button> + <Button + compact + variant="subtle" + onClick={(e) => { + if (!detailQuery?.data) return; + handleGeneralContextMenu(e, [detailQuery.data!]); + }} + > + <RiMoreFill size={20} /> + </Button> + </Group> + </Group> + </Box> + {showGenres && ( + <Box + ref={showGenres ? intersectRef : null} + component="section" + py="1rem" + > + <Group spacing="sm"> + {detailQuery?.data?.genres?.map((genre) => ( + <Button + key={`genre-${genre.id}`} + compact + component={Link} + radius={0} + size="md" + to={generatePath(`${AppRoute.LIBRARY_ALBUMS}?genre=${genre.id}`, { + albumId, + })} + variant="outline" + > + {genre.name} + </Button> + ))} + </Group> + </Box> + )} + <Box + ref={tableContainerRef} + style={{ minHeight: '300px' }} > - {detailQuery?.data?.userFavorite ? ( - <RiHeartFill - color="red" - size={20} + <VirtualTable + ref={tableRef} + autoFitColumns + autoHeight + suppressCellFocus + suppressHorizontalScroll + suppressLoadingOverlay + suppressRowDrag + columnDefs={columnDefs} + enableCellChangeFlash={false} + fullWidthCellRenderer={FullWidthDiscCell} + getRowHeight={getRowHeight} + getRowId={(data) => data.data.id} + isFullWidthRow={(data) => { + return isFullWidthRow(data.rowNode) || false; + }} + isRowSelectable={(data) => { + if (isFullWidthRow(data.data)) return false; + return true; + }} + rowData={songsRowData} + rowSelection="multiple" + onCellContextMenu={handleContextMenu} + onRowDoubleClicked={handleRowDoubleClick} /> - ) : ( - <RiHeartLine size={20} /> - )} - </Button> - <Button - compact - variant="subtle" - onClick={(e) => { - if (!detailQuery?.data) return; - handleGeneralContextMenu(e, [detailQuery.data!]); - }} + </Box> + <Stack + ref={cq.ref} + mt="5rem" > - <RiMoreFill size={20} /> - </Button> - </Group> - </Group> - </Box> - {showGenres && ( - <Box - ref={showGenres ? intersectRef : null} - component="section" - py="1rem" - > - <Group spacing="sm"> - {detailQuery?.data?.genres?.map((genre) => ( - <Button - key={`genre-${genre.id}`} - compact - component={Link} - radius={0} - size="md" - to={generatePath(`${AppRoute.LIBRARY_ALBUMS}?genre=${genre.id}`, { albumId })} - variant="outline" - > - {genre.name} - </Button> - ))} - </Group> - </Box> - )} - <Box - ref={tableContainerRef} - style={{ minHeight: '300px' }} - > - <VirtualTable - ref={tableRef} - autoFitColumns - autoHeight - suppressCellFocus - suppressHorizontalScroll - suppressLoadingOverlay - suppressRowDrag - columnDefs={columnDefs} - enableCellChangeFlash={false} - fullWidthCellRenderer={FullWidthDiscCell} - getRowHeight={getRowHeight} - getRowId={(data) => data.data.id} - isFullWidthRow={(data) => { - return isFullWidthRow(data.rowNode) || false; - }} - isRowSelectable={(data) => { - if (isFullWidthRow(data.data)) return false; - return true; - }} - rowData={songsRowData} - rowSelection="multiple" - onCellContextMenu={handleContextMenu} - onRowDoubleClicked={handleRowDoubleClick} - /> - </Box> - <Stack - ref={cq.ref} - mt="5rem" - > - <> - {cq.height || cq.width ? ( - <> - {carousels.map((carousel, index) => ( - <SwiperGridCarousel - key={`carousel-${carousel.uniqueId}-${index}`} - cardRows={[ - { - property: 'name', - route: { - route: AppRoute.LIBRARY_ALBUMS_DETAIL, - slugs: [{ idProperty: 'id', slugProperty: 'albumId' }], - }, - }, - { - arrayProperty: 'name', - property: 'albumArtists', - route: { - route: AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, - slugs: [{ idProperty: 'id', slugProperty: 'albumArtistId' }], - }, - }, - ]} - data={carousel.data} - isLoading={carousel.loading} - itemType={LibraryItem.ALBUM} - route={{ - route: AppRoute.LIBRARY_ALBUMS_DETAIL, - slugs: [{ idProperty: 'id', slugProperty: 'albumId' }], - }} - title={{ - label: carousel.title, - }} - uniqueId={carousel.uniqueId} - /> - ))} - </> - ) : null} - </> - </Stack> - </ContentContainer> - ); + <> + {cq.height || cq.width ? ( + <> + {carousels.map((carousel, index) => ( + <SwiperGridCarousel + key={`carousel-${carousel.uniqueId}-${index}`} + cardRows={[ + { + property: 'name', + route: { + route: AppRoute.LIBRARY_ALBUMS_DETAIL, + slugs: [ + { idProperty: 'id', slugProperty: 'albumId' }, + ], + }, + }, + { + arrayProperty: 'name', + property: 'albumArtists', + route: { + route: AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, + slugs: [ + { + idProperty: 'id', + slugProperty: 'albumArtistId', + }, + ], + }, + }, + ]} + data={carousel.data} + isLoading={carousel.loading} + itemType={LibraryItem.ALBUM} + route={{ + route: AppRoute.LIBRARY_ALBUMS_DETAIL, + slugs: [{ idProperty: 'id', slugProperty: 'albumId' }], + }} + title={{ + label: carousel.title, + }} + uniqueId={carousel.uniqueId} + /> + ))} + </> + ) : null} + </> + </Stack> + </ContentContainer> + ); }; diff --git a/src/renderer/features/albums/components/album-detail-header.tsx b/src/renderer/features/albums/components/album-detail-header.tsx index 5dcc7c45..e6c88eb4 100644 --- a/src/renderer/features/albums/components/album-detail-header.tsx +++ b/src/renderer/features/albums/components/album-detail-header.tsx @@ -12,118 +12,122 @@ import { useCurrentServer } from '/@/renderer/store'; import { formatDurationString } from '/@/renderer/utils'; interface AlbumDetailHeaderProps { - background: string; + background: string; } export const AlbumDetailHeader = forwardRef( - ({ background }: AlbumDetailHeaderProps, ref: Ref<HTMLDivElement>) => { - const { albumId } = useParams() as { albumId: string }; - const server = useCurrentServer(); - const detailQuery = useAlbumDetail({ query: { id: albumId }, serverId: server?.id }); - const cq = useContainerQuery(); + ({ background }: AlbumDetailHeaderProps, ref: Ref<HTMLDivElement>) => { + const { albumId } = useParams() as { albumId: string }; + const server = useCurrentServer(); + const detailQuery = useAlbumDetail({ query: { id: albumId }, serverId: server?.id }); + const cq = useContainerQuery(); - const metadataItems = [ - { - id: 'releaseYear', - secondary: false, - value: detailQuery?.data?.releaseYear, - }, - { - id: 'songCount', - secondary: false, - value: `${detailQuery?.data?.songCount} songs`, - }, - { - id: 'duration', - secondary: true, - value: detailQuery?.data?.duration && formatDurationString(detailQuery.data.duration), - }, - ]; + const metadataItems = [ + { + id: 'releaseYear', + secondary: false, + value: detailQuery?.data?.releaseYear, + }, + { + id: 'songCount', + secondary: false, + value: `${detailQuery?.data?.songCount} songs`, + }, + { + id: 'duration', + secondary: true, + value: + detailQuery?.data?.duration && formatDurationString(detailQuery.data.duration), + }, + ]; - const updateRatingMutation = useSetRating({}); + const updateRatingMutation = useSetRating({}); - const handleUpdateRating = (rating: number) => { - if (!detailQuery?.data) return; + const handleUpdateRating = (rating: number) => { + if (!detailQuery?.data) return; - updateRatingMutation.mutate({ - query: { - item: [detailQuery.data], - rating, - }, - serverId: detailQuery.data.serverId, - }); - }; + updateRatingMutation.mutate({ + query: { + item: [detailQuery.data], + rating, + }, + serverId: detailQuery.data.serverId, + }); + }; - const handleClearRating = () => { - if (!detailQuery?.data || !detailQuery?.data.userRating) return; + const handleClearRating = () => { + if (!detailQuery?.data || !detailQuery?.data.userRating) return; - updateRatingMutation.mutate({ - query: { - item: [detailQuery.data], - rating: 0, - }, - serverId: detailQuery.data.serverId, - }); - }; + updateRatingMutation.mutate({ + query: { + item: [detailQuery.data], + rating: 0, + }, + serverId: detailQuery.data.serverId, + }); + }; - const showRating = detailQuery?.data?.serverType === ServerType.NAVIDROME; + const showRating = detailQuery?.data?.serverType === ServerType.NAVIDROME; - return ( - <Stack ref={cq.ref}> - <LibraryHeader - ref={ref} - background={background} - imageUrl={detailQuery?.data?.imageUrl} - item={{ route: AppRoute.LIBRARY_ALBUMS, type: LibraryItem.ALBUM }} - title={detailQuery?.data?.name || ''} - > - <Stack spacing="sm"> - <Group spacing="sm"> - {metadataItems.map((item, index) => ( - <Fragment key={`item-${item.id}-${index}`}> - {index > 0 && <Text $noSelect>•</Text>} - <Text $secondary={item.secondary}>{item.value}</Text> - </Fragment> - ))} - {showRating && ( - <> - <Text $noSelect>•</Text> - <Rating - readOnly={detailQuery?.isFetching || updateRatingMutation.isLoading} - value={detailQuery?.data?.userRating || 0} - onChange={handleUpdateRating} - onClick={handleClearRating} - /> - </> - )} - </Group> - <Group - spacing="md" - sx={{ - WebkitBoxOrient: 'vertical', - WebkitLineClamp: 2, - overflow: 'hidden', - }} - > - {detailQuery?.data?.albumArtists.map((artist) => ( - <Text - key={`artist-${artist.id}`} - $link - component={Link} - fw={600} - size="md" - to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, { - albumArtistId: artist.id, - })} - variant="subtle" + return ( + <Stack ref={cq.ref}> + <LibraryHeader + ref={ref} + background={background} + imageUrl={detailQuery?.data?.imageUrl} + item={{ route: AppRoute.LIBRARY_ALBUMS, type: LibraryItem.ALBUM }} + title={detailQuery?.data?.name || ''} > - {artist.name} - </Text> - ))} - </Group> - </Stack> - </LibraryHeader> - </Stack> - ); - }, + <Stack spacing="sm"> + <Group spacing="sm"> + {metadataItems.map((item, index) => ( + <Fragment key={`item-${item.id}-${index}`}> + {index > 0 && <Text $noSelect>•</Text>} + <Text $secondary={item.secondary}>{item.value}</Text> + </Fragment> + ))} + {showRating && ( + <> + <Text $noSelect>•</Text> + <Rating + readOnly={ + detailQuery?.isFetching || + updateRatingMutation.isLoading + } + value={detailQuery?.data?.userRating || 0} + onChange={handleUpdateRating} + onClick={handleClearRating} + /> + </> + )} + </Group> + <Group + spacing="md" + sx={{ + WebkitBoxOrient: 'vertical', + WebkitLineClamp: 2, + overflow: 'hidden', + }} + > + {detailQuery?.data?.albumArtists.map((artist) => ( + <Text + key={`artist-${artist.id}`} + $link + component={Link} + fw={600} + size="md" + to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, { + albumArtistId: artist.id, + })} + variant="subtle" + > + {artist.name} + </Text> + ))} + </Group> + </Stack> + </LibraryHeader> + </Stack> + ); + }, ); diff --git a/src/renderer/features/albums/components/album-list-content.tsx b/src/renderer/features/albums/components/album-list-content.tsx index d3e13c19..33d0a893 100644 --- a/src/renderer/features/albums/components/album-list-content.tsx +++ b/src/renderer/features/albums/components/album-list-content.tsx @@ -7,40 +7,40 @@ import { useAlbumListStore } from '/@/renderer/store'; import { ListDisplayType } from '/@/renderer/types'; const AlbumListGridView = lazy(() => - import('/@/renderer/features/albums/components/album-list-grid-view').then((module) => ({ - default: module.AlbumListGridView, - })), + import('/@/renderer/features/albums/components/album-list-grid-view').then((module) => ({ + default: module.AlbumListGridView, + })), ); const AlbumListTableView = lazy(() => - import('/@/renderer/features/albums/components/album-list-table-view').then((module) => ({ - default: module.AlbumListTableView, - })), + import('/@/renderer/features/albums/components/album-list-table-view').then((module) => ({ + default: module.AlbumListTableView, + })), ); interface AlbumListContentProps { - gridRef: MutableRefObject<VirtualInfiniteGridRef | null>; - itemCount?: number; - tableRef: MutableRefObject<AgGridReactType | null>; + gridRef: MutableRefObject<VirtualInfiniteGridRef | null>; + itemCount?: number; + tableRef: MutableRefObject<AgGridReactType | null>; } export const AlbumListContent = ({ itemCount, gridRef, tableRef }: AlbumListContentProps) => { - const { id, pageKey } = useAlbumListContext(); - const { display } = useAlbumListStore({ id, key: pageKey }); + const { id, pageKey } = useAlbumListContext(); + const { display } = useAlbumListStore({ id, key: pageKey }); - return ( - <Suspense fallback={<Spinner container />}> - {display === ListDisplayType.CARD || display === ListDisplayType.POSTER ? ( - <AlbumListGridView - gridRef={gridRef} - itemCount={itemCount} - /> - ) : ( - <AlbumListTableView - itemCount={itemCount} - tableRef={tableRef} - /> - )} - </Suspense> - ); + return ( + <Suspense fallback={<Spinner container />}> + {display === ListDisplayType.CARD || display === ListDisplayType.POSTER ? ( + <AlbumListGridView + gridRef={gridRef} + itemCount={itemCount} + /> + ) : ( + <AlbumListTableView + itemCount={itemCount} + tableRef={tableRef} + /> + )} + </Suspense> + ); }; diff --git a/src/renderer/features/albums/components/album-list-grid-view.tsx b/src/renderer/features/albums/components/album-list-grid-view.tsx index 57adb16f..6a574569 100644 --- a/src/renderer/features/albums/components/album-list-grid-view.tsx +++ b/src/renderer/features/albums/components/album-list-grid-view.tsx @@ -7,194 +7,194 @@ import { queryKeys } from '/@/renderer/api/query-keys'; import { Album, AlbumListQuery, AlbumListSort, LibraryItem } from '/@/renderer/api/types'; import { ALBUM_CARD_ROWS } from '/@/renderer/components'; import { - VirtualGridAutoSizerContainer, - VirtualInfiniteGrid, + VirtualGridAutoSizerContainer, + VirtualInfiniteGrid, } from '/@/renderer/components/virtual-grid'; import { useAlbumListContext } from '/@/renderer/features/albums/context/album-list-context'; import { usePlayQueueAdd } from '/@/renderer/features/player'; import { AppRoute } from '/@/renderer/router/routes'; import { - useAlbumListFilter, - useAlbumListStore, - useCurrentServer, - useListStoreActions, + useAlbumListFilter, + useAlbumListStore, + useCurrentServer, + useListStoreActions, } from '/@/renderer/store'; import { CardRow, ListDisplayType } from '/@/renderer/types'; import { useCreateFavorite, useDeleteFavorite } from '/@/renderer/features/shared'; export const AlbumListGridView = ({ gridRef, itemCount }: any) => { - const queryClient = useQueryClient(); - const server = useCurrentServer(); - const handlePlayQueueAdd = usePlayQueueAdd(); - const { id, pageKey } = useAlbumListContext(); - const { grid, display } = useAlbumListStore({ id, key: pageKey }); - const { setGrid } = useListStoreActions(); - const filter = useAlbumListFilter({ id, key: pageKey }); + const queryClient = useQueryClient(); + const server = useCurrentServer(); + const handlePlayQueueAdd = usePlayQueueAdd(); + const { id, pageKey } = useAlbumListContext(); + const { grid, display } = useAlbumListStore({ id, key: pageKey }); + const { setGrid } = useListStoreActions(); + const filter = useAlbumListFilter({ id, key: pageKey }); - const createFavoriteMutation = useCreateFavorite({}); - const deleteFavoriteMutation = useDeleteFavorite({}); + const createFavoriteMutation = useCreateFavorite({}); + const deleteFavoriteMutation = useDeleteFavorite({}); - const handleFavorite = (options: { - id: string[]; - isFavorite: boolean; - itemType: LibraryItem; - }) => { - const { id, itemType, isFavorite } = options; - if (isFavorite) { - deleteFavoriteMutation.mutate({ - query: { - id, - type: itemType, + const handleFavorite = (options: { + id: string[]; + isFavorite: boolean; + itemType: LibraryItem; + }) => { + const { id, itemType, isFavorite } = options; + if (isFavorite) { + deleteFavoriteMutation.mutate({ + query: { + id, + type: itemType, + }, + serverId: server?.id, + }); + } else { + createFavoriteMutation.mutate({ + query: { + id, + type: itemType, + }, + serverId: server?.id, + }); + } + }; + + const cardRows = useMemo(() => { + const rows: CardRow<Album>[] = [ALBUM_CARD_ROWS.name]; + + switch (filter.sortBy) { + case AlbumListSort.ALBUM_ARTIST: + rows.push(ALBUM_CARD_ROWS.albumArtists); + rows.push(ALBUM_CARD_ROWS.releaseYear); + break; + case AlbumListSort.ARTIST: + rows.push(ALBUM_CARD_ROWS.artists); + rows.push(ALBUM_CARD_ROWS.releaseYear); + break; + case AlbumListSort.COMMUNITY_RATING: + rows.push(ALBUM_CARD_ROWS.albumArtists); + break; + case AlbumListSort.DURATION: + rows.push(ALBUM_CARD_ROWS.albumArtists); + rows.push(ALBUM_CARD_ROWS.duration); + break; + case AlbumListSort.FAVORITED: + rows.push(ALBUM_CARD_ROWS.albumArtists); + rows.push(ALBUM_CARD_ROWS.releaseYear); + break; + case AlbumListSort.NAME: + rows.push(ALBUM_CARD_ROWS.albumArtists); + rows.push(ALBUM_CARD_ROWS.releaseYear); + break; + case AlbumListSort.PLAY_COUNT: + rows.push(ALBUM_CARD_ROWS.albumArtists); + rows.push(ALBUM_CARD_ROWS.playCount); + break; + case AlbumListSort.RANDOM: + rows.push(ALBUM_CARD_ROWS.albumArtists); + rows.push(ALBUM_CARD_ROWS.releaseYear); + break; + case AlbumListSort.RATING: + rows.push(ALBUM_CARD_ROWS.albumArtists); + rows.push(ALBUM_CARD_ROWS.rating); + break; + case AlbumListSort.RECENTLY_ADDED: + rows.push(ALBUM_CARD_ROWS.albumArtists); + rows.push(ALBUM_CARD_ROWS.createdAt); + break; + case AlbumListSort.RECENTLY_PLAYED: + rows.push(ALBUM_CARD_ROWS.albumArtists); + rows.push(ALBUM_CARD_ROWS.lastPlayedAt); + break; + case AlbumListSort.SONG_COUNT: + rows.push(ALBUM_CARD_ROWS.albumArtists); + rows.push(ALBUM_CARD_ROWS.songCount); + break; + case AlbumListSort.YEAR: + rows.push(ALBUM_CARD_ROWS.albumArtists); + rows.push(ALBUM_CARD_ROWS.releaseYear); + break; + case AlbumListSort.RELEASE_DATE: + rows.push(ALBUM_CARD_ROWS.albumArtists); + rows.push(ALBUM_CARD_ROWS.releaseDate); + } + + return rows; + }, [filter.sortBy]); + + const handleGridScroll = useCallback( + (e: ListOnScrollProps) => { + setGrid({ data: { scrollOffset: e.scrollOffset }, key: pageKey }); }, - serverId: server?.id, - }); - } else { - createFavoriteMutation.mutate({ - query: { - id, - type: itemType, + [pageKey, setGrid], + ); + + const fetch = useCallback( + async ({ skip, take }: { skip: number; take: number }) => { + if (!server) { + return []; + } + + const query: AlbumListQuery = { + limit: take, + startIndex: skip, + ...filter, + _custom: { + jellyfin: { + ...filter._custom?.jellyfin, + }, + navidrome: { + ...filter._custom?.navidrome, + }, + }, + }; + + const queryKey = queryKeys.albums.list(server?.id || '', query); + + const albums = await queryClient.fetchQuery(queryKey, async ({ signal }) => + controller.getAlbumList({ + apiClientProps: { + server, + signal, + }, + query, + }), + ); + + return albums; }, - serverId: server?.id, - }); - } - }; + [filter, queryClient, server], + ); - const cardRows = useMemo(() => { - const rows: CardRow<Album>[] = [ALBUM_CARD_ROWS.name]; - - switch (filter.sortBy) { - case AlbumListSort.ALBUM_ARTIST: - rows.push(ALBUM_CARD_ROWS.albumArtists); - rows.push(ALBUM_CARD_ROWS.releaseYear); - break; - case AlbumListSort.ARTIST: - rows.push(ALBUM_CARD_ROWS.artists); - rows.push(ALBUM_CARD_ROWS.releaseYear); - break; - case AlbumListSort.COMMUNITY_RATING: - rows.push(ALBUM_CARD_ROWS.albumArtists); - break; - case AlbumListSort.DURATION: - rows.push(ALBUM_CARD_ROWS.albumArtists); - rows.push(ALBUM_CARD_ROWS.duration); - break; - case AlbumListSort.FAVORITED: - rows.push(ALBUM_CARD_ROWS.albumArtists); - rows.push(ALBUM_CARD_ROWS.releaseYear); - break; - case AlbumListSort.NAME: - rows.push(ALBUM_CARD_ROWS.albumArtists); - rows.push(ALBUM_CARD_ROWS.releaseYear); - break; - case AlbumListSort.PLAY_COUNT: - rows.push(ALBUM_CARD_ROWS.albumArtists); - rows.push(ALBUM_CARD_ROWS.playCount); - break; - case AlbumListSort.RANDOM: - rows.push(ALBUM_CARD_ROWS.albumArtists); - rows.push(ALBUM_CARD_ROWS.releaseYear); - break; - case AlbumListSort.RATING: - rows.push(ALBUM_CARD_ROWS.albumArtists); - rows.push(ALBUM_CARD_ROWS.rating); - break; - case AlbumListSort.RECENTLY_ADDED: - rows.push(ALBUM_CARD_ROWS.albumArtists); - rows.push(ALBUM_CARD_ROWS.createdAt); - break; - case AlbumListSort.RECENTLY_PLAYED: - rows.push(ALBUM_CARD_ROWS.albumArtists); - rows.push(ALBUM_CARD_ROWS.lastPlayedAt); - break; - case AlbumListSort.SONG_COUNT: - rows.push(ALBUM_CARD_ROWS.albumArtists); - rows.push(ALBUM_CARD_ROWS.songCount); - break; - case AlbumListSort.YEAR: - rows.push(ALBUM_CARD_ROWS.albumArtists); - rows.push(ALBUM_CARD_ROWS.releaseYear); - break; - case AlbumListSort.RELEASE_DATE: - rows.push(ALBUM_CARD_ROWS.albumArtists); - rows.push(ALBUM_CARD_ROWS.releaseDate); - } - - return rows; - }, [filter.sortBy]); - - const handleGridScroll = useCallback( - (e: ListOnScrollProps) => { - setGrid({ data: { scrollOffset: e.scrollOffset }, key: pageKey }); - }, - [pageKey, setGrid], - ); - - const fetch = useCallback( - async ({ skip, take }: { skip: number; take: number }) => { - if (!server) { - return []; - } - - const query: AlbumListQuery = { - limit: take, - startIndex: skip, - ...filter, - _custom: { - jellyfin: { - ...filter._custom?.jellyfin, - }, - navidrome: { - ...filter._custom?.navidrome, - }, - }, - }; - - const queryKey = queryKeys.albums.list(server?.id || '', query); - - const albums = await queryClient.fetchQuery(queryKey, async ({ signal }) => - controller.getAlbumList({ - apiClientProps: { - server, - signal, - }, - query, - }), - ); - - return albums; - }, - [filter, queryClient, server], - ); - - return ( - <VirtualGridAutoSizerContainer> - <AutoSizer> - {({ height, width }) => ( - <VirtualInfiniteGrid - key={`album-list-${server?.id}-${display}`} - ref={gridRef} - cardRows={cardRows} - display={display || ListDisplayType.CARD} - fetchFn={fetch} - handleFavorite={handleFavorite} - handlePlayQueueAdd={handlePlayQueueAdd} - height={height} - initialScrollOffset={grid?.scrollOffset || 0} - itemCount={itemCount || 0} - itemGap={20} - itemSize={grid?.itemsPerRow || 5} - itemType={LibraryItem.ALBUM} - loading={itemCount === undefined || itemCount === null} - minimumBatchSize={40} - route={{ - route: AppRoute.LIBRARY_ALBUMS_DETAIL, - slugs: [{ idProperty: 'id', slugProperty: 'albumId' }], - }} - width={width} - onScroll={handleGridScroll} - /> - )} - </AutoSizer> - </VirtualGridAutoSizerContainer> - ); + return ( + <VirtualGridAutoSizerContainer> + <AutoSizer> + {({ height, width }) => ( + <VirtualInfiniteGrid + key={`album-list-${server?.id}-${display}`} + ref={gridRef} + cardRows={cardRows} + display={display || ListDisplayType.CARD} + fetchFn={fetch} + handleFavorite={handleFavorite} + handlePlayQueueAdd={handlePlayQueueAdd} + height={height} + initialScrollOffset={grid?.scrollOffset || 0} + itemCount={itemCount || 0} + itemGap={20} + itemSize={grid?.itemsPerRow || 5} + itemType={LibraryItem.ALBUM} + loading={itemCount === undefined || itemCount === null} + minimumBatchSize={40} + route={{ + route: AppRoute.LIBRARY_ALBUMS_DETAIL, + slugs: [{ idProperty: 'id', slugProperty: 'albumId' }], + }} + width={width} + onScroll={handleGridScroll} + /> + )} + </AutoSizer> + </VirtualGridAutoSizerContainer> + ); }; diff --git a/src/renderer/features/albums/components/album-list-header-filters.tsx b/src/renderer/features/albums/components/album-list-header-filters.tsx index 6981126b..b5284487 100644 --- a/src/renderer/features/albums/components/album-list-header-filters.tsx +++ b/src/renderer/features/albums/components/album-list-header-filters.tsx @@ -6,16 +6,16 @@ import { openModal } from '@mantine/modals'; import { useQueryClient } from '@tanstack/react-query'; import debounce from 'lodash/debounce'; import { - RiSortAsc, - RiSortDesc, - RiFolder2Line, - RiMoreFill, - RiAddBoxFill, - RiPlayFill, - RiAddCircleFill, - RiRefreshLine, - RiSettings3Fill, - RiFilterFill, + RiSortAsc, + RiSortDesc, + RiFolder2Line, + RiMoreFill, + RiAddBoxFill, + RiPlayFill, + RiAddCircleFill, + RiRefreshLine, + RiSettings3Fill, + RiFilterFill, } from 'react-icons/ri'; import { api } from '/@/renderer/api'; import { queryKeys } from '/@/renderer/api/query-keys'; @@ -23,10 +23,10 @@ import { AlbumListQuery, AlbumListSort, LibraryItem, SortOrder } from '/@/render import { Button, DropdownMenu, MultiSelect, Slider, Switch, Text } from '/@/renderer/components'; import { useContainerQuery } from '/@/renderer/hooks'; import { - AlbumListFilter, - useAlbumListStore, - useCurrentServer, - useListStoreActions, + AlbumListFilter, + useAlbumListStore, + useCurrentServer, + useListStoreActions, } from '/@/renderer/store'; import { ServerType, Play, ListDisplayType, TableColumn } from '/@/renderer/types'; import { useMusicFolders } from '/@/renderer/features/shared'; @@ -38,588 +38,612 @@ import { VirtualInfiniteGridRef } from '/@/renderer/components/virtual-grid'; import { ALBUM_TABLE_COLUMNS } from '/@/renderer/components/virtual-table'; const FILTERS = { - jellyfin: [ - { defaultOrder: SortOrder.ASC, name: 'Album Artist', value: AlbumListSort.ALBUM_ARTIST }, - { - defaultOrder: SortOrder.DESC, - name: 'Community Rating', - value: AlbumListSort.COMMUNITY_RATING, - }, - { defaultOrder: SortOrder.DESC, name: 'Critic Rating', value: AlbumListSort.CRITIC_RATING }, - { defaultOrder: SortOrder.ASC, name: 'Name', value: AlbumListSort.NAME }, - { defaultOrder: SortOrder.ASC, name: 'Random', value: AlbumListSort.RANDOM }, - { defaultOrder: SortOrder.DESC, name: 'Recently Added', value: AlbumListSort.RECENTLY_ADDED }, - { defaultOrder: SortOrder.DESC, name: 'Release Date', value: AlbumListSort.RELEASE_DATE }, - ], - navidrome: [ - { defaultOrder: SortOrder.ASC, name: 'Album Artist', value: AlbumListSort.ALBUM_ARTIST }, - { defaultOrder: SortOrder.ASC, name: 'Artist', value: AlbumListSort.ARTIST }, - { defaultOrder: SortOrder.DESC, name: 'Duration', value: AlbumListSort.DURATION }, - { defaultOrder: SortOrder.DESC, name: 'Most Played', value: AlbumListSort.PLAY_COUNT }, - { defaultOrder: SortOrder.ASC, name: 'Name', value: AlbumListSort.NAME }, - { defaultOrder: SortOrder.ASC, name: 'Random', value: AlbumListSort.RANDOM }, - { defaultOrder: SortOrder.DESC, name: 'Rating', value: AlbumListSort.RATING }, - { defaultOrder: SortOrder.DESC, name: 'Recently Added', value: AlbumListSort.RECENTLY_ADDED }, - { defaultOrder: SortOrder.DESC, name: 'Recently Played', value: AlbumListSort.RECENTLY_PLAYED }, - { defaultOrder: SortOrder.DESC, name: 'Song Count', value: AlbumListSort.SONG_COUNT }, - { defaultOrder: SortOrder.DESC, name: 'Favorited', value: AlbumListSort.FAVORITED }, - { defaultOrder: SortOrder.DESC, name: 'Year', value: AlbumListSort.YEAR }, - ], + jellyfin: [ + { defaultOrder: SortOrder.ASC, name: 'Album Artist', value: AlbumListSort.ALBUM_ARTIST }, + { + defaultOrder: SortOrder.DESC, + name: 'Community Rating', + value: AlbumListSort.COMMUNITY_RATING, + }, + { defaultOrder: SortOrder.DESC, name: 'Critic Rating', value: AlbumListSort.CRITIC_RATING }, + { defaultOrder: SortOrder.ASC, name: 'Name', value: AlbumListSort.NAME }, + { defaultOrder: SortOrder.ASC, name: 'Random', value: AlbumListSort.RANDOM }, + { + defaultOrder: SortOrder.DESC, + name: 'Recently Added', + value: AlbumListSort.RECENTLY_ADDED, + }, + { defaultOrder: SortOrder.DESC, name: 'Release Date', value: AlbumListSort.RELEASE_DATE }, + ], + navidrome: [ + { defaultOrder: SortOrder.ASC, name: 'Album Artist', value: AlbumListSort.ALBUM_ARTIST }, + { defaultOrder: SortOrder.ASC, name: 'Artist', value: AlbumListSort.ARTIST }, + { defaultOrder: SortOrder.DESC, name: 'Duration', value: AlbumListSort.DURATION }, + { defaultOrder: SortOrder.DESC, name: 'Most Played', value: AlbumListSort.PLAY_COUNT }, + { defaultOrder: SortOrder.ASC, name: 'Name', value: AlbumListSort.NAME }, + { defaultOrder: SortOrder.ASC, name: 'Random', value: AlbumListSort.RANDOM }, + { defaultOrder: SortOrder.DESC, name: 'Rating', value: AlbumListSort.RATING }, + { + defaultOrder: SortOrder.DESC, + name: 'Recently Added', + value: AlbumListSort.RECENTLY_ADDED, + }, + { + defaultOrder: SortOrder.DESC, + name: 'Recently Played', + value: AlbumListSort.RECENTLY_PLAYED, + }, + { defaultOrder: SortOrder.DESC, name: 'Song Count', value: AlbumListSort.SONG_COUNT }, + { defaultOrder: SortOrder.DESC, name: 'Favorited', value: AlbumListSort.FAVORITED }, + { defaultOrder: SortOrder.DESC, name: 'Year', value: AlbumListSort.YEAR }, + ], }; const ORDER = [ - { name: 'Ascending', value: SortOrder.ASC }, - { name: 'Descending', value: SortOrder.DESC }, + { name: 'Ascending', value: SortOrder.ASC }, + { name: 'Descending', value: SortOrder.DESC }, ]; interface AlbumListHeaderFiltersProps { - customFilters?: Partial<AlbumListFilter>; - gridRef: MutableRefObject<VirtualInfiniteGridRef | null>; - itemCount?: number; - tableRef: MutableRefObject<AgGridReactType | null>; + customFilters?: Partial<AlbumListFilter>; + gridRef: MutableRefObject<VirtualInfiniteGridRef | null>; + itemCount?: number; + tableRef: MutableRefObject<AgGridReactType | null>; } export const AlbumListHeaderFilters = ({ - customFilters, - gridRef, - tableRef, - itemCount, + customFilters, + gridRef, + tableRef, + itemCount, }: AlbumListHeaderFiltersProps) => { - const queryClient = useQueryClient(); - const { id, pageKey } = useAlbumListContext(); - const server = useCurrentServer(); - const { setFilter, setTablePagination, setTable, setGrid, setDisplayType, setTableColumns } = - useListStoreActions(); - const { display, filter, table, grid } = useAlbumListStore({ id, key: pageKey }); - const cq = useContainerQuery(); + const queryClient = useQueryClient(); + const { id, pageKey } = useAlbumListContext(); + const server = useCurrentServer(); + const { setFilter, setTablePagination, setTable, setGrid, setDisplayType, setTableColumns } = + useListStoreActions(); + const { display, filter, table, grid } = useAlbumListStore({ id, key: pageKey }); + const cq = useContainerQuery(); - const musicFoldersQuery = useMusicFolders({ query: null, serverId: server?.id }); + const musicFoldersQuery = useMusicFolders({ query: null, serverId: server?.id }); - const sortByLabel = - (server?.type && - FILTERS[server.type as keyof typeof FILTERS].find((f) => f.value === filter.sortBy)?.name) || - 'Unknown'; + const sortByLabel = + (server?.type && + FILTERS[server.type as keyof typeof FILTERS].find((f) => f.value === filter.sortBy) + ?.name) || + 'Unknown'; - const sortOrderLabel = ORDER.find((o) => o.value === filter.sortOrder)?.name || 'Unknown'; - - const fetch = useCallback( - async (skip: number, take: number, filters: AlbumListFilter) => { - const query: AlbumListQuery = { - limit: take, - startIndex: skip, - ...filters, - _custom: { - jellyfin: { - ...filters._custom?.jellyfin, - ...customFilters?._custom?.jellyfin, - }, - navidrome: { - ...filters._custom?.navidrome, - ...customFilters?._custom?.navidrome, - }, - }, - ...customFilters, - }; - - const queryKey = queryKeys.albums.list(server?.id || '', query); - - const albums = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.getAlbumList({ - apiClientProps: { - server, - signal, - }, - query, - }), - { cacheTime: 1000 * 60 * 1 }, - ); - - return albums; - }, - [customFilters, queryClient, server], - ); - - const handleFilterChange = useCallback( - async (filters: AlbumListFilter) => { - if (display === ListDisplayType.TABLE || display === ListDisplayType.TABLE_PAGINATED) { - const dataSource: IDatasource = { - getRows: async (params) => { - const limit = params.endRow - params.startRow; - const startIndex = params.startRow; + const sortOrderLabel = ORDER.find((o) => o.value === filter.sortOrder)?.name || 'Unknown'; + const fetch = useCallback( + async (skip: number, take: number, filters: AlbumListFilter) => { const query: AlbumListQuery = { - limit, - startIndex, - ...filters, - ...customFilters, - _custom: { - jellyfin: { - ...filters._custom?.jellyfin, - ...customFilters?._custom?.jellyfin, + limit: take, + startIndex: skip, + ...filters, + _custom: { + jellyfin: { + ...filters._custom?.jellyfin, + ...customFilters?._custom?.jellyfin, + }, + navidrome: { + ...filters._custom?.navidrome, + ...customFilters?._custom?.navidrome, + }, }, - navidrome: { - ...filters._custom?.navidrome, - ...customFilters?._custom?.navidrome, - }, - }, + ...customFilters, }; const queryKey = queryKeys.albums.list(server?.id || '', query); - const albumsRes = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.getAlbumList({ - apiClientProps: { - server, - signal, - }, - query, - }), - { cacheTime: 1000 * 60 * 1 }, + const albums = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.getAlbumList({ + apiClientProps: { + server, + signal, + }, + query, + }), + { cacheTime: 1000 * 60 * 1 }, ); - return params.successCallback(albumsRes?.items || [], albumsRes?.totalRecordCount || 0); - }, - rowCount: undefined, - }; - tableRef.current?.api.setDatasource(dataSource); - tableRef.current?.api.purgeInfiniteCache(); - tableRef.current?.api.ensureIndexVisible(0, 'top'); - - if (display === ListDisplayType.TABLE_PAGINATED) { - setTablePagination({ data: { currentPage: 0 }, key: 'album' }); - } - } else { - gridRef.current?.scrollTo(0); - gridRef.current?.resetLoadMoreItemsCache(); - - // Refetching within the virtualized grid may be inconsistent due to it refetching - // using an outdated set of filters. To avoid this, we fetch using the updated filters - // and then set the grid's data here. - const data = await fetch(0, 200, filters); - - if (!data?.items) return; - gridRef.current?.setItemData(data.items); - } - }, - [display, tableRef, customFilters, server, queryClient, setTablePagination, gridRef, fetch], - ); - - const handleOpenFiltersModal = () => { - openModal({ - children: ( - <> - {server?.type === ServerType.NAVIDROME ? ( - <NavidromeAlbumFilters - disableArtistFilter={!!customFilters} - handleFilterChange={handleFilterChange} - id={id} - pageKey={pageKey} - serverId={server?.id} - /> - ) : ( - <JellyfinAlbumFilters - disableArtistFilter={!!customFilters} - handleFilterChange={handleFilterChange} - id={id} - pageKey={pageKey} - serverId={server?.id} - /> - )} - </> - ), - title: 'Album Filters', - }); - }; - - const handleRefresh = useCallback(() => { - queryClient.invalidateQueries(queryKeys.albums.list(server?.id || '')); - handleFilterChange(filter); - }, [filter, handleFilterChange, queryClient, server?.id]); - - const handleSetSortBy = useCallback( - (e: MouseEvent<HTMLButtonElement>) => { - if (!e.currentTarget?.value || !server?.type) return; - - const sortOrder = FILTERS[server.type as keyof typeof FILTERS].find( - (f) => f.value === e.currentTarget.value, - )?.defaultOrder; - - const updatedFilters = setFilter({ - data: { - sortBy: e.currentTarget.value as AlbumListSort, - sortOrder: sortOrder || SortOrder.ASC, + return albums; }, - itemType: LibraryItem.ALBUM, - key: 'album', - }) as AlbumListFilter; + [customFilters, queryClient, server], + ); - handleFilterChange(updatedFilters); - }, - [handleFilterChange, server?.type, setFilter], - ); + const handleFilterChange = useCallback( + async (filters: AlbumListFilter) => { + if (display === ListDisplayType.TABLE || display === ListDisplayType.TABLE_PAGINATED) { + const dataSource: IDatasource = { + getRows: async (params) => { + const limit = params.endRow - params.startRow; + const startIndex = params.startRow; - const handleSetMusicFolder = useCallback( - (e: MouseEvent<HTMLButtonElement>) => { - if (!e.currentTarget?.value) return; + const query: AlbumListQuery = { + limit, + startIndex, + ...filters, + ...customFilters, + _custom: { + jellyfin: { + ...filters._custom?.jellyfin, + ...customFilters?._custom?.jellyfin, + }, + navidrome: { + ...filters._custom?.navidrome, + ...customFilters?._custom?.navidrome, + }, + }, + }; - let updatedFilters = null; - if (e.currentTarget.value === String(filter.musicFolderId)) { - updatedFilters = setFilter({ - data: { musicFolderId: undefined }, - itemType: LibraryItem.ALBUM, - key: 'album', - }) as AlbumListFilter; - } else { - updatedFilters = setFilter({ - data: { musicFolderId: e.currentTarget.value }, - itemType: LibraryItem.ALBUM, - key: 'album', - }) as AlbumListFilter; - } + const queryKey = queryKeys.albums.list(server?.id || '', query); - handleFilterChange(updatedFilters); - }, - [handleFilterChange, filter.musicFolderId, setFilter], - ); + const albumsRes = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.getAlbumList({ + apiClientProps: { + server, + signal, + }, + query, + }), + { cacheTime: 1000 * 60 * 1 }, + ); - const handleToggleSortOrder = useCallback(() => { - const newSortOrder = filter.sortOrder === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC; - const updatedFilters = setFilter({ - data: { sortOrder: newSortOrder }, - itemType: LibraryItem.ALBUM, - key: 'album', - }) as AlbumListFilter; - handleFilterChange(updatedFilters); - }, [filter.sortOrder, handleFilterChange, setFilter]); + return params.successCallback( + albumsRes?.items || [], + albumsRes?.totalRecordCount || 0, + ); + }, + rowCount: undefined, + }; + tableRef.current?.api.setDatasource(dataSource); + tableRef.current?.api.purgeInfiniteCache(); + tableRef.current?.api.ensureIndexVisible(0, 'top'); - const handlePlayQueueAdd = usePlayQueueAdd(); - - const handlePlay = async (playType: Play) => { - if (!itemCount || itemCount === 0 || !server) return; - - const query = { - startIndex: 0, - ...filter, - ...customFilters, - _custom: { - jellyfin: { - ...filter._custom?.jellyfin, - ...customFilters?._custom?.jellyfin, - }, - navidrome: { - ...filter._custom?.navidrome, - ...customFilters?._custom?.navidrome, - }, - }, - }; - const queryKey = queryKeys.albums.list(server?.id || '', query); - - const albumListRes = await queryClient.fetchQuery({ - queryFn: ({ signal }) => - api.controller.getAlbumList({ apiClientProps: { server, signal }, query }), - queryKey, - }); - - const albumIds = albumListRes?.items?.map((a) => a.id) || []; - - handlePlayQueueAdd?.({ - byItemType: { - id: albumIds, - type: LibraryItem.ALBUM, - }, - playType, - }); - }; - - const handleItemSize = (e: number) => { - if (display === ListDisplayType.TABLE || display === ListDisplayType.TABLE_PAGINATED) { - setTable({ data: { rowHeight: e }, key: 'album' }); - } else { - setGrid({ data: { itemsPerRow: e }, key: 'album' }); - } - }; - - const debouncedHandleItemSize = debounce(handleItemSize, 20); - - const handleSetViewType = useCallback( - (e: MouseEvent<HTMLButtonElement>) => { - if (!e.currentTarget?.value) return; - setDisplayType({ data: e.currentTarget.value as ListDisplayType, key: 'album' }); - }, - [setDisplayType], - ); - - const handleTableColumns = (values: TableColumn[]) => { - const existingColumns = table.columns; - - if (values.length === 0) { - return setTableColumns({ - data: [], - key: 'album', - }); - } - - // If adding a column - if (values.length > existingColumns.length) { - const newColumn = { column: values[values.length - 1], width: 100 }; - - setTableColumns({ data: [...existingColumns, newColumn], key: 'album' }); - } else { - // If removing a column - const removed = existingColumns.filter((column) => !values.includes(column.column)); - const newColumns = existingColumns.filter((column) => !removed.includes(column)); - - setTableColumns({ data: newColumns, key: 'album' }); - } - - return tableRef.current?.api.sizeColumnsToFit(); - }; - - const handleAutoFitColumns = (e: ChangeEvent<HTMLInputElement>) => { - setTable({ data: { autoFit: e.currentTarget.checked }, key: 'album' }); - - if (e.currentTarget.checked) { - tableRef.current?.api.sizeColumnsToFit(); - } - }; - - const isFilterApplied = useMemo(() => { - const isNavidromeFilterApplied = - server?.type === ServerType.NAVIDROME && - filter?._custom?.navidrome && - Object.values(filter?._custom?.navidrome).some((value) => value !== undefined); - - const isJellyfinFilterApplied = - server?.type === ServerType.JELLYFIN && - filter?._custom?.jellyfin && - Object.values(filter?._custom?.jellyfin).some((value) => value !== undefined); - - return isNavidromeFilterApplied || isJellyfinFilterApplied; - }, [filter?._custom?.jellyfin, filter?._custom?.navidrome, server?.type]); - - return ( - <Flex justify="space-between"> - <Group - ref={cq.ref} - spacing="sm" - w="100%" - > - <DropdownMenu position="bottom-start"> - <DropdownMenu.Target> - <Button - compact - fw={600} - size="md" - variant="subtle" - > - {sortByLabel} - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - {FILTERS[server?.type as keyof typeof FILTERS].map((f) => ( - <DropdownMenu.Item - key={`filter-${f.name}`} - $isActive={f.value === filter.sortBy} - value={f.value} - onClick={handleSetSortBy} - > - {f.name} - </DropdownMenu.Item> - ))} - </DropdownMenu.Dropdown> - </DropdownMenu> - <Button - compact - fw={600} - size="md" - variant="subtle" - onClick={handleToggleSortOrder} - > - {cq.isSm ? ( - sortOrderLabel - ) : ( - <> - {filter.sortOrder === SortOrder.ASC ? ( - <RiSortAsc size={15} /> - ) : ( - <RiSortDesc size={15} /> - )} - </> - )} - </Button> - {server?.type === ServerType.JELLYFIN && ( - <DropdownMenu position="bottom-start"> - <DropdownMenu.Target> - <Button - compact - fw={600} - size="md" - variant="subtle" - > - {cq.isSm ? 'Folder' : <RiFolder2Line size="1.3rem" />} - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - {musicFoldersQuery.data?.items.map((folder) => ( - <DropdownMenu.Item - key={`musicFolder-${folder.id}`} - $isActive={filter.musicFolderId === folder.id} - value={folder.id} - onClick={handleSetMusicFolder} - > - {folder.name} - </DropdownMenu.Item> - ))} - </DropdownMenu.Dropdown> - </DropdownMenu> - )} - <DropdownMenu position="bottom-start"> - <DropdownMenu.Target> - <Button - compact - size="md" - variant="subtle" - > - <RiMoreFill size={15} /> - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - <DropdownMenu.Item - icon={<RiPlayFill />} - onClick={() => handlePlay(Play.NOW)} - > - Play - </DropdownMenu.Item> - <DropdownMenu.Item - icon={<RiAddBoxFill />} - onClick={() => handlePlay(Play.LAST)} - > - Add to queue - </DropdownMenu.Item> - <DropdownMenu.Item - icon={<RiAddCircleFill />} - onClick={() => handlePlay(Play.NEXT)} - > - Add to queue next - </DropdownMenu.Item> - <DropdownMenu.Divider /> - <DropdownMenu.Item - icon={<RiRefreshLine />} - onClick={handleRefresh} - > - Refresh - </DropdownMenu.Item> - </DropdownMenu.Dropdown> - </DropdownMenu> - </Group> - <Group - noWrap - spacing="sm" - > - <Button - compact - size="md" - sx={{ svg: { fill: isFilterApplied ? 'var(--primary-color) !important' : undefined } }} - tooltip={{ label: 'Filters' }} - variant="subtle" - onClick={handleOpenFiltersModal} - > - <RiFilterFill size="1.3rem" /> - </Button> - <DropdownMenu position="bottom-end"> - <DropdownMenu.Target> - <Button - compact - size="md" - tooltip={{ label: 'Configure' }} - variant="subtle" - > - <RiSettings3Fill size="1.3rem" /> - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - <DropdownMenu.Label>Display type</DropdownMenu.Label> - <DropdownMenu.Item - $isActive={display === ListDisplayType.CARD} - value={ListDisplayType.CARD} - onClick={handleSetViewType} - > - Card - </DropdownMenu.Item> - <DropdownMenu.Item - $isActive={display === ListDisplayType.POSTER} - value={ListDisplayType.POSTER} - onClick={handleSetViewType} - > - Poster - </DropdownMenu.Item> - <DropdownMenu.Item - $isActive={display === ListDisplayType.TABLE} - value={ListDisplayType.TABLE} - onClick={handleSetViewType} - > - Table - </DropdownMenu.Item> - <DropdownMenu.Item - $isActive={display === ListDisplayType.TABLE_PAGINATED} - value={ListDisplayType.TABLE_PAGINATED} - onClick={handleSetViewType} - > - Table (paginated) - </DropdownMenu.Item> - <DropdownMenu.Divider /> - <DropdownMenu.Label> - {display === ListDisplayType.CARD || display === ListDisplayType.POSTER - ? 'Items per row' - : 'Item size'} - </DropdownMenu.Label> - <DropdownMenu.Item closeMenuOnClick={false}> - <Slider - defaultValue={ - display === ListDisplayType.CARD || display === ListDisplayType.POSTER - ? grid?.itemsPerRow || 0 - : table.rowHeight + if (display === ListDisplayType.TABLE_PAGINATED) { + setTablePagination({ data: { currentPage: 0 }, key: 'album' }); } - label={null} - max={14} - min={2} - onChange={debouncedHandleItemSize} - /> - </DropdownMenu.Item> - {(display === ListDisplayType.TABLE || display === ListDisplayType.TABLE_PAGINATED) && ( - <> - <DropdownMenu.Label>Table Columns</DropdownMenu.Label> - <DropdownMenu.Item - closeMenuOnClick={false} - component="div" - sx={{ cursor: 'default' }} + } else { + gridRef.current?.scrollTo(0); + gridRef.current?.resetLoadMoreItemsCache(); + + // Refetching within the virtualized grid may be inconsistent due to it refetching + // using an outdated set of filters. To avoid this, we fetch using the updated filters + // and then set the grid's data here. + const data = await fetch(0, 200, filters); + + if (!data?.items) return; + gridRef.current?.setItemData(data.items); + } + }, + [display, tableRef, customFilters, server, queryClient, setTablePagination, gridRef, fetch], + ); + + const handleOpenFiltersModal = () => { + openModal({ + children: ( + <> + {server?.type === ServerType.NAVIDROME ? ( + <NavidromeAlbumFilters + disableArtistFilter={!!customFilters} + handleFilterChange={handleFilterChange} + id={id} + pageKey={pageKey} + serverId={server?.id} + /> + ) : ( + <JellyfinAlbumFilters + disableArtistFilter={!!customFilters} + handleFilterChange={handleFilterChange} + id={id} + pageKey={pageKey} + serverId={server?.id} + /> + )} + </> + ), + title: 'Album Filters', + }); + }; + + const handleRefresh = useCallback(() => { + queryClient.invalidateQueries(queryKeys.albums.list(server?.id || '')); + handleFilterChange(filter); + }, [filter, handleFilterChange, queryClient, server?.id]); + + const handleSetSortBy = useCallback( + (e: MouseEvent<HTMLButtonElement>) => { + if (!e.currentTarget?.value || !server?.type) return; + + const sortOrder = FILTERS[server.type as keyof typeof FILTERS].find( + (f) => f.value === e.currentTarget.value, + )?.defaultOrder; + + const updatedFilters = setFilter({ + data: { + sortBy: e.currentTarget.value as AlbumListSort, + sortOrder: sortOrder || SortOrder.ASC, + }, + itemType: LibraryItem.ALBUM, + key: 'album', + }) as AlbumListFilter; + + handleFilterChange(updatedFilters); + }, + [handleFilterChange, server?.type, setFilter], + ); + + const handleSetMusicFolder = useCallback( + (e: MouseEvent<HTMLButtonElement>) => { + if (!e.currentTarget?.value) return; + + let updatedFilters = null; + if (e.currentTarget.value === String(filter.musicFolderId)) { + updatedFilters = setFilter({ + data: { musicFolderId: undefined }, + itemType: LibraryItem.ALBUM, + key: 'album', + }) as AlbumListFilter; + } else { + updatedFilters = setFilter({ + data: { musicFolderId: e.currentTarget.value }, + itemType: LibraryItem.ALBUM, + key: 'album', + }) as AlbumListFilter; + } + + handleFilterChange(updatedFilters); + }, + [handleFilterChange, filter.musicFolderId, setFilter], + ); + + const handleToggleSortOrder = useCallback(() => { + const newSortOrder = filter.sortOrder === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC; + const updatedFilters = setFilter({ + data: { sortOrder: newSortOrder }, + itemType: LibraryItem.ALBUM, + key: 'album', + }) as AlbumListFilter; + handleFilterChange(updatedFilters); + }, [filter.sortOrder, handleFilterChange, setFilter]); + + const handlePlayQueueAdd = usePlayQueueAdd(); + + const handlePlay = async (playType: Play) => { + if (!itemCount || itemCount === 0 || !server) return; + + const query = { + startIndex: 0, + ...filter, + ...customFilters, + _custom: { + jellyfin: { + ...filter._custom?.jellyfin, + ...customFilters?._custom?.jellyfin, + }, + navidrome: { + ...filter._custom?.navidrome, + ...customFilters?._custom?.navidrome, + }, + }, + }; + const queryKey = queryKeys.albums.list(server?.id || '', query); + + const albumListRes = await queryClient.fetchQuery({ + queryFn: ({ signal }) => + api.controller.getAlbumList({ apiClientProps: { server, signal }, query }), + queryKey, + }); + + const albumIds = albumListRes?.items?.map((a) => a.id) || []; + + handlePlayQueueAdd?.({ + byItemType: { + id: albumIds, + type: LibraryItem.ALBUM, + }, + playType, + }); + }; + + const handleItemSize = (e: number) => { + if (display === ListDisplayType.TABLE || display === ListDisplayType.TABLE_PAGINATED) { + setTable({ data: { rowHeight: e }, key: 'album' }); + } else { + setGrid({ data: { itemsPerRow: e }, key: 'album' }); + } + }; + + const debouncedHandleItemSize = debounce(handleItemSize, 20); + + const handleSetViewType = useCallback( + (e: MouseEvent<HTMLButtonElement>) => { + if (!e.currentTarget?.value) return; + setDisplayType({ data: e.currentTarget.value as ListDisplayType, key: 'album' }); + }, + [setDisplayType], + ); + + const handleTableColumns = (values: TableColumn[]) => { + const existingColumns = table.columns; + + if (values.length === 0) { + return setTableColumns({ + data: [], + key: 'album', + }); + } + + // If adding a column + if (values.length > existingColumns.length) { + const newColumn = { column: values[values.length - 1], width: 100 }; + + setTableColumns({ data: [...existingColumns, newColumn], key: 'album' }); + } else { + // If removing a column + const removed = existingColumns.filter((column) => !values.includes(column.column)); + const newColumns = existingColumns.filter((column) => !removed.includes(column)); + + setTableColumns({ data: newColumns, key: 'album' }); + } + + return tableRef.current?.api.sizeColumnsToFit(); + }; + + const handleAutoFitColumns = (e: ChangeEvent<HTMLInputElement>) => { + setTable({ data: { autoFit: e.currentTarget.checked }, key: 'album' }); + + if (e.currentTarget.checked) { + tableRef.current?.api.sizeColumnsToFit(); + } + }; + + const isFilterApplied = useMemo(() => { + const isNavidromeFilterApplied = + server?.type === ServerType.NAVIDROME && + filter?._custom?.navidrome && + Object.values(filter?._custom?.navidrome).some((value) => value !== undefined); + + const isJellyfinFilterApplied = + server?.type === ServerType.JELLYFIN && + filter?._custom?.jellyfin && + Object.values(filter?._custom?.jellyfin).some((value) => value !== undefined); + + return isNavidromeFilterApplied || isJellyfinFilterApplied; + }, [filter?._custom?.jellyfin, filter?._custom?.navidrome, server?.type]); + + return ( + <Flex justify="space-between"> + <Group + ref={cq.ref} + spacing="sm" + w="100%" + > + <DropdownMenu position="bottom-start"> + <DropdownMenu.Target> + <Button + compact + fw={600} + size="md" + variant="subtle" + > + {sortByLabel} + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + {FILTERS[server?.type as keyof typeof FILTERS].map((f) => ( + <DropdownMenu.Item + key={`filter-${f.name}`} + $isActive={f.value === filter.sortBy} + value={f.value} + onClick={handleSetSortBy} + > + {f.name} + </DropdownMenu.Item> + ))} + </DropdownMenu.Dropdown> + </DropdownMenu> + <Button + compact + fw={600} + size="md" + variant="subtle" + onClick={handleToggleSortOrder} > - <Stack> - <MultiSelect - clearable - data={ALBUM_TABLE_COLUMNS} - defaultValue={table?.columns.map((column) => column.column)} - width={300} - onChange={handleTableColumns} - /> - <Group position="apart"> - <Text>Auto Fit Columns</Text> - <Switch - defaultChecked={table.autoFit} - onChange={handleAutoFitColumns} - /> - </Group> - </Stack> - </DropdownMenu.Item> - </> - )} - </DropdownMenu.Dropdown> - </DropdownMenu> - </Group> - </Flex> - ); + {cq.isSm ? ( + sortOrderLabel + ) : ( + <> + {filter.sortOrder === SortOrder.ASC ? ( + <RiSortAsc size={15} /> + ) : ( + <RiSortDesc size={15} /> + )} + </> + )} + </Button> + {server?.type === ServerType.JELLYFIN && ( + <DropdownMenu position="bottom-start"> + <DropdownMenu.Target> + <Button + compact + fw={600} + size="md" + variant="subtle" + > + {cq.isSm ? 'Folder' : <RiFolder2Line size="1.3rem" />} + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + {musicFoldersQuery.data?.items.map((folder) => ( + <DropdownMenu.Item + key={`musicFolder-${folder.id}`} + $isActive={filter.musicFolderId === folder.id} + value={folder.id} + onClick={handleSetMusicFolder} + > + {folder.name} + </DropdownMenu.Item> + ))} + </DropdownMenu.Dropdown> + </DropdownMenu> + )} + <DropdownMenu position="bottom-start"> + <DropdownMenu.Target> + <Button + compact + size="md" + variant="subtle" + > + <RiMoreFill size={15} /> + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + <DropdownMenu.Item + icon={<RiPlayFill />} + onClick={() => handlePlay(Play.NOW)} + > + Play + </DropdownMenu.Item> + <DropdownMenu.Item + icon={<RiAddBoxFill />} + onClick={() => handlePlay(Play.LAST)} + > + Add to queue + </DropdownMenu.Item> + <DropdownMenu.Item + icon={<RiAddCircleFill />} + onClick={() => handlePlay(Play.NEXT)} + > + Add to queue next + </DropdownMenu.Item> + <DropdownMenu.Divider /> + <DropdownMenu.Item + icon={<RiRefreshLine />} + onClick={handleRefresh} + > + Refresh + </DropdownMenu.Item> + </DropdownMenu.Dropdown> + </DropdownMenu> + </Group> + <Group + noWrap + spacing="sm" + > + <Button + compact + size="md" + sx={{ + svg: { + fill: isFilterApplied ? 'var(--primary-color) !important' : undefined, + }, + }} + tooltip={{ label: 'Filters' }} + variant="subtle" + onClick={handleOpenFiltersModal} + > + <RiFilterFill size="1.3rem" /> + </Button> + <DropdownMenu position="bottom-end"> + <DropdownMenu.Target> + <Button + compact + size="md" + tooltip={{ label: 'Configure' }} + variant="subtle" + > + <RiSettings3Fill size="1.3rem" /> + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + <DropdownMenu.Label>Display type</DropdownMenu.Label> + <DropdownMenu.Item + $isActive={display === ListDisplayType.CARD} + value={ListDisplayType.CARD} + onClick={handleSetViewType} + > + Card + </DropdownMenu.Item> + <DropdownMenu.Item + $isActive={display === ListDisplayType.POSTER} + value={ListDisplayType.POSTER} + onClick={handleSetViewType} + > + Poster + </DropdownMenu.Item> + <DropdownMenu.Item + $isActive={display === ListDisplayType.TABLE} + value={ListDisplayType.TABLE} + onClick={handleSetViewType} + > + Table + </DropdownMenu.Item> + <DropdownMenu.Item + $isActive={display === ListDisplayType.TABLE_PAGINATED} + value={ListDisplayType.TABLE_PAGINATED} + onClick={handleSetViewType} + > + Table (paginated) + </DropdownMenu.Item> + <DropdownMenu.Divider /> + <DropdownMenu.Label> + {display === ListDisplayType.CARD || display === ListDisplayType.POSTER + ? 'Items per row' + : 'Item size'} + </DropdownMenu.Label> + <DropdownMenu.Item closeMenuOnClick={false}> + <Slider + defaultValue={ + display === ListDisplayType.CARD || + display === ListDisplayType.POSTER + ? grid?.itemsPerRow || 0 + : table.rowHeight + } + label={null} + max={14} + min={2} + onChange={debouncedHandleItemSize} + /> + </DropdownMenu.Item> + {(display === ListDisplayType.TABLE || + display === ListDisplayType.TABLE_PAGINATED) && ( + <> + <DropdownMenu.Label>Table Columns</DropdownMenu.Label> + <DropdownMenu.Item + closeMenuOnClick={false} + component="div" + sx={{ cursor: 'default' }} + > + <Stack> + <MultiSelect + clearable + data={ALBUM_TABLE_COLUMNS} + defaultValue={table?.columns.map( + (column) => column.column, + )} + width={300} + onChange={handleTableColumns} + /> + <Group position="apart"> + <Text>Auto Fit Columns</Text> + <Switch + defaultChecked={table.autoFit} + onChange={handleAutoFitColumns} + /> + </Group> + </Stack> + </DropdownMenu.Item> + </> + )} + </DropdownMenu.Dropdown> + </DropdownMenu> + </Group> + </Flex> + ); }; diff --git a/src/renderer/features/albums/components/album-list-header.tsx b/src/renderer/features/albums/components/album-list-header.tsx index 67f977b6..4119b74e 100644 --- a/src/renderer/features/albums/components/album-list-header.tsx +++ b/src/renderer/features/albums/components/album-list-header.tsx @@ -13,11 +13,11 @@ import { PageHeader, SearchInput } from '/@/renderer/components'; import { FilterBar, LibraryHeaderBar } from '/@/renderer/features/shared'; import { useContainerQuery } from '/@/renderer/hooks'; import { - AlbumListFilter, - useAlbumListFilter, - useAlbumListStore, - useCurrentServer, - useListStoreActions, + AlbumListFilter, + useAlbumListFilter, + useAlbumListStore, + useCurrentServer, + useListStoreActions, } from '/@/renderer/store'; import { ListDisplayType, Play } from '/@/renderer/types'; import { AlbumListHeaderFilters } from '/@/renderer/features/albums/components/album-list-header-filters'; @@ -27,219 +27,226 @@ import { useAlbumListContext } from '/@/renderer/features/albums/context/album-l import { VirtualInfiniteGridRef } from '/@/renderer/components/virtual-grid'; interface AlbumListHeaderProps { - customFilters?: Partial<AlbumListFilter>; - gridRef: MutableRefObject<VirtualInfiniteGridRef | null>; - itemCount?: number; - tableRef: MutableRefObject<AgGridReactType | null>; - title?: string; + customFilters?: Partial<AlbumListFilter>; + gridRef: MutableRefObject<VirtualInfiniteGridRef | null>; + itemCount?: number; + tableRef: MutableRefObject<AgGridReactType | null>; + title?: string; } export const AlbumListHeader = ({ - itemCount, - gridRef, - tableRef, - title, - customFilters, + itemCount, + gridRef, + tableRef, + title, + customFilters, }: AlbumListHeaderProps) => { - const queryClient = useQueryClient(); - const server = useCurrentServer(); - const { setFilter, setTablePagination } = useListStoreActions(); - const cq = useContainerQuery(); - const { id, pageKey } = useAlbumListContext(); - const { display } = useAlbumListStore({ id, key: pageKey }); - const filter = useAlbumListFilter({ id, key: pageKey }); - - const fetch = useCallback( - async (skip: number, take: number, filters: AlbumListFilter) => { - const query: AlbumListQuery = { - limit: take, - startIndex: skip, - ...filters, - ...customFilters, - _custom: { - jellyfin: { - ...filters._custom?.jellyfin, - ...customFilters?._custom?.jellyfin, - }, - navidrome: { - ...filters._custom?.navidrome, - ...customFilters?._custom?.navidrome, - }, - }, - }; - - const queryKey = queryKeys.albums.list(server?.id || '', query); - - const albums = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - controller.getAlbumList({ - apiClientProps: { - server, - signal, - }, - query, - }), - { cacheTime: 1000 * 60 * 1 }, - ); - - return albums; - }, - [customFilters, queryClient, server], - ); - - const handleFilterChange = useCallback( - async (filters: AlbumListFilter) => { - if (display === ListDisplayType.TABLE || display === ListDisplayType.TABLE_PAGINATED) { - const dataSource: IDatasource = { - getRows: async (params) => { - const limit = params.endRow - params.startRow; - const startIndex = params.startRow; + const queryClient = useQueryClient(); + const server = useCurrentServer(); + const { setFilter, setTablePagination } = useListStoreActions(); + const cq = useContainerQuery(); + const { id, pageKey } = useAlbumListContext(); + const { display } = useAlbumListStore({ id, key: pageKey }); + const filter = useAlbumListFilter({ id, key: pageKey }); + const fetch = useCallback( + async (skip: number, take: number, filters: AlbumListFilter) => { const query: AlbumListQuery = { - limit, - startIndex, - ...filters, - ...customFilters, - _custom: { - jellyfin: { - ...filters._custom?.jellyfin, - ...customFilters?._custom?.jellyfin, + limit: take, + startIndex: skip, + ...filters, + ...customFilters, + _custom: { + jellyfin: { + ...filters._custom?.jellyfin, + ...customFilters?._custom?.jellyfin, + }, + navidrome: { + ...filters._custom?.navidrome, + ...customFilters?._custom?.navidrome, + }, }, - navidrome: { - ...filters._custom?.navidrome, - ...customFilters?._custom?.navidrome, - }, - }, }; const queryKey = queryKeys.albums.list(server?.id || '', query); - const albumsRes = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.getAlbumList({ - apiClientProps: { - server, - signal, - }, - query, - }), - { cacheTime: 1000 * 60 * 1 }, + const albums = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + controller.getAlbumList({ + apiClientProps: { + server, + signal, + }, + query, + }), + { cacheTime: 1000 * 60 * 1 }, ); - params.successCallback(albumsRes?.items || [], albumsRes?.totalRecordCount || 0); - }, - rowCount: undefined, + return albums; + }, + [customFilters, queryClient, server], + ); + + const handleFilterChange = useCallback( + async (filters: AlbumListFilter) => { + if (display === ListDisplayType.TABLE || display === ListDisplayType.TABLE_PAGINATED) { + const dataSource: IDatasource = { + getRows: async (params) => { + const limit = params.endRow - params.startRow; + const startIndex = params.startRow; + + const query: AlbumListQuery = { + limit, + startIndex, + ...filters, + ...customFilters, + _custom: { + jellyfin: { + ...filters._custom?.jellyfin, + ...customFilters?._custom?.jellyfin, + }, + navidrome: { + ...filters._custom?.navidrome, + ...customFilters?._custom?.navidrome, + }, + }, + }; + + const queryKey = queryKeys.albums.list(server?.id || '', query); + + const albumsRes = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.getAlbumList({ + apiClientProps: { + server, + signal, + }, + query, + }), + { cacheTime: 1000 * 60 * 1 }, + ); + + params.successCallback( + albumsRes?.items || [], + albumsRes?.totalRecordCount || 0, + ); + }, + rowCount: undefined, + }; + tableRef.current?.api.setDatasource(dataSource); + tableRef.current?.api.purgeInfiniteCache(); + tableRef.current?.api.ensureIndexVisible(0, 'top'); + + if (display === ListDisplayType.TABLE_PAGINATED) { + setTablePagination({ data: { currentPage: 0 }, key: 'album' }); + } + } else { + gridRef.current?.scrollTo(0); + gridRef.current?.resetLoadMoreItemsCache(); + + // Refetching within the virtualized grid may be inconsistent due to it refetching + // using an outdated set of filters. To avoid this, we fetch using the updated filters + // and then set the grid's data here. + const data = await fetch(0, 200, filters); + + if (!data?.items) return; + gridRef.current?.setItemData(data.items); + } + }, + [display, tableRef, customFilters, server, queryClient, setTablePagination, gridRef, fetch], + ); + + const handleSearch = debounce((e: ChangeEvent<HTMLInputElement>) => { + const previousSearchTerm = filter.searchTerm; + const searchTerm = e.target.value === '' ? undefined : e.target.value; + const updatedFilters = setFilter({ + data: { searchTerm }, + itemType: LibraryItem.ALBUM, + key: 'album', + }) as AlbumListFilter; + if (previousSearchTerm !== searchTerm) handleFilterChange(updatedFilters); + }, 500); + + const handlePlayQueueAdd = usePlayQueueAdd(); + const playButtonBehavior = usePlayButtonBehavior(); + + const handlePlay = async (playType: Play) => { + if (!itemCount || itemCount === 0) return; + + const query = { + startIndex: 0, + ...filter, + ...customFilters, + _custom: { + jellyfin: { + ...filter._custom?.jellyfin, + ...customFilters?._custom?.jellyfin, + }, + navidrome: { + ...filter._custom?.navidrome, + ...customFilters?._custom?.navidrome, + }, + }, }; - tableRef.current?.api.setDatasource(dataSource); - tableRef.current?.api.purgeInfiniteCache(); - tableRef.current?.api.ensureIndexVisible(0, 'top'); + const queryKey = queryKeys.albums.list(server?.id || '', query); - if (display === ListDisplayType.TABLE_PAGINATED) { - setTablePagination({ data: { currentPage: 0 }, key: 'album' }); - } - } else { - gridRef.current?.scrollTo(0); - gridRef.current?.resetLoadMoreItemsCache(); + const albumListRes = await queryClient.fetchQuery({ + queryFn: ({ signal }) => + api.controller.getAlbumList({ apiClientProps: { server, signal }, query }), + queryKey, + }); - // Refetching within the virtualized grid may be inconsistent due to it refetching - // using an outdated set of filters. To avoid this, we fetch using the updated filters - // and then set the grid's data here. - const data = await fetch(0, 200, filters); + const albumIds = albumListRes?.items?.map((item) => item.id) || []; - if (!data?.items) return; - gridRef.current?.setItemData(data.items); - } - }, - [display, tableRef, customFilters, server, queryClient, setTablePagination, gridRef, fetch], - ); - - const handleSearch = debounce((e: ChangeEvent<HTMLInputElement>) => { - const previousSearchTerm = filter.searchTerm; - const searchTerm = e.target.value === '' ? undefined : e.target.value; - const updatedFilters = setFilter({ - data: { searchTerm }, - itemType: LibraryItem.ALBUM, - key: 'album', - }) as AlbumListFilter; - if (previousSearchTerm !== searchTerm) handleFilterChange(updatedFilters); - }, 500); - - const handlePlayQueueAdd = usePlayQueueAdd(); - const playButtonBehavior = usePlayButtonBehavior(); - - const handlePlay = async (playType: Play) => { - if (!itemCount || itemCount === 0) return; - - const query = { - startIndex: 0, - ...filter, - ...customFilters, - _custom: { - jellyfin: { - ...filter._custom?.jellyfin, - ...customFilters?._custom?.jellyfin, - }, - navidrome: { - ...filter._custom?.navidrome, - ...customFilters?._custom?.navidrome, - }, - }, + handlePlayQueueAdd?.({ + byItemType: { + id: albumIds, + type: LibraryItem.ALBUM, + }, + playType, + }); }; - const queryKey = queryKeys.albums.list(server?.id || '', query); - const albumListRes = await queryClient.fetchQuery({ - queryFn: ({ signal }) => - api.controller.getAlbumList({ apiClientProps: { server, signal }, query }), - queryKey, - }); - - const albumIds = albumListRes?.items?.map((item) => item.id) || []; - - handlePlayQueueAdd?.({ - byItemType: { - id: albumIds, - type: LibraryItem.ALBUM, - }, - playType, - }); - }; - - return ( - <Stack - ref={cq.ref} - spacing={0} - > - <PageHeader backgroundColor="var(--titlebar-bg)"> - <Flex - justify="space-between" - w="100%" + return ( + <Stack + ref={cq.ref} + spacing={0} > - <LibraryHeaderBar> - <LibraryHeaderBar.PlayButton onClick={() => handlePlay(playButtonBehavior)} /> - <LibraryHeaderBar.Title>{title || 'Albums'}</LibraryHeaderBar.Title> - <LibraryHeaderBar.Badge isLoading={itemCount === null || itemCount === undefined}> - {itemCount} - </LibraryHeaderBar.Badge> - </LibraryHeaderBar> - <Group> - <SearchInput - defaultValue={filter.searchTerm} - openedWidth={cq.isMd ? 250 : cq.isSm ? 200 : 150} - onChange={handleSearch} - /> - </Group> - </Flex> - </PageHeader> - <FilterBar> - <AlbumListHeaderFilters - customFilters={customFilters} - gridRef={gridRef} - itemCount={itemCount} - tableRef={tableRef} - /> - </FilterBar> - </Stack> - ); + <PageHeader backgroundColor="var(--titlebar-bg)"> + <Flex + justify="space-between" + w="100%" + > + <LibraryHeaderBar> + <LibraryHeaderBar.PlayButton + onClick={() => handlePlay(playButtonBehavior)} + /> + <LibraryHeaderBar.Title>{title || 'Albums'}</LibraryHeaderBar.Title> + <LibraryHeaderBar.Badge + isLoading={itemCount === null || itemCount === undefined} + > + {itemCount} + </LibraryHeaderBar.Badge> + </LibraryHeaderBar> + <Group> + <SearchInput + defaultValue={filter.searchTerm} + openedWidth={cq.isMd ? 250 : cq.isSm ? 200 : 150} + onChange={handleSearch} + /> + </Group> + </Flex> + </PageHeader> + <FilterBar> + <AlbumListHeaderFilters + customFilters={customFilters} + gridRef={gridRef} + itemCount={itemCount} + tableRef={tableRef} + /> + </FilterBar> + </Stack> + ); }; diff --git a/src/renderer/features/albums/components/album-list-table-view.tsx b/src/renderer/features/albums/components/album-list-table-view.tsx index 906f36b0..57adb649 100644 --- a/src/renderer/features/albums/components/album-list-table-view.tsx +++ b/src/renderer/features/albums/components/album-list-table-view.tsx @@ -1,11 +1,11 @@ import { useMemo, useCallback } from 'react'; import { - ColDef, - GridReadyEvent, - IDatasource, - PaginationChangedEvent, - BodyScrollEvent, - RowDoubleClickedEvent, + ColDef, + GridReadyEvent, + IDatasource, + PaginationChangedEvent, + BodyScrollEvent, + RowDoubleClickedEvent, } from '@ag-grid-community/core'; import { api } from '/@/renderer/api'; import { queryKeys } from '/@/renderer/api/query-keys'; @@ -13,10 +13,10 @@ import { AlbumListQuery, LibraryItem } from '/@/renderer/api/types'; import { getColumnDefs, TablePagination, VirtualTable } from '/@/renderer/components/virtual-table'; import { useAlbumListContext } from '/@/renderer/features/albums/context/album-list-context'; import { - useCurrentServer, - useAlbumListFilter, - useListStoreActions, - useAlbumListStore, + useCurrentServer, + useAlbumListFilter, + useListStoreActions, + useAlbumListStore, } from '/@/renderer/store'; import { useQueryClient } from '@tanstack/react-query'; import { AnimatePresence } from 'framer-motion'; @@ -29,179 +29,188 @@ import { AppRoute } from '/@/renderer/router/routes'; import { VirtualGridAutoSizerContainer } from '/@/renderer/components/virtual-grid'; export const AlbumListTableView = ({ tableRef, itemCount }: any) => { - const queryClient = useQueryClient(); - const navigate = useNavigate(); - const server = useCurrentServer(); - const { id, pageKey } = useAlbumListContext(); - const filter = useAlbumListFilter({ id, key: pageKey }); - const { setTable, setTablePagination } = useListStoreActions(); - const { table, display } = useAlbumListStore({ id, key: pageKey }); - const columnDefs: ColDef[] = useMemo(() => getColumnDefs(table.columns), [table.columns]); - const isPaginationEnabled = display === ListDisplayType.TABLE_PAGINATED; + const queryClient = useQueryClient(); + const navigate = useNavigate(); + const server = useCurrentServer(); + const { id, pageKey } = useAlbumListContext(); + const filter = useAlbumListFilter({ id, key: pageKey }); + const { setTable, setTablePagination } = useListStoreActions(); + const { table, display } = useAlbumListStore({ id, key: pageKey }); + const columnDefs: ColDef[] = useMemo(() => getColumnDefs(table.columns), [table.columns]); + const isPaginationEnabled = display === ListDisplayType.TABLE_PAGINATED; - const onTableReady = useCallback( - (params: GridReadyEvent) => { - const dataSource: IDatasource = { - getRows: async (params) => { - const limit = params.endRow - params.startRow; - const startIndex = params.startRow; + const onTableReady = useCallback( + (params: GridReadyEvent) => { + const dataSource: IDatasource = { + getRows: async (params) => { + const limit = params.endRow - params.startRow; + const startIndex = params.startRow; - const query: AlbumListQuery = { - limit, - startIndex, - ...filter, - _custom: { - jellyfin: { - ...filter._custom?.jellyfin, - }, - navidrome: { - ...filter._custom?.navidrome, - }, - }, - }; + const query: AlbumListQuery = { + limit, + startIndex, + ...filter, + _custom: { + jellyfin: { + ...filter._custom?.jellyfin, + }, + navidrome: { + ...filter._custom?.navidrome, + }, + }, + }; - const queryKey = queryKeys.albums.list(server?.id || '', query); + const queryKey = queryKeys.albums.list(server?.id || '', query); - if (!server) { - return params.failCallback(); - } + if (!server) { + return params.failCallback(); + } - const albumsRes = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.getAlbumList({ - apiClientProps: { - server, - signal, + const albumsRes = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.getAlbumList({ + apiClientProps: { + server, + signal, + }, + query, + }), + { cacheTime: 1000 * 60 * 1 }, + ); + + return params.successCallback( + albumsRes?.items || [], + albumsRes?.totalRecordCount || 0, + ); }, - query, - }), - { cacheTime: 1000 * 60 * 1 }, - ); - - return params.successCallback(albumsRes?.items || [], albumsRes?.totalRecordCount || 0); + rowCount: undefined, + }; + params.api.setDatasource(dataSource); + params.api.ensureIndexVisible(table.scrollOffset || 0, 'top'); }, - rowCount: undefined, - }; - params.api.setDatasource(dataSource); - params.api.ensureIndexVisible(table.scrollOffset || 0, 'top'); - }, - [filter, queryClient, server, table.scrollOffset], - ); + [filter, queryClient, server, table.scrollOffset], + ); - const onTablePaginationChanged = useCallback( - (event: PaginationChangedEvent) => { - if (!isPaginationEnabled || !event.api) return; + const onTablePaginationChanged = useCallback( + (event: PaginationChangedEvent) => { + if (!isPaginationEnabled || !event.api) return; - try { - // Scroll to top of page on pagination change - const currentPageStartIndex = table.pagination.currentPage * table.pagination.itemsPerPage; - event.api?.ensureIndexVisible(currentPageStartIndex, 'top'); - } catch (err) { - console.log(err); - } + try { + // Scroll to top of page on pagination change + const currentPageStartIndex = + table.pagination.currentPage * table.pagination.itemsPerPage; + event.api?.ensureIndexVisible(currentPageStartIndex, 'top'); + } catch (err) { + console.log(err); + } - setTablePagination({ - data: { - itemsPerPage: event.api.paginationGetPageSize(), - totalItems: event.api.paginationGetRowCount(), - totalPages: event.api.paginationGetTotalPages() + 1, + setTablePagination({ + data: { + itemsPerPage: event.api.paginationGetPageSize(), + totalItems: event.api.paginationGetRowCount(), + totalPages: event.api.paginationGetTotalPages() + 1, + }, + key: pageKey, + }); }, - key: pageKey, - }); - }, - [ - isPaginationEnabled, - setTablePagination, - pageKey, - table.pagination.currentPage, - table.pagination.itemsPerPage, - ], - ); + [ + isPaginationEnabled, + setTablePagination, + pageKey, + table.pagination.currentPage, + table.pagination.itemsPerPage, + ], + ); - const handleTableColumnChange = useCallback(() => { - const { columnApi } = tableRef?.current || {}; - const columnsOrder = columnApi?.getAllGridColumns(); + const handleTableColumnChange = useCallback(() => { + const { columnApi } = tableRef?.current || {}; + const columnsOrder = columnApi?.getAllGridColumns(); - if (!columnsOrder) return; + if (!columnsOrder) return; - const columnsInSettings = table.columns; - const updatedColumns = []; - for (const column of columnsOrder) { - const columnInSettings = columnsInSettings.find((c) => c.column === column.getColDef().colId); + const columnsInSettings = table.columns; + const updatedColumns = []; + for (const column of columnsOrder) { + const columnInSettings = columnsInSettings.find( + (c) => c.column === column.getColDef().colId, + ); - if (columnInSettings) { - updatedColumns.push({ - ...columnInSettings, - ...(!table.autoFit && { - width: column.getColDef().width, - }), - }); - } - } + if (columnInSettings) { + updatedColumns.push({ + ...columnInSettings, + ...(!table.autoFit && { + width: column.getColDef().width, + }), + }); + } + } - setTable({ data: { columns: updatedColumns }, key: pageKey }); - }, [tableRef, table.columns, table.autoFit, setTable, pageKey]); + setTable({ data: { columns: updatedColumns }, key: pageKey }); + }, [tableRef, table.columns, table.autoFit, setTable, pageKey]); - const debouncedTableColumnChange = debounce(handleTableColumnChange, 200); + const debouncedTableColumnChange = debounce(handleTableColumnChange, 200); - const handleTableScroll = (e: BodyScrollEvent) => { - const scrollOffset = Number((e.top / table.rowHeight).toFixed(0)); - setTable({ data: { scrollOffset }, key: pageKey }); - }; + const handleTableScroll = (e: BodyScrollEvent) => { + const scrollOffset = Number((e.top / table.rowHeight).toFixed(0)); + setTable({ data: { scrollOffset }, key: pageKey }); + }; - const handleContextMenu = useHandleTableContextMenu(LibraryItem.ALBUM, ALBUM_CONTEXT_MENU_ITEMS); + const handleContextMenu = useHandleTableContextMenu( + LibraryItem.ALBUM, + ALBUM_CONTEXT_MENU_ITEMS, + ); - const handleRowDoubleClick = (e: RowDoubleClickedEvent) => { - navigate(generatePath(AppRoute.LIBRARY_ALBUMS_DETAIL, { albumId: e.data.id })); - }; + const handleRowDoubleClick = (e: RowDoubleClickedEvent) => { + navigate(generatePath(AppRoute.LIBRARY_ALBUMS_DETAIL, { albumId: e.data.id })); + }; - return ( - <> - <VirtualGridAutoSizerContainer> - <VirtualTable - // https://github.com/ag-grid/ag-grid/issues/5284 - // Key is used to force remount of table when display, rowHeight, or server changes - key={`table-${display}-${table.rowHeight}-${server?.id}`} - ref={tableRef} - alwaysShowHorizontalScroll - suppressRowDrag - autoFitColumns={table.autoFit} - blockLoadDebounceMillis={200} - columnDefs={columnDefs} - getRowId={(data) => data.data.id} - infiniteInitialRowCount={itemCount || 100} - pagination={isPaginationEnabled} - paginationAutoPageSize={isPaginationEnabled} - paginationPageSize={table.pagination.itemsPerPage || 100} - rowBuffer={20} - rowHeight={table.rowHeight || 40} - rowModelType="infinite" - onBodyScrollEnd={handleTableScroll} - onCellContextMenu={handleContextMenu} - onColumnMoved={handleTableColumnChange} - onColumnResized={debouncedTableColumnChange} - onGridReady={onTableReady} - onPaginationChanged={onTablePaginationChanged} - onRowDoubleClicked={handleRowDoubleClick} - /> - </VirtualGridAutoSizerContainer> - {isPaginationEnabled && ( - <AnimatePresence - presenceAffectsLayout - initial={false} - mode="wait" - > - {display === ListDisplayType.TABLE_PAGINATED && ( - <TablePagination - pageKey={pageKey} - pagination={table.pagination} - setPagination={setTablePagination} - tableRef={tableRef} - /> - )} - </AnimatePresence> - )} - </> - ); + return ( + <> + <VirtualGridAutoSizerContainer> + <VirtualTable + // https://github.com/ag-grid/ag-grid/issues/5284 + // Key is used to force remount of table when display, rowHeight, or server changes + key={`table-${display}-${table.rowHeight}-${server?.id}`} + ref={tableRef} + alwaysShowHorizontalScroll + suppressRowDrag + autoFitColumns={table.autoFit} + blockLoadDebounceMillis={200} + columnDefs={columnDefs} + getRowId={(data) => data.data.id} + infiniteInitialRowCount={itemCount || 100} + pagination={isPaginationEnabled} + paginationAutoPageSize={isPaginationEnabled} + paginationPageSize={table.pagination.itemsPerPage || 100} + rowBuffer={20} + rowHeight={table.rowHeight || 40} + rowModelType="infinite" + onBodyScrollEnd={handleTableScroll} + onCellContextMenu={handleContextMenu} + onColumnMoved={handleTableColumnChange} + onColumnResized={debouncedTableColumnChange} + onGridReady={onTableReady} + onPaginationChanged={onTablePaginationChanged} + onRowDoubleClicked={handleRowDoubleClick} + /> + </VirtualGridAutoSizerContainer> + {isPaginationEnabled && ( + <AnimatePresence + presenceAffectsLayout + initial={false} + mode="wait" + > + {display === ListDisplayType.TABLE_PAGINATED && ( + <TablePagination + pageKey={pageKey} + pagination={table.pagination} + setPagination={setTablePagination} + tableRef={tableRef} + /> + )} + </AnimatePresence> + )} + </> + ); }; diff --git a/src/renderer/features/albums/components/jellyfin-album-filters.tsx b/src/renderer/features/albums/components/jellyfin-album-filters.tsx index a74e65e6..baa665c2 100644 --- a/src/renderer/features/albums/components/jellyfin-album-filters.tsx +++ b/src/renderer/features/albums/components/jellyfin-album-filters.tsx @@ -8,220 +8,220 @@ import { AlbumArtistListSort, LibraryItem, SortOrder } from '/@/renderer/api/typ import { useAlbumArtistList } from '/@/renderer/features/artists/queries/album-artist-list-query'; interface JellyfinAlbumFiltersProps { - disableArtistFilter?: boolean; - handleFilterChange: (filters: AlbumListFilter) => void; - id?: string; - pageKey: string; - serverId?: string; + disableArtistFilter?: boolean; + handleFilterChange: (filters: AlbumListFilter) => void; + id?: string; + pageKey: string; + serverId?: string; } export const JellyfinAlbumFilters = ({ - disableArtistFilter, - handleFilterChange, - pageKey, - id, - serverId, + disableArtistFilter, + handleFilterChange, + pageKey, + id, + serverId, }: JellyfinAlbumFiltersProps) => { - const filter = useAlbumListFilter({ id, key: pageKey }); - const { setFilter } = useListStoreActions(); + const filter = useAlbumListFilter({ id, key: pageKey }); + const { setFilter } = useListStoreActions(); - // TODO - eventually replace with /items/filters endpoint to fetch genres and tags specific to the selected library - const genreListQuery = useGenreList({ query: null, serverId }); + // TODO - eventually replace with /items/filters endpoint to fetch genres and tags specific to the selected library + const genreListQuery = useGenreList({ query: null, serverId }); - const genreList = useMemo(() => { - if (!genreListQuery?.data) return []; - return genreListQuery.data.items.map((genre) => ({ - label: genre.name, - value: genre.id, - })); - }, [genreListQuery.data]); + const genreList = useMemo(() => { + if (!genreListQuery?.data) return []; + return genreListQuery.data.items.map((genre) => ({ + label: genre.name, + value: genre.id, + })); + }, [genreListQuery.data]); - const selectedGenres = useMemo(() => { - return filter._custom?.jellyfin?.GenreIds?.split(','); - }, [filter._custom?.jellyfin?.GenreIds]); + const selectedGenres = useMemo(() => { + return filter._custom?.jellyfin?.GenreIds?.split(','); + }, [filter._custom?.jellyfin?.GenreIds]); - const toggleFilters = [ - { - label: 'Is favorited', - onChange: (e: ChangeEvent<HTMLInputElement>) => { - const updatedFilters = setFilter({ - data: { - _custom: { - ...filter._custom, - jellyfin: { - ...filter._custom?.jellyfin, - IsFavorite: e.currentTarget.checked ? true : undefined, - }, + const toggleFilters = [ + { + label: 'Is favorited', + onChange: (e: ChangeEvent<HTMLInputElement>) => { + const updatedFilters = setFilter({ + data: { + _custom: { + ...filter._custom, + jellyfin: { + ...filter._custom?.jellyfin, + IsFavorite: e.currentTarget.checked ? true : undefined, + }, + }, + }, + itemType: LibraryItem.ALBUM, + key: pageKey, + }) as AlbumListFilter; + handleFilterChange(updatedFilters); }, - }, - itemType: LibraryItem.ALBUM, - key: pageKey, + value: filter._custom?.jellyfin?.IsFavorite, + }, + ]; + + const handleMinYearFilter = debounce((e: number | string) => { + if (typeof e === 'number' && (e < 1700 || e > 2300)) return; + const updatedFilters = setFilter({ + data: { + _custom: { + ...filter._custom, + jellyfin: { + ...filter._custom?.jellyfin, + minYear: e === '' ? undefined : (e as number), + }, + }, + }, + itemType: LibraryItem.ALBUM, + key: pageKey, }) as AlbumListFilter; handleFilterChange(updatedFilters); - }, - value: filter._custom?.jellyfin?.IsFavorite, - }, - ]; + }, 500); - const handleMinYearFilter = debounce((e: number | string) => { - if (typeof e === 'number' && (e < 1700 || e > 2300)) return; - const updatedFilters = setFilter({ - data: { - _custom: { - ...filter._custom, - jellyfin: { - ...filter._custom?.jellyfin, - minYear: e === '' ? undefined : (e as number), - }, + const handleMaxYearFilter = debounce((e: number | string) => { + if (typeof e === 'number' && (e < 1700 || e > 2300)) return; + const updatedFilters = setFilter({ + data: { + _custom: { + ...filter._custom, + jellyfin: { + ...filter._custom?.jellyfin, + maxYear: e === '' ? undefined : (e as number), + }, + }, + }, + itemType: LibraryItem.ALBUM, + key: pageKey, + }) as AlbumListFilter; + handleFilterChange(updatedFilters); + }, 500); + + const handleGenresFilter = debounce((e: string[] | undefined) => { + const genreFilterString = e?.length ? e.join(',') : undefined; + const updatedFilters = setFilter({ + data: { + _custom: { + ...filter._custom, + jellyfin: { + ...filter._custom?.jellyfin, + GenreIds: genreFilterString, + }, + }, + }, + itemType: LibraryItem.ALBUM, + key: pageKey, + }) as AlbumListFilter; + handleFilterChange(updatedFilters); + }, 250); + + const [albumArtistSearchTerm, setAlbumArtistSearchTerm] = useState<string>(''); + + const albumArtistListQuery = useAlbumArtistList({ + options: { + cacheTime: 1000 * 60 * 2, + staleTime: 1000 * 60 * 1, }, - }, - itemType: LibraryItem.ALBUM, - key: pageKey, - }) as AlbumListFilter; - handleFilterChange(updatedFilters); - }, 500); - - const handleMaxYearFilter = debounce((e: number | string) => { - if (typeof e === 'number' && (e < 1700 || e > 2300)) return; - const updatedFilters = setFilter({ - data: { - _custom: { - ...filter._custom, - jellyfin: { - ...filter._custom?.jellyfin, - maxYear: e === '' ? undefined : (e as number), - }, + query: { + sortBy: AlbumArtistListSort.NAME, + sortOrder: SortOrder.ASC, + startIndex: 0, }, - }, - itemType: LibraryItem.ALBUM, - key: pageKey, - }) as AlbumListFilter; - handleFilterChange(updatedFilters); - }, 500); + serverId, + }); - const handleGenresFilter = debounce((e: string[] | undefined) => { - const genreFilterString = e?.length ? e.join(',') : undefined; - const updatedFilters = setFilter({ - data: { - _custom: { - ...filter._custom, - jellyfin: { - ...filter._custom?.jellyfin, - GenreIds: genreFilterString, - }, - }, - }, - itemType: LibraryItem.ALBUM, - key: pageKey, - }) as AlbumListFilter; - handleFilterChange(updatedFilters); - }, 250); + const selectableAlbumArtists = useMemo(() => { + if (!albumArtistListQuery?.data?.items) return []; - const [albumArtistSearchTerm, setAlbumArtistSearchTerm] = useState<string>(''); + return albumArtistListQuery?.data?.items?.map((artist) => ({ + label: artist.name, + value: artist.id, + })); + }, [albumArtistListQuery?.data?.items]); - const albumArtistListQuery = useAlbumArtistList({ - options: { - cacheTime: 1000 * 60 * 2, - staleTime: 1000 * 60 * 1, - }, - query: { - sortBy: AlbumArtistListSort.NAME, - sortOrder: SortOrder.ASC, - startIndex: 0, - }, - serverId, - }); + const handleAlbumArtistFilter = (e: string[] | null) => { + const albumArtistFilterString = e?.length ? e.join(',') : undefined; + const updatedFilters = setFilter({ + data: { + _custom: { + ...filter._custom, + jellyfin: { + ...filter._custom?.jellyfin, + AlbumArtistIds: albumArtistFilterString, + }, + }, + }, + itemType: LibraryItem.ALBUM, + key: pageKey, + }) as AlbumListFilter; + handleFilterChange(updatedFilters); + }; - const selectableAlbumArtists = useMemo(() => { - if (!albumArtistListQuery?.data?.items) return []; + return ( + <Stack p="0.8rem"> + {toggleFilters.map((filter) => ( + <Group + key={`nd-filter-${filter.label}`} + position="apart" + > + <Text>{filter.label}</Text> + <Switch + checked={filter?.value || false} + size="xs" + onChange={filter.onChange} + /> + </Group> + ))} + <Divider my="0.5rem" /> + <Group grow> + <NumberInput + defaultValue={filter._custom?.jellyfin?.minYear} + hideControls={false} + label="From year" + max={2300} + min={1700} + required={!!filter._custom?.jellyfin?.maxYear} + onChange={(e) => handleMinYearFilter(e)} + /> + <NumberInput + defaultValue={filter._custom?.jellyfin?.maxYear} + hideControls={false} + label="To year" + max={2300} + min={1700} + required={!!filter._custom?.jellyfin?.minYear} + onChange={(e) => handleMaxYearFilter(e)} + /> + </Group> + <Group grow> + <MultiSelect + clearable + searchable + data={genreList} + defaultValue={selectedGenres} + label="Genres" + onChange={handleGenresFilter} + /> + </Group> - return albumArtistListQuery?.data?.items?.map((artist) => ({ - label: artist.name, - value: artist.id, - })); - }, [albumArtistListQuery?.data?.items]); - - const handleAlbumArtistFilter = (e: string[] | null) => { - const albumArtistFilterString = e?.length ? e.join(',') : undefined; - const updatedFilters = setFilter({ - data: { - _custom: { - ...filter._custom, - jellyfin: { - ...filter._custom?.jellyfin, - AlbumArtistIds: albumArtistFilterString, - }, - }, - }, - itemType: LibraryItem.ALBUM, - key: pageKey, - }) as AlbumListFilter; - handleFilterChange(updatedFilters); - }; - - return ( - <Stack p="0.8rem"> - {toggleFilters.map((filter) => ( - <Group - key={`nd-filter-${filter.label}`} - position="apart" - > - <Text>{filter.label}</Text> - <Switch - checked={filter?.value || false} - size="xs" - onChange={filter.onChange} - /> - </Group> - ))} - <Divider my="0.5rem" /> - <Group grow> - <NumberInput - defaultValue={filter._custom?.jellyfin?.minYear} - hideControls={false} - label="From year" - max={2300} - min={1700} - required={!!filter._custom?.jellyfin?.maxYear} - onChange={(e) => handleMinYearFilter(e)} - /> - <NumberInput - defaultValue={filter._custom?.jellyfin?.maxYear} - hideControls={false} - label="To year" - max={2300} - min={1700} - required={!!filter._custom?.jellyfin?.minYear} - onChange={(e) => handleMaxYearFilter(e)} - /> - </Group> - <Group grow> - <MultiSelect - clearable - searchable - data={genreList} - defaultValue={selectedGenres} - label="Genres" - onChange={handleGenresFilter} - /> - </Group> - - <Group grow> - <MultiSelect - clearable - searchable - data={selectableAlbumArtists} - defaultValue={filter._custom?.jellyfin?.AlbumArtistIds?.split(',')} - disabled={disableArtistFilter} - label="Artist" - limit={300} - placeholder="Type to search for an artist" - rightSection={albumArtistListQuery.isFetching ? <SpinnerIcon /> : undefined} - searchValue={albumArtistSearchTerm} - onChange={handleAlbumArtistFilter} - onSearchChange={setAlbumArtistSearchTerm} - /> - </Group> - </Stack> - ); + <Group grow> + <MultiSelect + clearable + searchable + data={selectableAlbumArtists} + defaultValue={filter._custom?.jellyfin?.AlbumArtistIds?.split(',')} + disabled={disableArtistFilter} + label="Artist" + limit={300} + placeholder="Type to search for an artist" + rightSection={albumArtistListQuery.isFetching ? <SpinnerIcon /> : undefined} + searchValue={albumArtistSearchTerm} + onChange={handleAlbumArtistFilter} + onSearchChange={setAlbumArtistSearchTerm} + /> + </Group> + </Stack> + ); }; diff --git a/src/renderer/features/albums/components/navidrome-album-filters.tsx b/src/renderer/features/albums/components/navidrome-album-filters.tsx index b57b219e..43cddd0e 100644 --- a/src/renderer/features/albums/components/navidrome-album-filters.tsx +++ b/src/renderer/features/albums/components/navidrome-album-filters.tsx @@ -8,241 +8,241 @@ import { useAlbumArtistList } from '/@/renderer/features/artists/queries/album-a import { AlbumArtistListSort, LibraryItem, SortOrder } from '/@/renderer/api/types'; interface NavidromeAlbumFiltersProps { - disableArtistFilter?: boolean; - handleFilterChange: (filters: AlbumListFilter) => void; - id?: string; - pageKey: string; - serverId?: string; + disableArtistFilter?: boolean; + handleFilterChange: (filters: AlbumListFilter) => void; + id?: string; + pageKey: string; + serverId?: string; } export const NavidromeAlbumFilters = ({ - handleFilterChange, - disableArtistFilter, - pageKey, - id, - serverId, -}: NavidromeAlbumFiltersProps) => { - const filter = useAlbumListFilter({ id, key: pageKey }); - const { setFilter } = useListStoreActions(); - - const genreListQuery = useGenreList({ query: null, serverId }); - - const genreList = useMemo(() => { - if (!genreListQuery?.data) return []; - return genreListQuery.data.items.map((genre) => ({ - label: genre.name, - value: genre.id, - })); - }, [genreListQuery.data]); - - const handleGenresFilter = debounce((e: string | null) => { - const updatedFilters = setFilter({ - data: { - _custom: { - ...filter._custom, - navidrome: { - ...filter._custom?.navidrome, - genre_id: e || undefined, - }, - }, - }, - itemType: LibraryItem.ALBUM, - key: 'album', - }) as AlbumListFilter; - handleFilterChange(updatedFilters); - }, 250); - - const toggleFilters = [ - { - label: 'Is rated', - onChange: (e: ChangeEvent<HTMLInputElement>) => { - const updatedFilters = setFilter({ - data: { - _custom: { - ...filter._custom, - navidrome: { - ...filter._custom?.navidrome, - has_rating: e.currentTarget.checked ? true : undefined, - }, - }, - }, - itemType: LibraryItem.ALBUM, - key: pageKey, - }) as AlbumListFilter; - handleFilterChange(updatedFilters); - }, - value: filter._custom?.navidrome?.has_rating, - }, - { - label: 'Is favorited', - onChange: (e: ChangeEvent<HTMLInputElement>) => { - const updatedFilters = setFilter({ - data: { - _custom: { - ...filter._custom, - navidrome: { - ...filter._custom?.navidrome, - starred: e.currentTarget.checked ? true : undefined, - }, - }, - }, - itemType: LibraryItem.ALBUM, - key: pageKey, - }) as AlbumListFilter; - handleFilterChange(updatedFilters); - }, - value: filter._custom?.navidrome?.starred, - }, - { - label: 'Is compilation', - onChange: (e: ChangeEvent<HTMLInputElement>) => { - const updatedFilters = setFilter({ - data: { - _custom: { - ...filter._custom, - navidrome: { - ...filter._custom?.navidrome, - compilation: e.currentTarget.checked ? true : undefined, - }, - }, - }, - itemType: LibraryItem.ALBUM, - key: pageKey, - }) as AlbumListFilter; - handleFilterChange(updatedFilters); - }, - value: filter._custom?.navidrome?.compilation, - }, - { - label: 'Is recently played', - onChange: (e: ChangeEvent<HTMLInputElement>) => { - const updatedFilters = setFilter({ - data: { - _custom: { - ...filter._custom, - navidrome: { - ...filter._custom?.navidrome, - recently_played: e.currentTarget.checked ? true : undefined, - }, - }, - }, - itemType: LibraryItem.ALBUM, - key: pageKey, - }) as AlbumListFilter; - handleFilterChange(updatedFilters); - }, - value: filter._custom?.navidrome?.recently_played, - }, - ]; - - const handleYearFilter = debounce((e: number | string) => { - const updatedFilters = setFilter({ - data: { - _custom: { - navidrome: { - ...filter._custom?.navidrome, - year: e === '' ? undefined : (e as number), - }, - ...filter._custom, - }, - }, - itemType: LibraryItem.ALBUM, - key: pageKey, - }) as AlbumListFilter; - handleFilterChange(updatedFilters); - }, 500); - - const [albumArtistSearchTerm, setAlbumArtistSearchTerm] = useState<string>(''); - - const albumArtistListQuery = useAlbumArtistList({ - options: { - cacheTime: 1000 * 60 * 2, - staleTime: 1000 * 60 * 1, - }, - query: { - // searchTerm: debouncedSearchTerm, - sortBy: AlbumArtistListSort.NAME, - sortOrder: SortOrder.ASC, - startIndex: 0, - }, + handleFilterChange, + disableArtistFilter, + pageKey, + id, serverId, - }); +}: NavidromeAlbumFiltersProps) => { + const filter = useAlbumListFilter({ id, key: pageKey }); + const { setFilter } = useListStoreActions(); - const selectableAlbumArtists = useMemo(() => { - if (!albumArtistListQuery?.data?.items) return []; + const genreListQuery = useGenreList({ query: null, serverId }); - return albumArtistListQuery?.data?.items?.map((artist) => ({ - label: artist.name, - value: artist.id, - })); - }, [albumArtistListQuery?.data?.items]); + const genreList = useMemo(() => { + if (!genreListQuery?.data) return []; + return genreListQuery.data.items.map((genre) => ({ + label: genre.name, + value: genre.id, + })); + }, [genreListQuery.data]); - const handleAlbumArtistFilter = (e: string | null) => { - const updatedFilters = setFilter({ - data: { - _custom: { - ...filter._custom, - navidrome: { - ...filter._custom?.navidrome, - artist_id: e || undefined, - }, + const handleGenresFilter = debounce((e: string | null) => { + const updatedFilters = setFilter({ + data: { + _custom: { + ...filter._custom, + navidrome: { + ...filter._custom?.navidrome, + genre_id: e || undefined, + }, + }, + }, + itemType: LibraryItem.ALBUM, + key: 'album', + }) as AlbumListFilter; + handleFilterChange(updatedFilters); + }, 250); + + const toggleFilters = [ + { + label: 'Is rated', + onChange: (e: ChangeEvent<HTMLInputElement>) => { + const updatedFilters = setFilter({ + data: { + _custom: { + ...filter._custom, + navidrome: { + ...filter._custom?.navidrome, + has_rating: e.currentTarget.checked ? true : undefined, + }, + }, + }, + itemType: LibraryItem.ALBUM, + key: pageKey, + }) as AlbumListFilter; + handleFilterChange(updatedFilters); + }, + value: filter._custom?.navidrome?.has_rating, }, - }, - itemType: LibraryItem.ALBUM, - key: pageKey, - }) as AlbumListFilter; - handleFilterChange(updatedFilters); - }; + { + label: 'Is favorited', + onChange: (e: ChangeEvent<HTMLInputElement>) => { + const updatedFilters = setFilter({ + data: { + _custom: { + ...filter._custom, + navidrome: { + ...filter._custom?.navidrome, + starred: e.currentTarget.checked ? true : undefined, + }, + }, + }, + itemType: LibraryItem.ALBUM, + key: pageKey, + }) as AlbumListFilter; + handleFilterChange(updatedFilters); + }, + value: filter._custom?.navidrome?.starred, + }, + { + label: 'Is compilation', + onChange: (e: ChangeEvent<HTMLInputElement>) => { + const updatedFilters = setFilter({ + data: { + _custom: { + ...filter._custom, + navidrome: { + ...filter._custom?.navidrome, + compilation: e.currentTarget.checked ? true : undefined, + }, + }, + }, + itemType: LibraryItem.ALBUM, + key: pageKey, + }) as AlbumListFilter; + handleFilterChange(updatedFilters); + }, + value: filter._custom?.navidrome?.compilation, + }, + { + label: 'Is recently played', + onChange: (e: ChangeEvent<HTMLInputElement>) => { + const updatedFilters = setFilter({ + data: { + _custom: { + ...filter._custom, + navidrome: { + ...filter._custom?.navidrome, + recently_played: e.currentTarget.checked ? true : undefined, + }, + }, + }, + itemType: LibraryItem.ALBUM, + key: pageKey, + }) as AlbumListFilter; + handleFilterChange(updatedFilters); + }, + value: filter._custom?.navidrome?.recently_played, + }, + ]; - return ( - <Stack p="0.8rem"> - {toggleFilters.map((filter) => ( - <Group - key={`nd-filter-${filter.label}`} - position="apart" - > - <Text>{filter.label}</Text> - <Switch - checked={filter?.value || false} - onChange={filter.onChange} - /> - </Group> - ))} - <Divider my="0.5rem" /> - <Group grow> - <NumberInput - defaultValue={filter._custom?.navidrome?.year} - hideControls={false} - label="Year" - max={5000} - min={0} - onChange={(e) => handleYearFilter(e)} - /> - <Select - clearable - searchable - data={genreList} - defaultValue={filter._custom?.navidrome?.genre_id} - label="Genre" - onChange={handleGenresFilter} - /> - </Group> - <Group grow> - <Select - clearable - searchable - data={selectableAlbumArtists} - defaultValue={filter._custom?.navidrome?.artist_id} - disabled={disableArtistFilter} - label="Artist" - limit={300} - placeholder="Type to search for an artist" - rightSection={albumArtistListQuery.isFetching ? <SpinnerIcon /> : undefined} - searchValue={albumArtistSearchTerm} - onChange={handleAlbumArtistFilter} - onSearchChange={setAlbumArtistSearchTerm} - /> - </Group> - </Stack> - ); + const handleYearFilter = debounce((e: number | string) => { + const updatedFilters = setFilter({ + data: { + _custom: { + navidrome: { + ...filter._custom?.navidrome, + year: e === '' ? undefined : (e as number), + }, + ...filter._custom, + }, + }, + itemType: LibraryItem.ALBUM, + key: pageKey, + }) as AlbumListFilter; + handleFilterChange(updatedFilters); + }, 500); + + const [albumArtistSearchTerm, setAlbumArtistSearchTerm] = useState<string>(''); + + const albumArtistListQuery = useAlbumArtistList({ + options: { + cacheTime: 1000 * 60 * 2, + staleTime: 1000 * 60 * 1, + }, + query: { + // searchTerm: debouncedSearchTerm, + sortBy: AlbumArtistListSort.NAME, + sortOrder: SortOrder.ASC, + startIndex: 0, + }, + serverId, + }); + + const selectableAlbumArtists = useMemo(() => { + if (!albumArtistListQuery?.data?.items) return []; + + return albumArtistListQuery?.data?.items?.map((artist) => ({ + label: artist.name, + value: artist.id, + })); + }, [albumArtistListQuery?.data?.items]); + + const handleAlbumArtistFilter = (e: string | null) => { + const updatedFilters = setFilter({ + data: { + _custom: { + ...filter._custom, + navidrome: { + ...filter._custom?.navidrome, + artist_id: e || undefined, + }, + }, + }, + itemType: LibraryItem.ALBUM, + key: pageKey, + }) as AlbumListFilter; + handleFilterChange(updatedFilters); + }; + + return ( + <Stack p="0.8rem"> + {toggleFilters.map((filter) => ( + <Group + key={`nd-filter-${filter.label}`} + position="apart" + > + <Text>{filter.label}</Text> + <Switch + checked={filter?.value || false} + onChange={filter.onChange} + /> + </Group> + ))} + <Divider my="0.5rem" /> + <Group grow> + <NumberInput + defaultValue={filter._custom?.navidrome?.year} + hideControls={false} + label="Year" + max={5000} + min={0} + onChange={(e) => handleYearFilter(e)} + /> + <Select + clearable + searchable + data={genreList} + defaultValue={filter._custom?.navidrome?.genre_id} + label="Genre" + onChange={handleGenresFilter} + /> + </Group> + <Group grow> + <Select + clearable + searchable + data={selectableAlbumArtists} + defaultValue={filter._custom?.navidrome?.artist_id} + disabled={disableArtistFilter} + label="Artist" + limit={300} + placeholder="Type to search for an artist" + rightSection={albumArtistListQuery.isFetching ? <SpinnerIcon /> : undefined} + searchValue={albumArtistSearchTerm} + onChange={handleAlbumArtistFilter} + onSearchChange={setAlbumArtistSearchTerm} + /> + </Group> + </Stack> + ); }; diff --git a/src/renderer/features/albums/context/album-list-context.tsx b/src/renderer/features/albums/context/album-list-context.tsx index 01b83905..8a232c31 100644 --- a/src/renderer/features/albums/context/album-list-context.tsx +++ b/src/renderer/features/albums/context/album-list-context.tsx @@ -2,10 +2,10 @@ import { createContext, useContext } from 'react'; import { ListKey } from '/@/renderer/store'; export const AlbumListContext = createContext<{ id?: string; pageKey: ListKey }>({ - pageKey: 'album', + pageKey: 'album', }); export const useAlbumListContext = () => { - const ctxValue = useContext(AlbumListContext); - return ctxValue; + const ctxValue = useContext(AlbumListContext); + return ctxValue; }; diff --git a/src/renderer/features/albums/queries/album-detail-query.ts b/src/renderer/features/albums/queries/album-detail-query.ts index a9a3bea4..96d7726f 100644 --- a/src/renderer/features/albums/queries/album-detail-query.ts +++ b/src/renderer/features/albums/queries/album-detail-query.ts @@ -6,15 +6,15 @@ import type { AlbumDetailQuery } from '/@/renderer/api/types'; import { controller } from '/@/renderer/api/controller'; export const useAlbumDetail = (args: QueryHookArgs<AlbumDetailQuery>) => { - const { options, query, serverId } = args; - const server = getServerById(serverId); + const { options, query, serverId } = args; + const server = getServerById(serverId); - return useQuery({ - queryFn: ({ signal }) => { - if (!server) throw new Error('Server not found'); - return controller.getAlbumDetail({ apiClientProps: { server, signal }, query }); - }, - queryKey: queryKeys.albums.detail(server?.id || '', query), - ...options, - }); + return useQuery({ + queryFn: ({ signal }) => { + if (!server) throw new Error('Server not found'); + return controller.getAlbumDetail({ apiClientProps: { server, signal }, query }); + }, + queryKey: queryKeys.albums.detail(server?.id || '', query), + ...options, + }); }; diff --git a/src/renderer/features/albums/queries/album-list-query.ts b/src/renderer/features/albums/queries/album-list-query.ts index 77be7722..a4785ab6 100644 --- a/src/renderer/features/albums/queries/album-list-query.ts +++ b/src/renderer/features/albums/queries/album-list-query.ts @@ -7,55 +7,55 @@ import type { QueryHookArgs } from '/@/renderer/lib/react-query'; import { getServerById } from '/@/renderer/store'; export const useAlbumList = (args: QueryHookArgs<AlbumListQuery>) => { - const { options, query, serverId } = args; - const server = getServerById(serverId); + const { options, query, serverId } = args; + const server = getServerById(serverId); - return useQuery({ - enabled: !!serverId, - queryFn: ({ signal }) => { - if (!server) throw new Error('Server not found'); - return controller.getAlbumList({ - apiClientProps: { - server, - signal, + return useQuery({ + enabled: !!serverId, + queryFn: ({ signal }) => { + if (!server) throw new Error('Server not found'); + return controller.getAlbumList({ + apiClientProps: { + server, + signal, + }, + query, + }); }, - query, - }); - }, - queryKey: queryKeys.albums.list(serverId || '', query), - ...options, - }); + queryKey: queryKeys.albums.list(serverId || '', query), + ...options, + }); }; export const useAlbumListInfinite = (args: QueryHookArgs<AlbumListQuery>) => { - const { options, query, serverId } = args; - const server = getServerById(serverId); + const { options, query, serverId } = args; + const server = getServerById(serverId); - return useInfiniteQuery({ - enabled: !!serverId, - getNextPageParam: (lastPage: AlbumListResponse | undefined, pages) => { - if (!lastPage?.items) return undefined; - if (lastPage?.items?.length >= (query?.limit || 50)) { - return pages?.length; - } + return useInfiniteQuery({ + enabled: !!serverId, + getNextPageParam: (lastPage: AlbumListResponse | undefined, pages) => { + if (!lastPage?.items) return undefined; + if (lastPage?.items?.length >= (query?.limit || 50)) { + return pages?.length; + } - return undefined; - }, - queryFn: ({ pageParam = 0, signal }) => { - if (!server) throw new Error('Server not found'); - return api.controller.getAlbumList({ - apiClientProps: { - server, - signal, + return undefined; }, - query: { - ...query, - limit: query.limit || 50, - startIndex: pageParam * (query.limit || 50), + queryFn: ({ pageParam = 0, signal }) => { + if (!server) throw new Error('Server not found'); + return api.controller.getAlbumList({ + apiClientProps: { + server, + signal, + }, + query: { + ...query, + limit: query.limit || 50, + startIndex: pageParam * (query.limit || 50), + }, + }); }, - }); - }, - queryKey: queryKeys.albums.list(server?.id || '', query), - ...options, - }); + queryKey: queryKeys.albums.list(server?.id || '', query), + ...options, + }); }; diff --git a/src/renderer/features/albums/routes/album-detail-route.tsx b/src/renderer/features/albums/routes/album-detail-route.tsx index 2a8805c0..b3d47c80 100644 --- a/src/renderer/features/albums/routes/album-detail-route.tsx +++ b/src/renderer/features/albums/routes/album-detail-route.tsx @@ -13,52 +13,54 @@ import { LibraryItem } from '/@/renderer/api/types'; import { useCurrentServer } from '/@/renderer/store'; const AlbumDetailRoute = () => { - const tableRef = useRef<AgGridReactType | null>(null); - const scrollAreaRef = useRef<HTMLDivElement>(null); - const headerRef = useRef<HTMLDivElement>(null); + const tableRef = useRef<AgGridReactType | null>(null); + const scrollAreaRef = useRef<HTMLDivElement>(null); + const headerRef = useRef<HTMLDivElement>(null); - const { albumId } = useParams() as { albumId: string }; - const server = useCurrentServer(); - const detailQuery = useAlbumDetail({ query: { id: albumId }, serverId: server?.id }); - const background = useFastAverageColor(detailQuery.data?.imageUrl, !detailQuery.isLoading); - const handlePlayQueueAdd = usePlayQueueAdd(); - const playButtonBehavior = usePlayButtonBehavior(); + const { albumId } = useParams() as { albumId: string }; + const server = useCurrentServer(); + const detailQuery = useAlbumDetail({ query: { id: albumId }, serverId: server?.id }); + const background = useFastAverageColor(detailQuery.data?.imageUrl, !detailQuery.isLoading); + const handlePlayQueueAdd = usePlayQueueAdd(); + const playButtonBehavior = usePlayButtonBehavior(); - const handlePlay = () => { - handlePlayQueueAdd?.({ - byItemType: { - id: [albumId], - type: LibraryItem.ALBUM, - }, - playType: playButtonBehavior, - }); - }; + const handlePlay = () => { + handlePlayQueueAdd?.({ + byItemType: { + id: [albumId], + type: LibraryItem.ALBUM, + }, + playType: playButtonBehavior, + }); + }; - if (!background) return null; + if (!background) return null; - return ( - <AnimatedPage key={`album-detail-${albumId}`}> - <NativeScrollArea - ref={scrollAreaRef} - pageHeaderProps={{ - backgroundColor: background, - children: ( - <LibraryHeaderBar> - <LibraryHeaderBar.PlayButton onClick={handlePlay} /> - <LibraryHeaderBar.Title>{detailQuery?.data?.name}</LibraryHeaderBar.Title> - </LibraryHeaderBar> - ), - target: headerRef, - }} - > - <AlbumDetailHeader - ref={headerRef} - background={background} - /> - <AlbumDetailContent tableRef={tableRef} /> - </NativeScrollArea> - </AnimatedPage> - ); + return ( + <AnimatedPage key={`album-detail-${albumId}`}> + <NativeScrollArea + ref={scrollAreaRef} + pageHeaderProps={{ + backgroundColor: background, + children: ( + <LibraryHeaderBar> + <LibraryHeaderBar.PlayButton onClick={handlePlay} /> + <LibraryHeaderBar.Title> + {detailQuery?.data?.name} + </LibraryHeaderBar.Title> + </LibraryHeaderBar> + ), + target: headerRef, + }} + > + <AlbumDetailHeader + ref={headerRef} + background={background} + /> + <AlbumDetailContent tableRef={tableRef} /> + </NativeScrollArea> + </AnimatedPage> + ); }; export default AlbumDetailRoute; diff --git a/src/renderer/features/albums/routes/album-list-route.tsx b/src/renderer/features/albums/routes/album-list-route.tsx index 91c78c65..5d819e4a 100644 --- a/src/renderer/features/albums/routes/album-list-route.tsx +++ b/src/renderer/features/albums/routes/album-list-route.tsx @@ -10,55 +10,55 @@ import { useParams, useSearchParams } from 'react-router-dom'; import { AlbumListContext } from '/@/renderer/features/albums/context/album-list-context'; const AlbumListRoute = () => { - const gridRef = useRef<VirtualInfiniteGridRef | null>(null); - const tableRef = useRef<AgGridReactType | null>(null); - const server = useCurrentServer(); + const gridRef = useRef<VirtualInfiniteGridRef | null>(null); + const tableRef = useRef<AgGridReactType | null>(null); + const server = useCurrentServer(); - const [searchParams] = useSearchParams(); - const { albumArtistId } = useParams(); + const [searchParams] = useSearchParams(); + const { albumArtistId } = useParams(); - const pageKey = generatePageKey( - 'album', - albumArtistId ? `${albumArtistId}_${server?.id}` : undefined, - ); + const pageKey = generatePageKey( + 'album', + albumArtistId ? `${albumArtistId}_${server?.id}` : undefined, + ); - const albumListFilter = useAlbumListFilter({ id: albumArtistId || undefined, key: pageKey }); + const albumListFilter = useAlbumListFilter({ id: albumArtistId || undefined, key: pageKey }); - const itemCountCheck = useAlbumList({ - options: { - cacheTime: 1000 * 60, - staleTime: 1000 * 60, - }, - query: { - limit: 1, - startIndex: 0, - ...albumListFilter, - }, - serverId: server?.id, - }); + const itemCountCheck = useAlbumList({ + options: { + cacheTime: 1000 * 60, + staleTime: 1000 * 60, + }, + query: { + limit: 1, + startIndex: 0, + ...albumListFilter, + }, + serverId: server?.id, + }); - const itemCount = - itemCountCheck.data?.totalRecordCount === null - ? undefined - : itemCountCheck.data?.totalRecordCount; + const itemCount = + itemCountCheck.data?.totalRecordCount === null + ? undefined + : itemCountCheck.data?.totalRecordCount; - return ( - <AnimatedPage> - <AlbumListContext.Provider value={{ id: albumArtistId || undefined, pageKey }}> - <AlbumListHeader - gridRef={gridRef} - itemCount={itemCount} - tableRef={tableRef} - title={searchParams.get('artistName') || undefined} - /> - <AlbumListContent - gridRef={gridRef} - itemCount={itemCount} - tableRef={tableRef} - /> - </AlbumListContext.Provider> - </AnimatedPage> - ); + return ( + <AnimatedPage> + <AlbumListContext.Provider value={{ id: albumArtistId || undefined, pageKey }}> + <AlbumListHeader + gridRef={gridRef} + itemCount={itemCount} + tableRef={tableRef} + title={searchParams.get('artistName') || undefined} + /> + <AlbumListContent + gridRef={gridRef} + itemCount={itemCount} + tableRef={tableRef} + /> + </AlbumListContext.Provider> + </AnimatedPage> + ); }; export default AlbumListRoute; diff --git a/src/renderer/features/artists/components/album-artist-detail-content.tsx b/src/renderer/features/artists/components/album-artist-detail-content.tsx index 5e771bb0..372defeb 100644 --- a/src/renderer/features/artists/components/album-artist-detail-content.tsx +++ b/src/renderer/features/artists/components/album-artist-detail-content.tsx @@ -11,24 +11,24 @@ import { AppRoute } from '/@/renderer/router/routes'; import { useContainerQuery } from '/@/renderer/hooks'; import { usePlayButtonBehavior } from '/@/renderer/store/settings.store'; import { - useHandleGeneralContextMenu, - useHandleTableContextMenu, + useHandleGeneralContextMenu, + useHandleTableContextMenu, } from '/@/renderer/features/context-menu'; import { CardRow, Play, TableColumn } from '/@/renderer/types'; import { - ARTIST_CONTEXT_MENU_ITEMS, - SONG_CONTEXT_MENU_ITEMS, + ARTIST_CONTEXT_MENU_ITEMS, + SONG_CONTEXT_MENU_ITEMS, } from '/@/renderer/features/context-menu/context-menu-items'; import { PlayButton, useCreateFavorite, useDeleteFavorite } from '/@/renderer/features/shared'; import { useAlbumList } from '/@/renderer/features/albums/queries/album-list-query'; import { - Album, - AlbumArtist, - AlbumListSort, - LibraryItem, - QueueSong, - ServerType, - SortOrder, + Album, + AlbumArtist, + AlbumListSort, + LibraryItem, + QueueSong, + ServerType, + SortOrder, } from '/@/renderer/api/types'; import { usePlayQueueAdd } from '/@/renderer/features/player'; import { useAlbumArtistDetail } from '/@/renderer/features/artists/queries/album-artist-detail-query'; @@ -37,441 +37,455 @@ import { getColumnDefs, VirtualTable } from '/@/renderer/components/virtual-tabl import { SwiperGridCarousel } from '/@/renderer/components/grid-carousel'; const ContentContainer = styled.div` - position: relative; - display: flex; - flex-direction: column; - gap: 3rem; - padding: 1rem 2rem 5rem; - overflow: hidden; + position: relative; + display: flex; + flex-direction: column; + gap: 3rem; + padding: 1rem 2rem 5rem; + overflow: hidden; - .ag-theme-alpine-dark { - --ag-header-background-color: rgba(0, 0, 0, 0%) !important; - } + .ag-theme-alpine-dark { + --ag-header-background-color: rgba(0, 0, 0, 0%) !important; + } - .ag-header { - margin-bottom: 0.5rem; - } + .ag-header { + margin-bottom: 0.5rem; + } `; export const AlbumArtistDetailContent = () => { - const { albumArtistId } = useParams() as { albumArtistId: string }; - const cq = useContainerQuery(); - const handlePlayQueueAdd = usePlayQueueAdd(); - const server = useCurrentServer(); + const { albumArtistId } = useParams() as { albumArtistId: string }; + const cq = useContainerQuery(); + const handlePlayQueueAdd = usePlayQueueAdd(); + const server = useCurrentServer(); - const detailQuery = useAlbumArtistDetail({ query: { id: albumArtistId }, serverId: server?.id }); - - const artistDiscographyLink = `${generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL_DISCOGRAPHY, { - albumArtistId, - })}?${createSearchParams({ - artistId: albumArtistId, - artistName: detailQuery?.data?.name || '', - })}`; - - const artistSongsLink = `${generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL_SONGS, { - albumArtistId, - })}?${createSearchParams({ - artistId: albumArtistId, - artistName: detailQuery?.data?.name || '', - })}`; - - const recentAlbumsQuery = useAlbumList({ - query: { - _custom: { - jellyfin: { - ...(server?.type === ServerType.JELLYFIN ? { ArtistIds: albumArtistId } : undefined), - }, - navidrome: { - ...(server?.type === ServerType.NAVIDROME - ? { artist_id: albumArtistId, compilation: false } - : undefined), - }, - }, - // limit: 10, - sortBy: AlbumListSort.RELEASE_DATE, - sortOrder: SortOrder.DESC, - startIndex: 0, - }, - serverId: server?.id, - }); - - const compilationAlbumsQuery = useAlbumList({ - query: { - _custom: { - jellyfin: { - ...(server?.type === ServerType.JELLYFIN - ? { ContributingArtistIds: albumArtistId } - : undefined), - }, - navidrome: { - ...(server?.type === ServerType.NAVIDROME - ? { artist_id: albumArtistId, compilation: true } - : undefined), - }, - }, - // limit: 10, - sortBy: AlbumListSort.RELEASE_DATE, - sortOrder: SortOrder.DESC, - startIndex: 0, - }, - serverId: server?.id, - }); - - const topSongsQuery = useTopSongsList({ - options: { - enabled: !!detailQuery?.data?.name, - }, - query: { - artist: detailQuery?.data?.name || '', - artistId: albumArtistId, - }, - serverId: server?.id, - }); - - const topSongsColumnDefs: ColDef[] = useMemo( - () => - getColumnDefs([ - { column: TableColumn.ROW_INDEX, width: 0 }, - { column: TableColumn.TITLE_COMBINED, width: 0 }, - { column: TableColumn.DURATION, width: 0 }, - { column: TableColumn.ALBUM, width: 0 }, - { column: TableColumn.YEAR, width: 0 }, - { column: TableColumn.PLAY_COUNT, width: 0 }, - { column: TableColumn.USER_FAVORITE, width: 0 }, - ]), - [], - ); - - const cardRows: Record<string, CardRow<Album>[] | CardRow<AlbumArtist>[]> = { - album: [ - { - property: 'name', - route: { - route: AppRoute.LIBRARY_ALBUMS_DETAIL, - slugs: [{ idProperty: 'id', slugProperty: 'albumId' }], - }, - }, - { - arrayProperty: 'name', - property: 'albumArtists', - route: { - route: AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, - slugs: [{ idProperty: 'id', slugProperty: 'albumArtistId' }], - }, - }, - ], - albumArtist: [ - { - property: 'name', - route: { - route: AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, - slugs: [{ idProperty: 'id', slugProperty: 'albumArtistId' }], - }, - }, - ], - }; - - const cardRoutes = { - album: { - route: AppRoute.LIBRARY_ALBUMS_DETAIL, - slugs: [{ idProperty: 'id', slugProperty: 'albumId' }], - }, - albumArtist: { - route: AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, - slugs: [{ idProperty: 'id', slugProperty: 'albumArtistId' }], - }, - }; - - const carousels = [ - { - data: recentAlbumsQuery?.data?.items, - isHidden: !recentAlbumsQuery?.data?.items?.length, - itemType: LibraryItem.ALBUM, - loading: recentAlbumsQuery?.isLoading || recentAlbumsQuery.isFetching, - title: ( - <Group align="flex-end"> - <TextTitle - order={2} - weight={700} - > - Recent releases - </TextTitle> - <Button - compact - uppercase - component={Link} - to={artistDiscographyLink} - variant="subtle" - > - View discography - </Button> - </Group> - ), - uniqueId: 'recentReleases', - }, - { - data: compilationAlbumsQuery?.data?.items, - isHidden: !compilationAlbumsQuery?.data?.items?.length, - itemType: LibraryItem.ALBUM, - loading: compilationAlbumsQuery?.isLoading || compilationAlbumsQuery.isFetching, - title: ( - <TextTitle - order={2} - weight={700} - > - Appears on - </TextTitle> - ), - uniqueId: 'compilationAlbums', - }, - { - data: detailQuery?.data?.similarArtists || [], - isHidden: !detailQuery?.data?.similarArtists, - itemType: LibraryItem.ALBUM_ARTIST, - loading: detailQuery?.isLoading || detailQuery.isFetching, - title: ( - <TextTitle - order={2} - weight={700} - > - Related artists - </TextTitle> - ), - uniqueId: 'similarArtists', - }, - ]; - - const playButtonBehavior = usePlayButtonBehavior(); - - const handlePlay = async (playType?: Play) => { - handlePlayQueueAdd?.({ - byItemType: { - id: [albumArtistId], - type: LibraryItem.ALBUM_ARTIST, - }, - playType: playType || playButtonBehavior, + const detailQuery = useAlbumArtistDetail({ + query: { id: albumArtistId }, + serverId: server?.id, }); - }; - const handleContextMenu = useHandleTableContextMenu(LibraryItem.SONG, SONG_CONTEXT_MENU_ITEMS); + const artistDiscographyLink = `${generatePath( + AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL_DISCOGRAPHY, + { + albumArtistId, + }, + )}?${createSearchParams({ + artistId: albumArtistId, + artistName: detailQuery?.data?.name || '', + })}`; - const handleRowDoubleClick = (e: RowDoubleClickedEvent<QueueSong>) => { - if (!e.data || !topSongsQuery?.data) return; + const artistSongsLink = `${generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL_SONGS, { + albumArtistId, + })}?${createSearchParams({ + artistId: albumArtistId, + artistName: detailQuery?.data?.name || '', + })}`; - handlePlayQueueAdd?.({ - byData: topSongsQuery?.data?.items || [], - initialSongId: e.data.id, - playType: playButtonBehavior, + const recentAlbumsQuery = useAlbumList({ + query: { + _custom: { + jellyfin: { + ...(server?.type === ServerType.JELLYFIN + ? { ArtistIds: albumArtistId } + : undefined), + }, + navidrome: { + ...(server?.type === ServerType.NAVIDROME + ? { artist_id: albumArtistId, compilation: false } + : undefined), + }, + }, + // limit: 10, + sortBy: AlbumListSort.RELEASE_DATE, + sortOrder: SortOrder.DESC, + startIndex: 0, + }, + serverId: server?.id, }); - }; - const createFavoriteMutation = useCreateFavorite({}); - const deleteFavoriteMutation = useDeleteFavorite({}); - - const handleFavorite = () => { - if (!detailQuery?.data) return; - - if (detailQuery.data.userFavorite) { - deleteFavoriteMutation.mutate({ + const compilationAlbumsQuery = useAlbumList({ query: { - id: [detailQuery.data.id], - type: LibraryItem.ALBUM_ARTIST, + _custom: { + jellyfin: { + ...(server?.type === ServerType.JELLYFIN + ? { ContributingArtistIds: albumArtistId } + : undefined), + }, + navidrome: { + ...(server?.type === ServerType.NAVIDROME + ? { artist_id: albumArtistId, compilation: true } + : undefined), + }, + }, + // limit: 10, + sortBy: AlbumListSort.RELEASE_DATE, + sortOrder: SortOrder.DESC, + startIndex: 0, + }, + serverId: server?.id, + }); + + const topSongsQuery = useTopSongsList({ + options: { + enabled: !!detailQuery?.data?.name, }, - serverId: detailQuery.data.serverId, - }); - } else { - createFavoriteMutation.mutate({ query: { - id: [detailQuery.data.id], - type: LibraryItem.ALBUM_ARTIST, + artist: detailQuery?.data?.name || '', + artistId: albumArtistId, }, - serverId: detailQuery.data.serverId, - }); - } - }; + serverId: server?.id, + }); - const handleGeneralContextMenu = useHandleGeneralContextMenu( - LibraryItem.ALBUM_ARTIST, - ARTIST_CONTEXT_MENU_ITEMS, - ); + const topSongsColumnDefs: ColDef[] = useMemo( + () => + getColumnDefs([ + { column: TableColumn.ROW_INDEX, width: 0 }, + { column: TableColumn.TITLE_COMBINED, width: 0 }, + { column: TableColumn.DURATION, width: 0 }, + { column: TableColumn.ALBUM, width: 0 }, + { column: TableColumn.YEAR, width: 0 }, + { column: TableColumn.PLAY_COUNT, width: 0 }, + { column: TableColumn.USER_FAVORITE, width: 0 }, + ]), + [], + ); - const topSongs = topSongsQuery?.data?.items?.slice(0, 10); + const cardRows: Record<string, CardRow<Album>[] | CardRow<AlbumArtist>[]> = { + album: [ + { + property: 'name', + route: { + route: AppRoute.LIBRARY_ALBUMS_DETAIL, + slugs: [{ idProperty: 'id', slugProperty: 'albumId' }], + }, + }, + { + arrayProperty: 'name', + property: 'albumArtists', + route: { + route: AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, + slugs: [{ idProperty: 'id', slugProperty: 'albumArtistId' }], + }, + }, + ], + albumArtist: [ + { + property: 'name', + route: { + route: AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, + slugs: [{ idProperty: 'id', slugProperty: 'albumArtistId' }], + }, + }, + ], + }; - const showBiography = - detailQuery?.data?.biography !== undefined && detailQuery?.data?.biography !== null; - const showTopSongs = topSongsQuery?.data?.items?.length; - const showGenres = detailQuery?.data?.genres ? detailQuery?.data?.genres.length !== 0 : false; + const cardRoutes = { + album: { + route: AppRoute.LIBRARY_ALBUMS_DETAIL, + slugs: [{ idProperty: 'id', slugProperty: 'albumId' }], + }, + albumArtist: { + route: AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, + slugs: [{ idProperty: 'id', slugProperty: 'albumArtistId' }], + }, + }; - const isLoading = - detailQuery?.isLoading || (server?.type === ServerType.NAVIDROME && topSongsQuery?.isLoading); + const carousels = [ + { + data: recentAlbumsQuery?.data?.items, + isHidden: !recentAlbumsQuery?.data?.items?.length, + itemType: LibraryItem.ALBUM, + loading: recentAlbumsQuery?.isLoading || recentAlbumsQuery.isFetching, + title: ( + <Group align="flex-end"> + <TextTitle + order={2} + weight={700} + > + Recent releases + </TextTitle> + <Button + compact + uppercase + component={Link} + to={artistDiscographyLink} + variant="subtle" + > + View discography + </Button> + </Group> + ), + uniqueId: 'recentReleases', + }, + { + data: compilationAlbumsQuery?.data?.items, + isHidden: !compilationAlbumsQuery?.data?.items?.length, + itemType: LibraryItem.ALBUM, + loading: compilationAlbumsQuery?.isLoading || compilationAlbumsQuery.isFetching, + title: ( + <TextTitle + order={2} + weight={700} + > + Appears on + </TextTitle> + ), + uniqueId: 'compilationAlbums', + }, + { + data: detailQuery?.data?.similarArtists || [], + isHidden: !detailQuery?.data?.similarArtists, + itemType: LibraryItem.ALBUM_ARTIST, + loading: detailQuery?.isLoading || detailQuery.isFetching, + title: ( + <TextTitle + order={2} + weight={700} + > + Related artists + </TextTitle> + ), + uniqueId: 'similarArtists', + }, + ]; - if (isLoading) return <ContentContainer ref={cq.ref} />; + const playButtonBehavior = usePlayButtonBehavior(); - return ( - <ContentContainer ref={cq.ref}> - <Box component="section"> - <Group spacing="md"> - <PlayButton onClick={() => handlePlay(playButtonBehavior)} /> - <Group spacing="xs"> - <Button - compact - loading={createFavoriteMutation.isLoading || deleteFavoriteMutation.isLoading} - variant="subtle" - onClick={handleFavorite} - > - {detailQuery?.data?.userFavorite ? ( - <RiHeartFill - color="red" - size={20} - /> - ) : ( - <RiHeartLine size={20} /> - )} - </Button> - <Button - compact - variant="subtle" - onClick={(e) => { - if (!detailQuery?.data) return; - handleGeneralContextMenu(e, [detailQuery.data!]); - }} - > - <RiMoreFill size={20} /> - </Button> - <Button - compact - uppercase - component={Link} - to={artistDiscographyLink} - variant="subtle" - > - View discography - </Button> - <Button - compact - uppercase - component={Link} - to={artistSongsLink} - variant="subtle" - > - View all songs - </Button> - </Group> - </Group> - </Box> - {showGenres ? ( - <Box component="section"> - <Group spacing="sm"> - {detailQuery?.data?.genres?.map((genre) => ( - <Button - key={`genre-${genre.id}`} - compact - component={Link} - radius="md" - size="md" - to={generatePath(`${AppRoute.LIBRARY_ALBUM_ARTISTS}?genre=${genre.id}`, { - albumArtistId, - })} - variant="outline" - > - {genre.name} - </Button> - ))} - </Group> - </Box> - ) : null} - {showBiography ? ( - <Box - component="section" - maw="1280px" - > - <TextTitle - order={2} - weight={700} - > - About {detailQuery?.data?.name} - </TextTitle> - <Text - $secondary - component="p" - dangerouslySetInnerHTML={{ __html: detailQuery?.data?.biography || '' }} - sx={{ textAlign: 'justify' }} - /> - </Box> - ) : null} - {showTopSongs ? ( - <Box component="section"> - <Group - noWrap - position="apart" - > - <Group - noWrap - align="flex-end" - > - <TextTitle - order={2} - weight={700} - > - Top Songs - </TextTitle> - <Button - compact - uppercase - component={Link} - to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL_TOP_SONGS, { - albumArtistId, - })} - variant="subtle" - > - View all - </Button> - </Group> - </Group> - <VirtualTable - autoFitColumns - autoHeight - deselectOnClickOutside - suppressCellFocus - suppressHorizontalScroll - suppressLoadingOverlay - suppressRowDrag - columnDefs={topSongsColumnDefs} - enableCellChangeFlash={false} - getRowId={(data) => data.data.uniqueId} - rowData={topSongs} - rowHeight={60} - rowSelection="multiple" - onCellContextMenu={handleContextMenu} - onRowDoubleClicked={handleRowDoubleClick} - /> - </Box> - ) : null} - <Box component="section"> - <Stack spacing="xl"> - {carousels - .filter((c) => !c.isHidden) - .map((carousel) => ( - <SwiperGridCarousel - key={`carousel-${carousel.uniqueId}`} - cardRows={cardRows[carousel.itemType as keyof typeof cardRows]} - data={carousel.data} - isLoading={carousel.loading} - itemType={carousel.itemType} - route={cardRoutes[carousel.itemType as keyof typeof cardRoutes]} - swiperProps={{ - grid: { - rows: 2, - }, - }} - title={{ - label: carousel.title, - }} - uniqueId={carousel.uniqueId} - /> - ))} - </Stack> - </Box> - </ContentContainer> - ); + const handlePlay = async (playType?: Play) => { + handlePlayQueueAdd?.({ + byItemType: { + id: [albumArtistId], + type: LibraryItem.ALBUM_ARTIST, + }, + playType: playType || playButtonBehavior, + }); + }; + + const handleContextMenu = useHandleTableContextMenu(LibraryItem.SONG, SONG_CONTEXT_MENU_ITEMS); + + const handleRowDoubleClick = (e: RowDoubleClickedEvent<QueueSong>) => { + if (!e.data || !topSongsQuery?.data) return; + + handlePlayQueueAdd?.({ + byData: topSongsQuery?.data?.items || [], + initialSongId: e.data.id, + playType: playButtonBehavior, + }); + }; + + const createFavoriteMutation = useCreateFavorite({}); + const deleteFavoriteMutation = useDeleteFavorite({}); + + const handleFavorite = () => { + if (!detailQuery?.data) return; + + if (detailQuery.data.userFavorite) { + deleteFavoriteMutation.mutate({ + query: { + id: [detailQuery.data.id], + type: LibraryItem.ALBUM_ARTIST, + }, + serverId: detailQuery.data.serverId, + }); + } else { + createFavoriteMutation.mutate({ + query: { + id: [detailQuery.data.id], + type: LibraryItem.ALBUM_ARTIST, + }, + serverId: detailQuery.data.serverId, + }); + } + }; + + const handleGeneralContextMenu = useHandleGeneralContextMenu( + LibraryItem.ALBUM_ARTIST, + ARTIST_CONTEXT_MENU_ITEMS, + ); + + const topSongs = topSongsQuery?.data?.items?.slice(0, 10); + + const showBiography = + detailQuery?.data?.biography !== undefined && detailQuery?.data?.biography !== null; + const showTopSongs = topSongsQuery?.data?.items?.length; + const showGenres = detailQuery?.data?.genres ? detailQuery?.data?.genres.length !== 0 : false; + + const isLoading = + detailQuery?.isLoading || + (server?.type === ServerType.NAVIDROME && topSongsQuery?.isLoading); + + if (isLoading) return <ContentContainer ref={cq.ref} />; + + return ( + <ContentContainer ref={cq.ref}> + <Box component="section"> + <Group spacing="md"> + <PlayButton onClick={() => handlePlay(playButtonBehavior)} /> + <Group spacing="xs"> + <Button + compact + loading={ + createFavoriteMutation.isLoading || deleteFavoriteMutation.isLoading + } + variant="subtle" + onClick={handleFavorite} + > + {detailQuery?.data?.userFavorite ? ( + <RiHeartFill + color="red" + size={20} + /> + ) : ( + <RiHeartLine size={20} /> + )} + </Button> + <Button + compact + variant="subtle" + onClick={(e) => { + if (!detailQuery?.data) return; + handleGeneralContextMenu(e, [detailQuery.data!]); + }} + > + <RiMoreFill size={20} /> + </Button> + <Button + compact + uppercase + component={Link} + to={artistDiscographyLink} + variant="subtle" + > + View discography + </Button> + <Button + compact + uppercase + component={Link} + to={artistSongsLink} + variant="subtle" + > + View all songs + </Button> + </Group> + </Group> + </Box> + {showGenres ? ( + <Box component="section"> + <Group spacing="sm"> + {detailQuery?.data?.genres?.map((genre) => ( + <Button + key={`genre-${genre.id}`} + compact + component={Link} + radius="md" + size="md" + to={generatePath( + `${AppRoute.LIBRARY_ALBUM_ARTISTS}?genre=${genre.id}`, + { + albumArtistId, + }, + )} + variant="outline" + > + {genre.name} + </Button> + ))} + </Group> + </Box> + ) : null} + {showBiography ? ( + <Box + component="section" + maw="1280px" + > + <TextTitle + order={2} + weight={700} + > + About {detailQuery?.data?.name} + </TextTitle> + <Text + $secondary + component="p" + dangerouslySetInnerHTML={{ __html: detailQuery?.data?.biography || '' }} + sx={{ textAlign: 'justify' }} + /> + </Box> + ) : null} + {showTopSongs ? ( + <Box component="section"> + <Group + noWrap + position="apart" + > + <Group + noWrap + align="flex-end" + > + <TextTitle + order={2} + weight={700} + > + Top Songs + </TextTitle> + <Button + compact + uppercase + component={Link} + to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL_TOP_SONGS, { + albumArtistId, + })} + variant="subtle" + > + View all + </Button> + </Group> + </Group> + <VirtualTable + autoFitColumns + autoHeight + deselectOnClickOutside + suppressCellFocus + suppressHorizontalScroll + suppressLoadingOverlay + suppressRowDrag + columnDefs={topSongsColumnDefs} + enableCellChangeFlash={false} + getRowId={(data) => data.data.uniqueId} + rowData={topSongs} + rowHeight={60} + rowSelection="multiple" + onCellContextMenu={handleContextMenu} + onRowDoubleClicked={handleRowDoubleClick} + /> + </Box> + ) : null} + <Box component="section"> + <Stack spacing="xl"> + {carousels + .filter((c) => !c.isHidden) + .map((carousel) => ( + <SwiperGridCarousel + key={`carousel-${carousel.uniqueId}`} + cardRows={cardRows[carousel.itemType as keyof typeof cardRows]} + data={carousel.data} + isLoading={carousel.loading} + itemType={carousel.itemType} + route={cardRoutes[carousel.itemType as keyof typeof cardRoutes]} + swiperProps={{ + grid: { + rows: 2, + }, + }} + title={{ + label: carousel.title, + }} + uniqueId={carousel.uniqueId} + /> + ))} + </Stack> + </Box> + </ContentContainer> + ); }; diff --git a/src/renderer/features/artists/components/album-artist-detail-header.tsx b/src/renderer/features/artists/components/album-artist-detail-header.tsx index 92dddc17..a40b3435 100644 --- a/src/renderer/features/artists/components/album-artist-detail-header.tsx +++ b/src/renderer/features/artists/components/album-artist-detail-header.tsx @@ -11,110 +11,114 @@ import { formatDurationString } from '/@/renderer/utils'; import { useCurrentServer } from '../../../store/auth.store'; interface AlbumArtistDetailHeaderProps { - background: string; + background: string; } export const AlbumArtistDetailHeader = forwardRef( - ({ background }: AlbumArtistDetailHeaderProps, ref: Ref<HTMLDivElement>) => { - const { albumArtistId } = useParams() as { albumArtistId: string }; - const server = useCurrentServer(); - const detailQuery = useAlbumArtistDetail({ - query: { id: albumArtistId }, - serverId: server?.id, - }); - const cq = useContainerQuery(); + ({ background }: AlbumArtistDetailHeaderProps, ref: Ref<HTMLDivElement>) => { + const { albumArtistId } = useParams() as { albumArtistId: string }; + const server = useCurrentServer(); + const detailQuery = useAlbumArtistDetail({ + query: { id: albumArtistId }, + serverId: server?.id, + }); + const cq = useContainerQuery(); - const metadataItems = [ - { - id: 'albumCount', - secondary: false, - value: detailQuery?.data?.albumCount && `${detailQuery?.data?.albumCount} albums`, - }, - { - id: 'songCount', - secondary: false, - value: detailQuery?.data?.songCount && `${detailQuery?.data?.songCount} songs`, - }, - { - id: 'duration', - secondary: true, - value: detailQuery?.data?.duration && formatDurationString(detailQuery.data.duration), - }, - ]; + const metadataItems = [ + { + id: 'albumCount', + secondary: false, + value: detailQuery?.data?.albumCount && `${detailQuery?.data?.albumCount} albums`, + }, + { + id: 'songCount', + secondary: false, + value: detailQuery?.data?.songCount && `${detailQuery?.data?.songCount} songs`, + }, + { + id: 'duration', + secondary: true, + value: + detailQuery?.data?.duration && formatDurationString(detailQuery.data.duration), + }, + ]; - const updateRatingMutation = useSetRating({}); + const updateRatingMutation = useSetRating({}); - const handleUpdateRating = (rating: number) => { - if (!detailQuery?.data) return; + const handleUpdateRating = (rating: number) => { + if (!detailQuery?.data) return; - updateRatingMutation.mutate({ - query: { - item: [detailQuery.data], - rating, - }, - serverId: detailQuery?.data.serverId, - }); - }; + updateRatingMutation.mutate({ + query: { + item: [detailQuery.data], + rating, + }, + serverId: detailQuery?.data.serverId, + }); + }; - const handleClearRating = (_e: MouseEvent<HTMLDivElement>, rating?: number) => { - if (!detailQuery?.data || !detailQuery?.data.userRating) return; + const handleClearRating = (_e: MouseEvent<HTMLDivElement>, rating?: number) => { + if (!detailQuery?.data || !detailQuery?.data.userRating) return; - const isSameRatingAsPrevious = rating === detailQuery.data.userRating; - if (!isSameRatingAsPrevious) return; + const isSameRatingAsPrevious = rating === detailQuery.data.userRating; + if (!isSameRatingAsPrevious) return; - updateRatingMutation.mutate({ - query: { - item: [detailQuery.data], - rating: 0, - }, - serverId: detailQuery.data.serverId, - }); - }; + updateRatingMutation.mutate({ + query: { + item: [detailQuery.data], + rating: 0, + }, + serverId: detailQuery.data.serverId, + }); + }; - const showRating = detailQuery?.data?.serverType === ServerType.NAVIDROME; + const showRating = detailQuery?.data?.serverType === ServerType.NAVIDROME; - return ( - <Stack ref={cq.ref}> - <LibraryHeader - ref={ref} - background={background} - imageUrl={detailQuery?.data?.imageUrl} - item={{ route: AppRoute.LIBRARY_ALBUM_ARTISTS, type: LibraryItem.ALBUM_ARTIST }} - title={detailQuery?.data?.name || ''} - > - <Stack> - <Group> - {metadataItems - .filter((i) => i.value) - .map((item, index) => ( - <Fragment key={`item-${item.id}-${index}`}> - {index > 0 && <Text $noSelect>•</Text>} - <Text $secondary={item.secondary}>{item.value}</Text> - </Fragment> - ))} - {showRating && ( - <> - <Text $noSelect>•</Text> - <Rating - readOnly={detailQuery?.isFetching || updateRatingMutation.isLoading} - value={detailQuery?.data?.userRating || 0} - onChange={handleUpdateRating} - onClick={handleClearRating} - /> - </> - )} - </Group> - <Group - sx={{ - WebkitBoxOrient: 'vertical', - WebkitLineClamp: 2, - display: '-webkit-box', - overflow: 'hidden', - }} - /> - </Stack> - </LibraryHeader> - </Stack> - ); - }, + return ( + <Stack ref={cq.ref}> + <LibraryHeader + ref={ref} + background={background} + imageUrl={detailQuery?.data?.imageUrl} + item={{ route: AppRoute.LIBRARY_ALBUM_ARTISTS, type: LibraryItem.ALBUM_ARTIST }} + title={detailQuery?.data?.name || ''} + > + <Stack> + <Group> + {metadataItems + .filter((i) => i.value) + .map((item, index) => ( + <Fragment key={`item-${item.id}-${index}`}> + {index > 0 && <Text $noSelect>•</Text>} + <Text $secondary={item.secondary}>{item.value}</Text> + </Fragment> + ))} + {showRating && ( + <> + <Text $noSelect>•</Text> + <Rating + readOnly={ + detailQuery?.isFetching || + updateRatingMutation.isLoading + } + value={detailQuery?.data?.userRating || 0} + onChange={handleUpdateRating} + onClick={handleClearRating} + /> + </> + )} + </Group> + <Group + sx={{ + WebkitBoxOrient: 'vertical', + WebkitLineClamp: 2, + display: '-webkit-box', + overflow: 'hidden', + }} + /> + </Stack> + </LibraryHeader> + </Stack> + ); + }, ); diff --git a/src/renderer/features/artists/components/album-artist-detail-top-songs-list-content.tsx b/src/renderer/features/artists/components/album-artist-detail-top-songs-list-content.tsx index ea7d7554..ee063185 100644 --- a/src/renderer/features/artists/components/album-artist-detail-top-songs-list-content.tsx +++ b/src/renderer/features/artists/components/album-artist-detail-top-songs-list-content.tsx @@ -11,72 +11,72 @@ import { VirtualGridAutoSizerContainer } from '/@/renderer/components/virtual-gr import { getColumnDefs, VirtualTable } from '/@/renderer/components/virtual-table'; interface AlbumArtistSongListContentProps { - data: QueueSong[]; - tableRef: MutableRefObject<AgGridReactType | null>; + data: QueueSong[]; + tableRef: MutableRefObject<AgGridReactType | null>; } export const AlbumArtistDetailTopSongsListContent = ({ - tableRef, - data, + tableRef, + data, }: AlbumArtistSongListContentProps) => { - const server = useCurrentServer(); - const page = useSongListStore(); + const server = useCurrentServer(); + const page = useSongListStore(); - const handlePlayQueueAdd = usePlayQueueAdd(); - const playButtonBehavior = usePlayButtonBehavior(); + const handlePlayQueueAdd = usePlayQueueAdd(); + const playButtonBehavior = usePlayButtonBehavior(); - const columnDefs: ColDef[] = useMemo( - () => getColumnDefs(page.table.columns), - [page.table.columns], - ); + const columnDefs: ColDef[] = useMemo( + () => getColumnDefs(page.table.columns), + [page.table.columns], + ); - const handleContextMenu = useHandleTableContextMenu(LibraryItem.SONG, SONG_CONTEXT_MENU_ITEMS); + const handleContextMenu = useHandleTableContextMenu(LibraryItem.SONG, SONG_CONTEXT_MENU_ITEMS); - const handleRowDoubleClick = (e: RowDoubleClickedEvent<QueueSong>) => { - if (!e.data) return; + const handleRowDoubleClick = (e: RowDoubleClickedEvent<QueueSong>) => { + if (!e.data) return; - const rowData: QueueSong[] = []; - e.api.forEachNode((node) => { - if (!node.data) return; - rowData.push(node.data); - }); + const rowData: QueueSong[] = []; + e.api.forEachNode((node) => { + if (!node.data) return; + rowData.push(node.data); + }); - handlePlayQueueAdd?.({ - byData: rowData, - initialSongId: e.data.id, - playType: playButtonBehavior, - }); - }; + handlePlayQueueAdd?.({ + byData: rowData, + initialSongId: e.data.id, + playType: playButtonBehavior, + }); + }; - return ( - <> - <VirtualGridAutoSizerContainer> - <VirtualTable - // https://github.com/ag-grid/ag-grid/issues/5284 - // Key is used to force remount of table when display, rowHeight, or server changes - key={`table-${page.display}-${page.table.rowHeight}-${server?.id}`} - ref={tableRef} - alwaysShowHorizontalScroll - animateRows - maintainColumnOrder - suppressCopyRowsToClipboard - suppressMoveWhenRowDragging - suppressPaginationPanel - suppressRowDrag - suppressScrollOnNewData - autoFitColumns={page.table.autoFit} - columnDefs={columnDefs} - enableCellChangeFlash={false} - getRowId={(data) => data.data.uniqueId} - rowBuffer={20} - rowData={data} - rowHeight={page.table.rowHeight || 40} - rowModelType="clientSide" - rowSelection="multiple" - onCellContextMenu={handleContextMenu} - onRowDoubleClicked={handleRowDoubleClick} - /> - </VirtualGridAutoSizerContainer> - </> - ); + return ( + <> + <VirtualGridAutoSizerContainer> + <VirtualTable + // https://github.com/ag-grid/ag-grid/issues/5284 + // Key is used to force remount of table when display, rowHeight, or server changes + key={`table-${page.display}-${page.table.rowHeight}-${server?.id}`} + ref={tableRef} + alwaysShowHorizontalScroll + animateRows + maintainColumnOrder + suppressCopyRowsToClipboard + suppressMoveWhenRowDragging + suppressPaginationPanel + suppressRowDrag + suppressScrollOnNewData + autoFitColumns={page.table.autoFit} + columnDefs={columnDefs} + enableCellChangeFlash={false} + getRowId={(data) => data.data.uniqueId} + rowBuffer={20} + rowData={data} + rowHeight={page.table.rowHeight || 40} + rowModelType="clientSide" + rowSelection="multiple" + onCellContextMenu={handleContextMenu} + onRowDoubleClicked={handleRowDoubleClick} + /> + </VirtualGridAutoSizerContainer> + </> + ); }; diff --git a/src/renderer/features/artists/components/album-artist-detail-top-songs-list-header.tsx b/src/renderer/features/artists/components/album-artist-detail-top-songs-list-header.tsx index 76d8c9bc..f11c8f0c 100644 --- a/src/renderer/features/artists/components/album-artist-detail-top-songs-list-header.tsx +++ b/src/renderer/features/artists/components/album-artist-detail-top-songs-list-header.tsx @@ -7,71 +7,71 @@ import { usePlayButtonBehavior } from '/@/renderer/store/settings.store'; import { Play } from '/@/renderer/types'; interface AlbumArtistDetailTopSongsListHeaderProps { - data: QueueSong[]; - itemCount?: number; - title: string; + data: QueueSong[]; + itemCount?: number; + title: string; } export const AlbumArtistDetailTopSongsListHeader = ({ - title, - itemCount, - data, + title, + itemCount, + data, }: AlbumArtistDetailTopSongsListHeaderProps) => { - const handlePlayQueueAdd = usePlayQueueAdd(); - const playButtonBehavior = usePlayButtonBehavior(); + const handlePlayQueueAdd = usePlayQueueAdd(); + const playButtonBehavior = usePlayButtonBehavior(); - const handlePlay = async (playType: Play) => { - handlePlayQueueAdd?.({ - byData: data, - playType, - }); - }; + const handlePlay = async (playType: Play) => { + handlePlayQueueAdd?.({ + byData: data, + playType, + }); + }; - return ( - <PageHeader p="1rem"> - <LibraryHeaderBar> - <LibraryHeaderBar.PlayButton onClick={() => handlePlay(playButtonBehavior)} /> - <LibraryHeaderBar.Title>Top songs from {title}</LibraryHeaderBar.Title> - <Paper - fw="600" - px="1rem" - py="0.3rem" - radius="sm" - > - {itemCount === null || itemCount === undefined ? <SpinnerIcon /> : itemCount} - </Paper> - <DropdownMenu position="bottom-start"> - <DropdownMenu.Target> - <Button - compact - fw="600" - variant="subtle" - > - <RiMoreFill size={15} /> - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - <DropdownMenu.Item - icon={<RiPlayFill />} - onClick={() => handlePlay(Play.NOW)} - > - Play - </DropdownMenu.Item> - <DropdownMenu.Item - icon={<RiAddBoxFill />} - onClick={() => handlePlay(Play.LAST)} - > - Add to queue - </DropdownMenu.Item> - <DropdownMenu.Item - icon={<RiAddCircleFill />} - onClick={() => handlePlay(Play.NEXT)} - > - Add to queue next - </DropdownMenu.Item> - </DropdownMenu.Dropdown> - </DropdownMenu> - </LibraryHeaderBar> - </PageHeader> - ); + return ( + <PageHeader p="1rem"> + <LibraryHeaderBar> + <LibraryHeaderBar.PlayButton onClick={() => handlePlay(playButtonBehavior)} /> + <LibraryHeaderBar.Title>Top songs from {title}</LibraryHeaderBar.Title> + <Paper + fw="600" + px="1rem" + py="0.3rem" + radius="sm" + > + {itemCount === null || itemCount === undefined ? <SpinnerIcon /> : itemCount} + </Paper> + <DropdownMenu position="bottom-start"> + <DropdownMenu.Target> + <Button + compact + fw="600" + variant="subtle" + > + <RiMoreFill size={15} /> + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + <DropdownMenu.Item + icon={<RiPlayFill />} + onClick={() => handlePlay(Play.NOW)} + > + Play + </DropdownMenu.Item> + <DropdownMenu.Item + icon={<RiAddBoxFill />} + onClick={() => handlePlay(Play.LAST)} + > + Add to queue + </DropdownMenu.Item> + <DropdownMenu.Item + icon={<RiAddCircleFill />} + onClick={() => handlePlay(Play.NEXT)} + > + Add to queue next + </DropdownMenu.Item> + </DropdownMenu.Dropdown> + </DropdownMenu> + </LibraryHeaderBar> + </PageHeader> + ); }; diff --git a/src/renderer/features/artists/components/album-artist-list-content.tsx b/src/renderer/features/artists/components/album-artist-list-content.tsx index 2ffdc7c1..15c54120 100644 --- a/src/renderer/features/artists/components/album-artist-list-content.tsx +++ b/src/renderer/features/artists/components/album-artist-list-content.tsx @@ -11,12 +11,12 @@ import { useQueryClient } from '@tanstack/react-query'; import { useCurrentServer, useAlbumArtistListStore } from '/@/renderer/store'; import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact'; import { - BodyScrollEvent, - ColDef, - GridReadyEvent, - IDatasource, - PaginationChangedEvent, - RowDoubleClickedEvent, + BodyScrollEvent, + ColDef, + GridReadyEvent, + IDatasource, + PaginationChangedEvent, + RowDoubleClickedEvent, } from '@ag-grid-community/core'; import { AnimatePresence } from 'framer-motion'; import debounce from 'lodash/debounce'; @@ -28,311 +28,316 @@ import { usePlayQueueAdd } from '/@/renderer/features/player'; import { useAlbumArtistListFilter, useListStoreActions } from '../../../store/list.store'; import { useAlbumArtistListContext } from '/@/renderer/features/artists/context/album-artist-list-context'; import { - VirtualInfiniteGridRef, - VirtualGridAutoSizerContainer, - VirtualInfiniteGrid, + VirtualInfiniteGridRef, + VirtualGridAutoSizerContainer, + VirtualInfiniteGrid, } from '/@/renderer/components/virtual-grid'; import { getColumnDefs, VirtualTable, TablePagination } from '/@/renderer/components/virtual-table'; interface AlbumArtistListContentProps { - gridRef: MutableRefObject<VirtualInfiniteGridRef | null>; - tableRef: MutableRefObject<AgGridReactType | null>; + gridRef: MutableRefObject<VirtualInfiniteGridRef | null>; + tableRef: MutableRefObject<AgGridReactType | null>; } export const AlbumArtistListContent = ({ gridRef, tableRef }: AlbumArtistListContentProps) => { - const queryClient = useQueryClient(); - const navigate = useNavigate(); - const server = useCurrentServer(); - const handlePlayQueueAdd = usePlayQueueAdd(); + const queryClient = useQueryClient(); + const navigate = useNavigate(); + const server = useCurrentServer(); + const handlePlayQueueAdd = usePlayQueueAdd(); - const { id, pageKey } = useAlbumArtistListContext(); - const filter = useAlbumArtistListFilter({ id, key: pageKey }); - const { table, grid, display } = useAlbumArtistListStore(); - const { setTable, setTablePagination, setGrid } = useListStoreActions(); + const { id, pageKey } = useAlbumArtistListContext(); + const filter = useAlbumArtistListFilter({ id, key: pageKey }); + const { table, grid, display } = useAlbumArtistListStore(); + const { setTable, setTablePagination, setGrid } = useListStoreActions(); - const isPaginationEnabled = display === ListDisplayType.TABLE_PAGINATED; + const isPaginationEnabled = display === ListDisplayType.TABLE_PAGINATED; - const checkAlbumArtistList = useAlbumArtistList({ - options: { - cacheTime: Infinity, - staleTime: 60 * 1000 * 5, - }, - query: { - limit: 1, - startIndex: 0, - ...filter, - }, - serverId: server?.id, - }); - - const columnDefs: ColDef[] = useMemo(() => getColumnDefs(table.columns), [table.columns]); - - const onTableReady = useCallback( - (params: GridReadyEvent) => { - const dataSource: IDatasource = { - getRows: async (params) => { - const limit = params.endRow - params.startRow; - const startIndex = params.startRow; - - const queryKey = queryKeys.albumArtists.list(server?.id || '', { - limit, - startIndex, + const checkAlbumArtistList = useAlbumArtistList({ + options: { + cacheTime: Infinity, + staleTime: 60 * 1000 * 5, + }, + query: { + limit: 1, + startIndex: 0, ...filter, - }); - - const albumArtistsRes = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.getAlbumArtistList({ - apiClientProps: { - server, - signal, - }, - query: { - limit, - startIndex, - ...filter, - }, - }), - { cacheTime: 1000 * 60 * 1 }, - ); - - params.successCallback( - albumArtistsRes?.items || [], - albumArtistsRes?.totalRecordCount || 0, - ); }, - rowCount: undefined, - }; + serverId: server?.id, + }); - params.api.setDatasource(dataSource); - params.api.ensureIndexVisible(table.scrollOffset || 0, 'top'); - }, - [filter, table.scrollOffset, queryClient, server], - ); + const columnDefs: ColDef[] = useMemo(() => getColumnDefs(table.columns), [table.columns]); - const onTablePaginationChanged = useCallback( - (event: PaginationChangedEvent) => { - if (!isPaginationEnabled || !event.api) return; + const onTableReady = useCallback( + (params: GridReadyEvent) => { + const dataSource: IDatasource = { + getRows: async (params) => { + const limit = params.endRow - params.startRow; + const startIndex = params.startRow; - try { - // Scroll to top of page on pagination change - const currentPageStartIndex = table.pagination.currentPage * table.pagination.itemsPerPage; - event.api?.ensureIndexVisible(currentPageStartIndex, 'top'); - } catch (err) { - console.log(err); - } + const queryKey = queryKeys.albumArtists.list(server?.id || '', { + limit, + startIndex, + ...filter, + }); - setTablePagination({ - data: { - itemsPerPage: event.api.paginationGetPageSize(), - totalItems: event.api.paginationGetRowCount(), - totalPages: event.api.paginationGetTotalPages() + 1, + const albumArtistsRes = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.getAlbumArtistList({ + apiClientProps: { + server, + signal, + }, + query: { + limit, + startIndex, + ...filter, + }, + }), + { cacheTime: 1000 * 60 * 1 }, + ); + + params.successCallback( + albumArtistsRes?.items || [], + albumArtistsRes?.totalRecordCount || 0, + ); + }, + rowCount: undefined, + }; + + params.api.setDatasource(dataSource); + params.api.ensureIndexVisible(table.scrollOffset || 0, 'top'); }, - key: pageKey, - }); - }, - [ - isPaginationEnabled, - pageKey, - setTablePagination, - table.pagination.currentPage, - table.pagination.itemsPerPage, - ], - ); + [filter, table.scrollOffset, queryClient, server], + ); - const handleTableColumnChange = useCallback(() => { - const { columnApi } = tableRef?.current || {}; - const columnsOrder = columnApi?.getAllGridColumns(); + const onTablePaginationChanged = useCallback( + (event: PaginationChangedEvent) => { + if (!isPaginationEnabled || !event.api) return; - if (!columnsOrder) return; + try { + // Scroll to top of page on pagination change + const currentPageStartIndex = + table.pagination.currentPage * table.pagination.itemsPerPage; + event.api?.ensureIndexVisible(currentPageStartIndex, 'top'); + } catch (err) { + console.log(err); + } - const columnsInSettings = table.columns; - const updatedColumns = []; - for (const column of columnsOrder) { - const columnInSettings = columnsInSettings.find((c) => c.column === column.getColDef().colId); + setTablePagination({ + data: { + itemsPerPage: event.api.paginationGetPageSize(), + totalItems: event.api.paginationGetRowCount(), + totalPages: event.api.paginationGetTotalPages() + 1, + }, + key: pageKey, + }); + }, + [ + isPaginationEnabled, + pageKey, + setTablePagination, + table.pagination.currentPage, + table.pagination.itemsPerPage, + ], + ); - if (columnInSettings) { - updatedColumns.push({ - ...columnInSettings, - ...(!table.autoFit && { - width: column.getColDef().width, - }), - }); - } - } + const handleTableColumnChange = useCallback(() => { + const { columnApi } = tableRef?.current || {}; + const columnsOrder = columnApi?.getAllGridColumns(); - setTable({ data: { columns: updatedColumns }, key: pageKey }); - }, [tableRef, table.columns, table.autoFit, setTable, pageKey]); + if (!columnsOrder) return; - const debouncedTableColumnChange = debounce(handleTableColumnChange, 200); + const columnsInSettings = table.columns; + const updatedColumns = []; + for (const column of columnsOrder) { + const columnInSettings = columnsInSettings.find( + (c) => c.column === column.getColDef().colId, + ); - const handleTableScroll = (e: BodyScrollEvent) => { - const scrollOffset = Number((e.top / table.rowHeight).toFixed(0)); - setTable({ data: { scrollOffset }, key: pageKey }); - }; + if (columnInSettings) { + updatedColumns.push({ + ...columnInSettings, + ...(!table.autoFit && { + width: column.getColDef().width, + }), + }); + } + } - const fetch = useCallback( - async ({ skip: startIndex, take: limit }: { skip: number; take: number }) => { - const queryKey = queryKeys.albumArtists.list(server?.id || '', { - limit, - startIndex, - ...filter, - }); + setTable({ data: { columns: updatedColumns }, key: pageKey }); + }, [tableRef, table.columns, table.autoFit, setTable, pageKey]); - const albumArtistsRes = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.getAlbumArtistList({ - apiClientProps: { - server, - signal, - }, - query: { - limit, - startIndex, - ...filter, - }, - }), - { cacheTime: 1000 * 60 * 1 }, - ); + const debouncedTableColumnChange = debounce(handleTableColumnChange, 200); - return albumArtistsRes; - }, - [filter, queryClient, server], - ); + const handleTableScroll = (e: BodyScrollEvent) => { + const scrollOffset = Number((e.top / table.rowHeight).toFixed(0)); + setTable({ data: { scrollOffset }, key: pageKey }); + }; - const handleGridScroll = useCallback( - (e: ListOnScrollProps) => { - setGrid({ data: { scrollOffset: e.scrollOffset }, key: pageKey }); - }, - [pageKey, setGrid], - ); + const fetch = useCallback( + async ({ skip: startIndex, take: limit }: { skip: number; take: number }) => { + const queryKey = queryKeys.albumArtists.list(server?.id || '', { + limit, + startIndex, + ...filter, + }); - const handleGridSizeChange = () => { - if (table.autoFit) { - tableRef?.current?.api.sizeColumnsToFit(); - } - }; + const albumArtistsRes = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.getAlbumArtistList({ + apiClientProps: { + server, + signal, + }, + query: { + limit, + startIndex, + ...filter, + }, + }), + { cacheTime: 1000 * 60 * 1 }, + ); - const cardRows = useMemo(() => { - const rows: CardRow<AlbumArtist>[] = [ALBUMARTIST_CARD_ROWS.name]; + return albumArtistsRes; + }, + [filter, queryClient, server], + ); - switch (filter.sortBy) { - case AlbumArtistListSort.DURATION: - rows.push(ALBUMARTIST_CARD_ROWS.duration); - break; - case AlbumArtistListSort.FAVORITED: - break; - case AlbumArtistListSort.NAME: - break; - case AlbumArtistListSort.ALBUM_COUNT: - rows.push(ALBUMARTIST_CARD_ROWS.albumCount); - break; - case AlbumArtistListSort.PLAY_COUNT: - rows.push(ALBUMARTIST_CARD_ROWS.playCount); - break; - case AlbumArtistListSort.RANDOM: - break; - case AlbumArtistListSort.RATING: - rows.push(ALBUMARTIST_CARD_ROWS.rating); - break; - case AlbumArtistListSort.RECENTLY_ADDED: - break; - case AlbumArtistListSort.SONG_COUNT: - rows.push(ALBUMARTIST_CARD_ROWS.songCount); - break; - case AlbumArtistListSort.RELEASE_DATE: - break; - } + const handleGridScroll = useCallback( + (e: ListOnScrollProps) => { + setGrid({ data: { scrollOffset: e.scrollOffset }, key: pageKey }); + }, + [pageKey, setGrid], + ); - return rows; - }, [filter.sortBy]); + const handleGridSizeChange = () => { + if (table.autoFit) { + tableRef?.current?.api.sizeColumnsToFit(); + } + }; - const handleContextMenu = useHandleTableContextMenu( - LibraryItem.ALBUM_ARTIST, - ALBUM_CONTEXT_MENU_ITEMS, - ); + const cardRows = useMemo(() => { + const rows: CardRow<AlbumArtist>[] = [ALBUMARTIST_CARD_ROWS.name]; - const handleRowDoubleClick = (e: RowDoubleClickedEvent) => { - navigate(generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, { albumArtistId: e.data.id })); - }; + switch (filter.sortBy) { + case AlbumArtistListSort.DURATION: + rows.push(ALBUMARTIST_CARD_ROWS.duration); + break; + case AlbumArtistListSort.FAVORITED: + break; + case AlbumArtistListSort.NAME: + break; + case AlbumArtistListSort.ALBUM_COUNT: + rows.push(ALBUMARTIST_CARD_ROWS.albumCount); + break; + case AlbumArtistListSort.PLAY_COUNT: + rows.push(ALBUMARTIST_CARD_ROWS.playCount); + break; + case AlbumArtistListSort.RANDOM: + break; + case AlbumArtistListSort.RATING: + rows.push(ALBUMARTIST_CARD_ROWS.rating); + break; + case AlbumArtistListSort.RECENTLY_ADDED: + break; + case AlbumArtistListSort.SONG_COUNT: + rows.push(ALBUMARTIST_CARD_ROWS.songCount); + break; + case AlbumArtistListSort.RELEASE_DATE: + break; + } - return ( - <> - <VirtualGridAutoSizerContainer> - {display === ListDisplayType.CARD || display === ListDisplayType.POSTER ? ( - <AutoSizer> - {({ height, width }) => ( - <> - <VirtualInfiniteGrid - ref={gridRef} - cardRows={cardRows} - display={display || ListDisplayType.CARD} - fetchFn={fetch} - handlePlayQueueAdd={handlePlayQueueAdd} - height={height} - initialScrollOffset={grid?.scrollOffset || 0} - itemCount={checkAlbumArtistList?.data?.totalRecordCount || 0} - itemGap={20} - itemSize={grid?.itemsPerRow || 5} - itemType={LibraryItem.ALBUM_ARTIST} - loading={checkAlbumArtistList.isLoading} - minimumBatchSize={40} - route={{ - route: AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, - slugs: [{ idProperty: 'id', slugProperty: 'albumArtistId' }], - }} - width={width} - onScroll={handleGridScroll} - /> - </> + return rows; + }, [filter.sortBy]); + + const handleContextMenu = useHandleTableContextMenu( + LibraryItem.ALBUM_ARTIST, + ALBUM_CONTEXT_MENU_ITEMS, + ); + + const handleRowDoubleClick = (e: RowDoubleClickedEvent) => { + navigate(generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, { albumArtistId: e.data.id })); + }; + + return ( + <> + <VirtualGridAutoSizerContainer> + {display === ListDisplayType.CARD || display === ListDisplayType.POSTER ? ( + <AutoSizer> + {({ height, width }) => ( + <> + <VirtualInfiniteGrid + ref={gridRef} + cardRows={cardRows} + display={display || ListDisplayType.CARD} + fetchFn={fetch} + handlePlayQueueAdd={handlePlayQueueAdd} + height={height} + initialScrollOffset={grid?.scrollOffset || 0} + itemCount={checkAlbumArtistList?.data?.totalRecordCount || 0} + itemGap={20} + itemSize={grid?.itemsPerRow || 5} + itemType={LibraryItem.ALBUM_ARTIST} + loading={checkAlbumArtistList.isLoading} + minimumBatchSize={40} + route={{ + route: AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, + slugs: [ + { idProperty: 'id', slugProperty: 'albumArtistId' }, + ], + }} + width={width} + onScroll={handleGridScroll} + /> + </> + )} + </AutoSizer> + ) : ( + <VirtualTable + // https://github.com/ag-grid/ag-grid/issues/5284 + // Key is used to force remount of table when display, rowHeight, or server changes + key={`table-${display}-${table.rowHeight}-${server?.id}`} + ref={tableRef} + alwaysShowHorizontalScroll + suppressRowDrag + autoFitColumns={table.autoFit} + columnDefs={columnDefs} + getRowId={(data) => data.data.id} + infiniteInitialRowCount={checkAlbumArtistList.data?.totalRecordCount || 1} + pagination={isPaginationEnabled} + paginationAutoPageSize={isPaginationEnabled} + paginationPageSize={table.pagination.itemsPerPage || 100} + rowHeight={table.rowHeight || 40} + rowModelType="infinite" + onBodyScrollEnd={handleTableScroll} + onCellContextMenu={handleContextMenu} + onColumnMoved={handleTableColumnChange} + onColumnResized={debouncedTableColumnChange} + onGridReady={onTableReady} + onGridSizeChanged={handleGridSizeChange} + onPaginationChanged={onTablePaginationChanged} + onRowDoubleClicked={handleRowDoubleClick} + /> + )} + </VirtualGridAutoSizerContainer> + {isPaginationEnabled && ( + <AnimatePresence + presenceAffectsLayout + initial={false} + mode="wait" + > + {display === ListDisplayType.TABLE_PAGINATED && ( + <TablePagination + pageKey={pageKey} + pagination={table.pagination} + setPagination={setTablePagination} + tableRef={tableRef} + /> + )} + </AnimatePresence> )} - </AutoSizer> - ) : ( - <VirtualTable - // https://github.com/ag-grid/ag-grid/issues/5284 - // Key is used to force remount of table when display, rowHeight, or server changes - key={`table-${display}-${table.rowHeight}-${server?.id}`} - ref={tableRef} - alwaysShowHorizontalScroll - suppressRowDrag - autoFitColumns={table.autoFit} - columnDefs={columnDefs} - getRowId={(data) => data.data.id} - infiniteInitialRowCount={checkAlbumArtistList.data?.totalRecordCount || 1} - pagination={isPaginationEnabled} - paginationAutoPageSize={isPaginationEnabled} - paginationPageSize={table.pagination.itemsPerPage || 100} - rowHeight={table.rowHeight || 40} - rowModelType="infinite" - onBodyScrollEnd={handleTableScroll} - onCellContextMenu={handleContextMenu} - onColumnMoved={handleTableColumnChange} - onColumnResized={debouncedTableColumnChange} - onGridReady={onTableReady} - onGridSizeChanged={handleGridSizeChange} - onPaginationChanged={onTablePaginationChanged} - onRowDoubleClicked={handleRowDoubleClick} - /> - )} - </VirtualGridAutoSizerContainer> - {isPaginationEnabled && ( - <AnimatePresence - presenceAffectsLayout - initial={false} - mode="wait" - > - {display === ListDisplayType.TABLE_PAGINATED && ( - <TablePagination - pageKey={pageKey} - pagination={table.pagination} - setPagination={setTablePagination} - tableRef={tableRef} - /> - )} - </AnimatePresence> - )} - </> - ); + </> + ); }; diff --git a/src/renderer/features/artists/components/album-artist-list-header-filters.tsx b/src/renderer/features/artists/components/album-artist-list-header-filters.tsx index 0c84e56a..d994ca5c 100644 --- a/src/renderer/features/artists/components/album-artist-list-header-filters.tsx +++ b/src/renderer/features/artists/components/album-artist-list-header-filters.tsx @@ -5,12 +5,12 @@ import { Group, Stack, Flex } from '@mantine/core'; import { useQueryClient } from '@tanstack/react-query'; import debounce from 'lodash/debounce'; import { - RiSortAsc, - RiSortDesc, - RiFolder2Line, - RiMoreFill, - RiRefreshLine, - RiSettings3Fill, + RiSortAsc, + RiSortDesc, + RiFolder2Line, + RiMoreFill, + RiRefreshLine, + RiSettings3Fill, } from 'react-icons/ri'; import { api } from '/@/renderer/api'; import { queryKeys } from '/@/renderer/api/query-keys'; @@ -19,11 +19,11 @@ import { DropdownMenu, Text, Button, Slider, MultiSelect, Switch } from '/@/rend import { useMusicFolders } from '/@/renderer/features/shared'; import { useContainerQuery } from '/@/renderer/hooks'; import { - useCurrentServer, - useAlbumArtistListStore, - AlbumArtistListFilter, - useListStoreActions, - useAlbumArtistListFilter, + useCurrentServer, + useAlbumArtistListStore, + AlbumArtistListFilter, + useListStoreActions, + useAlbumArtistListFilter, } from '/@/renderer/store'; import { ListDisplayType, TableColumn, ServerType } from '/@/renderer/types'; import { useAlbumArtistListContext } from '../context/album-artist-list-context'; @@ -31,455 +31,468 @@ import { VirtualInfiniteGridRef } from '/@/renderer/components/virtual-grid'; import { ALBUMARTIST_TABLE_COLUMNS } from '/@/renderer/components/virtual-table'; const FILTERS = { - jellyfin: [ - { defaultOrder: SortOrder.ASC, name: 'Album', value: AlbumArtistListSort.ALBUM }, - { defaultOrder: SortOrder.DESC, name: 'Duration', value: AlbumArtistListSort.DURATION }, - { defaultOrder: SortOrder.ASC, name: 'Name', value: AlbumArtistListSort.NAME }, - { defaultOrder: SortOrder.ASC, name: 'Random', value: AlbumArtistListSort.RANDOM }, - { - defaultOrder: SortOrder.DESC, - name: 'Recently Added', - value: AlbumArtistListSort.RECENTLY_ADDED, - }, - // { defaultOrder: SortOrder.DESC, name: 'Release Date', value: AlbumArtistListSort.RELEASE_DATE }, - ], - navidrome: [ - { defaultOrder: SortOrder.DESC, name: 'Album Count', value: AlbumArtistListSort.ALBUM_COUNT }, - { defaultOrder: SortOrder.DESC, name: 'Favorited', value: AlbumArtistListSort.FAVORITED }, - { defaultOrder: SortOrder.DESC, name: 'Most Played', value: AlbumArtistListSort.PLAY_COUNT }, - { defaultOrder: SortOrder.ASC, name: 'Name', value: AlbumArtistListSort.NAME }, - { defaultOrder: SortOrder.DESC, name: 'Rating', value: AlbumArtistListSort.RATING }, - { defaultOrder: SortOrder.DESC, name: 'Song Count', value: AlbumArtistListSort.SONG_COUNT }, - ], + jellyfin: [ + { defaultOrder: SortOrder.ASC, name: 'Album', value: AlbumArtistListSort.ALBUM }, + { defaultOrder: SortOrder.DESC, name: 'Duration', value: AlbumArtistListSort.DURATION }, + { defaultOrder: SortOrder.ASC, name: 'Name', value: AlbumArtistListSort.NAME }, + { defaultOrder: SortOrder.ASC, name: 'Random', value: AlbumArtistListSort.RANDOM }, + { + defaultOrder: SortOrder.DESC, + name: 'Recently Added', + value: AlbumArtistListSort.RECENTLY_ADDED, + }, + // { defaultOrder: SortOrder.DESC, name: 'Release Date', value: AlbumArtistListSort.RELEASE_DATE }, + ], + navidrome: [ + { + defaultOrder: SortOrder.DESC, + name: 'Album Count', + value: AlbumArtistListSort.ALBUM_COUNT, + }, + { defaultOrder: SortOrder.DESC, name: 'Favorited', value: AlbumArtistListSort.FAVORITED }, + { + defaultOrder: SortOrder.DESC, + name: 'Most Played', + value: AlbumArtistListSort.PLAY_COUNT, + }, + { defaultOrder: SortOrder.ASC, name: 'Name', value: AlbumArtistListSort.NAME }, + { defaultOrder: SortOrder.DESC, name: 'Rating', value: AlbumArtistListSort.RATING }, + { defaultOrder: SortOrder.DESC, name: 'Song Count', value: AlbumArtistListSort.SONG_COUNT }, + ], }; const ORDER = [ - { name: 'Ascending', value: SortOrder.ASC }, - { name: 'Descending', value: SortOrder.DESC }, + { name: 'Ascending', value: SortOrder.ASC }, + { name: 'Descending', value: SortOrder.DESC }, ]; interface AlbumArtistListHeaderFiltersProps { - gridRef: MutableRefObject<VirtualInfiniteGridRef | null>; - tableRef: MutableRefObject<AgGridReactType | null>; + gridRef: MutableRefObject<VirtualInfiniteGridRef | null>; + tableRef: MutableRefObject<AgGridReactType | null>; } export const AlbumArtistListHeaderFilters = ({ - gridRef, - tableRef, + gridRef, + tableRef, }: AlbumArtistListHeaderFiltersProps) => { - const queryClient = useQueryClient(); - const server = useCurrentServer(); - const { pageKey } = useAlbumArtistListContext(); - const { display, table, grid } = useAlbumArtistListStore(); - const { setFilter, setTable, setTablePagination, setDisplayType, setGrid } = - useListStoreActions(); - const filter = useAlbumArtistListFilter({ key: pageKey }); - const cq = useContainerQuery(); + const queryClient = useQueryClient(); + const server = useCurrentServer(); + const { pageKey } = useAlbumArtistListContext(); + const { display, table, grid } = useAlbumArtistListStore(); + const { setFilter, setTable, setTablePagination, setDisplayType, setGrid } = + useListStoreActions(); + const filter = useAlbumArtistListFilter({ key: pageKey }); + const cq = useContainerQuery(); - const musicFoldersQuery = useMusicFolders({ query: null, serverId: server?.id }); + const musicFoldersQuery = useMusicFolders({ query: null, serverId: server?.id }); - const sortByLabel = - (server?.type && - FILTERS[server.type as keyof typeof FILTERS].find((f) => f.value === filter.sortBy)?.name) || - 'Unknown'; + const sortByLabel = + (server?.type && + FILTERS[server.type as keyof typeof FILTERS].find((f) => f.value === filter.sortBy) + ?.name) || + 'Unknown'; - const sortOrderLabel = ORDER.find((o) => o.value === filter.sortOrder)?.name || 'Unknown'; + const sortOrderLabel = ORDER.find((o) => o.value === filter.sortOrder)?.name || 'Unknown'; - const handleItemSize = (e: number) => { - if (display === ListDisplayType.TABLE || display === ListDisplayType.TABLE_PAGINATED) { - setTable({ data: { rowHeight: e }, key: pageKey }); - } else { - setGrid({ data: { itemsPerRow: e }, key: pageKey }); - } - }; + const handleItemSize = (e: number) => { + if (display === ListDisplayType.TABLE || display === ListDisplayType.TABLE_PAGINATED) { + setTable({ data: { rowHeight: e }, key: pageKey }); + } else { + setGrid({ data: { itemsPerRow: e }, key: pageKey }); + } + }; - const debouncedHandleItemSize = debounce(handleItemSize, 20); - - const fetch = useCallback( - async (startIndex: number, limit: number, filters: AlbumArtistListFilter) => { - const queryKey = queryKeys.albumArtists.list(server?.id || '', { - limit, - startIndex, - ...filters, - }); - - const albums = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.getAlbumArtistList({ - apiClientProps: { - server, - signal, - }, - query: { - limit, - startIndex, - ...filters, - }, - }), - { cacheTime: 1000 * 60 * 1 }, - ); - - return albums; - }, - [queryClient, server], - ); - - const handleFilterChange = useCallback( - async (filters: AlbumArtistListFilter) => { - if (display === ListDisplayType.TABLE || display === ListDisplayType.TABLE_PAGINATED) { - const dataSource: IDatasource = { - getRows: async (params) => { - const limit = params.endRow - params.startRow; - const startIndex = params.startRow; + const debouncedHandleItemSize = debounce(handleItemSize, 20); + const fetch = useCallback( + async (startIndex: number, limit: number, filters: AlbumArtistListFilter) => { const queryKey = queryKeys.albumArtists.list(server?.id || '', { - limit, - startIndex, - ...filters, + limit, + startIndex, + ...filters, }); - const albumArtistsRes = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.getAlbumArtistList({ - apiClientProps: { - server, - signal, - }, - query: { - limit, - startIndex, - ...filters, - }, - }), - { cacheTime: 1000 * 60 * 1 }, + const albums = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.getAlbumArtistList({ + apiClientProps: { + server, + signal, + }, + query: { + limit, + startIndex, + ...filters, + }, + }), + { cacheTime: 1000 * 60 * 1 }, ); - params.successCallback( - albumArtistsRes?.items || [], - albumArtistsRes?.totalRecordCount || 0, - ); - }, - rowCount: undefined, - }; - tableRef.current?.api.setDatasource(dataSource); - tableRef.current?.api.purgeInfiniteCache(); - tableRef.current?.api.ensureIndexVisible(0, 'top'); + return albums; + }, + [queryClient, server], + ); - if (display === ListDisplayType.TABLE_PAGINATED) { - setTablePagination({ data: { currentPage: 0 }, key: pageKey }); + const handleFilterChange = useCallback( + async (filters: AlbumArtistListFilter) => { + if (display === ListDisplayType.TABLE || display === ListDisplayType.TABLE_PAGINATED) { + const dataSource: IDatasource = { + getRows: async (params) => { + const limit = params.endRow - params.startRow; + const startIndex = params.startRow; + + const queryKey = queryKeys.albumArtists.list(server?.id || '', { + limit, + startIndex, + ...filters, + }); + + const albumArtistsRes = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.getAlbumArtistList({ + apiClientProps: { + server, + signal, + }, + query: { + limit, + startIndex, + ...filters, + }, + }), + { cacheTime: 1000 * 60 * 1 }, + ); + + params.successCallback( + albumArtistsRes?.items || [], + albumArtistsRes?.totalRecordCount || 0, + ); + }, + rowCount: undefined, + }; + tableRef.current?.api.setDatasource(dataSource); + tableRef.current?.api.purgeInfiniteCache(); + tableRef.current?.api.ensureIndexVisible(0, 'top'); + + if (display === ListDisplayType.TABLE_PAGINATED) { + setTablePagination({ data: { currentPage: 0 }, key: pageKey }); + } + } else { + gridRef.current?.scrollTo(0); + gridRef.current?.resetLoadMoreItemsCache(); + + // Refetching within the virtualized grid may be inconsistent due to it refetching + // using an outdated set of filters. To avoid this, we fetch using the updated filters + // and then set the grid's data here. + const data = await fetch(0, 200, filters); + + if (!data?.items) return; + gridRef.current?.setItemData(data.items); + } + }, + [display, tableRef, server, queryClient, setTablePagination, pageKey, gridRef, fetch], + ); + + const handleSetSortBy = useCallback( + (e: MouseEvent<HTMLButtonElement>) => { + if (!e.currentTarget?.value || !server?.type) return; + + const sortOrder = FILTERS[server.type as keyof typeof FILTERS].find( + (f) => f.value === e.currentTarget.value, + )?.defaultOrder; + + const updatedFilters = setFilter({ + data: { + sortBy: e.currentTarget.value as AlbumArtistListSort, + sortOrder: sortOrder || SortOrder.ASC, + }, + itemType: LibraryItem.ALBUM_ARTIST, + key: pageKey, + }) as AlbumArtistListFilter; + + handleFilterChange(updatedFilters); + }, + [handleFilterChange, pageKey, server?.type, setFilter], + ); + + const handleSetMusicFolder = useCallback( + (e: MouseEvent<HTMLButtonElement>) => { + if (!e.currentTarget?.value) return; + + let updatedFilters = null; + if (e.currentTarget.value === String(filter.musicFolderId)) { + updatedFilters = setFilter({ + data: { musicFolderId: undefined }, + itemType: LibraryItem.ALBUM_ARTIST, + key: pageKey, + }) as AlbumArtistListFilter; + } else { + updatedFilters = setFilter({ + data: { musicFolderId: e.currentTarget.value }, + itemType: LibraryItem.ALBUM_ARTIST, + key: pageKey, + }) as AlbumArtistListFilter; + } + + handleFilterChange(updatedFilters); + }, + [filter.musicFolderId, handleFilterChange, setFilter, pageKey], + ); + + const handleToggleSortOrder = useCallback(() => { + const newSortOrder = filter.sortOrder === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC; + const updatedFilters = setFilter({ + data: { sortOrder: newSortOrder }, + itemType: LibraryItem.ALBUM_ARTIST, + key: pageKey, + }) as AlbumArtistListFilter; + handleFilterChange(updatedFilters); + }, [filter.sortOrder, handleFilterChange, pageKey, setFilter]); + + const handleSetViewType = useCallback( + (e: MouseEvent<HTMLButtonElement>) => { + if (!e.currentTarget?.value) return; + + setDisplayType({ data: e.currentTarget.value as ListDisplayType, key: pageKey }); + }, + [pageKey, setDisplayType], + ); + + const handleTableColumns = (values: TableColumn[]) => { + const existingColumns = table.columns; + + if (values.length === 0) { + return setTable({ + data: { + columns: [], + }, + key: pageKey, + }); } - } else { - gridRef.current?.scrollTo(0); - gridRef.current?.resetLoadMoreItemsCache(); - // Refetching within the virtualized grid may be inconsistent due to it refetching - // using an outdated set of filters. To avoid this, we fetch using the updated filters - // and then set the grid's data here. - const data = await fetch(0, 200, filters); + // If adding a column + if (values.length > existingColumns.length) { + const newColumn = { column: values[values.length - 1], width: 100 }; - if (!data?.items) return; - gridRef.current?.setItemData(data.items); - } - }, - [display, tableRef, server, queryClient, setTablePagination, pageKey, gridRef, fetch], - ); + setTable({ data: { columns: [...existingColumns, newColumn] }, key: pageKey }); + } else { + // If removing a column + const removed = existingColumns.filter((column) => !values.includes(column.column)); + const newColumns = existingColumns.filter((column) => !removed.includes(column)); - const handleSetSortBy = useCallback( - (e: MouseEvent<HTMLButtonElement>) => { - if (!e.currentTarget?.value || !server?.type) return; + setTable({ data: { columns: newColumns }, key: pageKey }); + } - const sortOrder = FILTERS[server.type as keyof typeof FILTERS].find( - (f) => f.value === e.currentTarget.value, - )?.defaultOrder; + return tableRef.current?.api.sizeColumnsToFit(); + }; - const updatedFilters = setFilter({ - data: { - sortBy: e.currentTarget.value as AlbumArtistListSort, - sortOrder: sortOrder || SortOrder.ASC, - }, - itemType: LibraryItem.ALBUM_ARTIST, - key: pageKey, - }) as AlbumArtistListFilter; + const handleAutoFitColumns = (e: ChangeEvent<HTMLInputElement>) => { + setTable({ data: { autoFit: e.currentTarget.checked }, key: pageKey }); - handleFilterChange(updatedFilters); - }, - [handleFilterChange, pageKey, server?.type, setFilter], - ); + if (e.currentTarget.checked) { + tableRef.current?.api.sizeColumnsToFit(); + } + }; - const handleSetMusicFolder = useCallback( - (e: MouseEvent<HTMLButtonElement>) => { - if (!e.currentTarget?.value) return; + const handleRefresh = useCallback(() => { + queryClient.invalidateQueries(queryKeys.albumArtists.list(server?.id || '')); + handleFilterChange(filter); + }, [filter, handleFilterChange, queryClient, server?.id]); - let updatedFilters = null; - if (e.currentTarget.value === String(filter.musicFolderId)) { - updatedFilters = setFilter({ - data: { musicFolderId: undefined }, - itemType: LibraryItem.ALBUM_ARTIST, - key: pageKey, - }) as AlbumArtistListFilter; - } else { - updatedFilters = setFilter({ - data: { musicFolderId: e.currentTarget.value }, - itemType: LibraryItem.ALBUM_ARTIST, - key: pageKey, - }) as AlbumArtistListFilter; - } - - handleFilterChange(updatedFilters); - }, - [filter.musicFolderId, handleFilterChange, setFilter, pageKey], - ); - - const handleToggleSortOrder = useCallback(() => { - const newSortOrder = filter.sortOrder === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC; - const updatedFilters = setFilter({ - data: { sortOrder: newSortOrder }, - itemType: LibraryItem.ALBUM_ARTIST, - key: pageKey, - }) as AlbumArtistListFilter; - handleFilterChange(updatedFilters); - }, [filter.sortOrder, handleFilterChange, pageKey, setFilter]); - - const handleSetViewType = useCallback( - (e: MouseEvent<HTMLButtonElement>) => { - if (!e.currentTarget?.value) return; - - setDisplayType({ data: e.currentTarget.value as ListDisplayType, key: pageKey }); - }, - [pageKey, setDisplayType], - ); - - const handleTableColumns = (values: TableColumn[]) => { - const existingColumns = table.columns; - - if (values.length === 0) { - return setTable({ - data: { - columns: [], - }, - key: pageKey, - }); - } - - // If adding a column - if (values.length > existingColumns.length) { - const newColumn = { column: values[values.length - 1], width: 100 }; - - setTable({ data: { columns: [...existingColumns, newColumn] }, key: pageKey }); - } else { - // If removing a column - const removed = existingColumns.filter((column) => !values.includes(column.column)); - const newColumns = existingColumns.filter((column) => !removed.includes(column)); - - setTable({ data: { columns: newColumns }, key: pageKey }); - } - - return tableRef.current?.api.sizeColumnsToFit(); - }; - - const handleAutoFitColumns = (e: ChangeEvent<HTMLInputElement>) => { - setTable({ data: { autoFit: e.currentTarget.checked }, key: pageKey }); - - if (e.currentTarget.checked) { - tableRef.current?.api.sizeColumnsToFit(); - } - }; - - const handleRefresh = useCallback(() => { - queryClient.invalidateQueries(queryKeys.albumArtists.list(server?.id || '')); - handleFilterChange(filter); - }, [filter, handleFilterChange, queryClient, server?.id]); - - return ( - <Flex justify="space-between"> - <Group - ref={cq.ref} - spacing="sm" - w="100%" - > - <DropdownMenu position="bottom-start"> - <DropdownMenu.Target> - <Button - compact - fw="600" - size="md" - variant="subtle" + return ( + <Flex justify="space-between"> + <Group + ref={cq.ref} + spacing="sm" + w="100%" > - {sortByLabel} - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - {FILTERS[server?.type as keyof typeof FILTERS].map((f) => ( - <DropdownMenu.Item - key={`filter-${f.name}`} - $isActive={f.value === filter.sortBy} - value={f.value} - onClick={handleSetSortBy} - > - {f.name} - </DropdownMenu.Item> - ))} - </DropdownMenu.Dropdown> - </DropdownMenu> - <Button - compact - fw="600" - size="md" - variant="subtle" - onClick={handleToggleSortOrder} - > - {cq.isMd ? ( - sortOrderLabel - ) : ( - <> - {filter.sortOrder === SortOrder.ASC ? ( - <RiSortAsc size={15} /> - ) : ( - <RiSortDesc size={15} /> - )} - </> - )} - </Button> - {server?.type === ServerType.JELLYFIN && ( - <DropdownMenu position="bottom-start"> - <DropdownMenu.Target> - <Button - compact - fw="600" - size="md" - variant="subtle" - > - {cq.isMd ? 'Folder' : <RiFolder2Line size={15} />} - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - {musicFoldersQuery.data?.items.map((folder) => ( - <DropdownMenu.Item - key={`musicFolder-${folder.id}`} - $isActive={filter.musicFolderId === folder.id} - value={folder.id} - onClick={handleSetMusicFolder} + <DropdownMenu position="bottom-start"> + <DropdownMenu.Target> + <Button + compact + fw="600" + size="md" + variant="subtle" + > + {sortByLabel} + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + {FILTERS[server?.type as keyof typeof FILTERS].map((f) => ( + <DropdownMenu.Item + key={`filter-${f.name}`} + $isActive={f.value === filter.sortBy} + value={f.value} + onClick={handleSetSortBy} + > + {f.name} + </DropdownMenu.Item> + ))} + </DropdownMenu.Dropdown> + </DropdownMenu> + <Button + compact + fw="600" + size="md" + variant="subtle" + onClick={handleToggleSortOrder} > - {folder.name} - </DropdownMenu.Item> - ))} - </DropdownMenu.Dropdown> - </DropdownMenu> - )} - <DropdownMenu position="bottom-start"> - <DropdownMenu.Target> - <Button - compact - size="md" - variant="subtle" - > - <RiMoreFill size={15} /> - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - <DropdownMenu.Item - icon={<RiRefreshLine />} - onClick={handleRefresh} - > - Refresh - </DropdownMenu.Item> - </DropdownMenu.Dropdown> - </DropdownMenu> - </Group> - <Group> - <DropdownMenu position="bottom-end"> - <DropdownMenu.Target> - <Button - compact - size="md" - variant="subtle" - > - <RiSettings3Fill size="1.3rem" /> - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - <DropdownMenu.Label>Display type</DropdownMenu.Label> - <DropdownMenu.Item - $isActive={display === ListDisplayType.CARD} - value={ListDisplayType.CARD} - onClick={handleSetViewType} - > - Card - </DropdownMenu.Item> - <DropdownMenu.Item - $isActive={display === ListDisplayType.POSTER} - value={ListDisplayType.POSTER} - onClick={handleSetViewType} - > - Poster - </DropdownMenu.Item> - <DropdownMenu.Item - $isActive={display === ListDisplayType.TABLE} - value={ListDisplayType.TABLE} - onClick={handleSetViewType} - > - Table - </DropdownMenu.Item> - <DropdownMenu.Item - $isActive={display === ListDisplayType.TABLE_PAGINATED} - value={ListDisplayType.TABLE_PAGINATED} - onClick={handleSetViewType} - > - Table (paginated) - </DropdownMenu.Item> - <DropdownMenu.Divider /> - <DropdownMenu.Label>Item size</DropdownMenu.Label> - <DropdownMenu.Item closeMenuOnClick={false}> - {display === ListDisplayType.CARD || display === ListDisplayType.POSTER ? ( - <Slider - defaultValue={grid?.itemsPerRow} - label={null} - max={10} - min={2} - onChange={debouncedHandleItemSize} - /> - ) : ( - <Slider - defaultValue={table.rowHeight} - label={null} - max={100} - min={30} - onChange={debouncedHandleItemSize} - /> - )} - </DropdownMenu.Item> - {(display === ListDisplayType.TABLE || display === ListDisplayType.TABLE_PAGINATED) && ( - <> - <DropdownMenu.Label>Table Columns</DropdownMenu.Label> - <DropdownMenu.Item - closeMenuOnClick={false} - component="div" - sx={{ cursor: 'default' }} - > - <Stack> - <MultiSelect - clearable - data={ALBUMARTIST_TABLE_COLUMNS} - defaultValue={table?.columns.map((column) => column.column)} - width={300} - onChange={handleTableColumns} - /> - <Group position="apart"> - <Text>Auto Fit Columns</Text> - <Switch - defaultChecked={table.autoFit} - onChange={handleAutoFitColumns} - /> - </Group> - </Stack> - </DropdownMenu.Item> - </> - )} - </DropdownMenu.Dropdown> - </DropdownMenu> - </Group> - </Flex> - ); + {cq.isMd ? ( + sortOrderLabel + ) : ( + <> + {filter.sortOrder === SortOrder.ASC ? ( + <RiSortAsc size={15} /> + ) : ( + <RiSortDesc size={15} /> + )} + </> + )} + </Button> + {server?.type === ServerType.JELLYFIN && ( + <DropdownMenu position="bottom-start"> + <DropdownMenu.Target> + <Button + compact + fw="600" + size="md" + variant="subtle" + > + {cq.isMd ? 'Folder' : <RiFolder2Line size={15} />} + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + {musicFoldersQuery.data?.items.map((folder) => ( + <DropdownMenu.Item + key={`musicFolder-${folder.id}`} + $isActive={filter.musicFolderId === folder.id} + value={folder.id} + onClick={handleSetMusicFolder} + > + {folder.name} + </DropdownMenu.Item> + ))} + </DropdownMenu.Dropdown> + </DropdownMenu> + )} + <DropdownMenu position="bottom-start"> + <DropdownMenu.Target> + <Button + compact + size="md" + variant="subtle" + > + <RiMoreFill size={15} /> + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + <DropdownMenu.Item + icon={<RiRefreshLine />} + onClick={handleRefresh} + > + Refresh + </DropdownMenu.Item> + </DropdownMenu.Dropdown> + </DropdownMenu> + </Group> + <Group> + <DropdownMenu position="bottom-end"> + <DropdownMenu.Target> + <Button + compact + size="md" + variant="subtle" + > + <RiSettings3Fill size="1.3rem" /> + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + <DropdownMenu.Label>Display type</DropdownMenu.Label> + <DropdownMenu.Item + $isActive={display === ListDisplayType.CARD} + value={ListDisplayType.CARD} + onClick={handleSetViewType} + > + Card + </DropdownMenu.Item> + <DropdownMenu.Item + $isActive={display === ListDisplayType.POSTER} + value={ListDisplayType.POSTER} + onClick={handleSetViewType} + > + Poster + </DropdownMenu.Item> + <DropdownMenu.Item + $isActive={display === ListDisplayType.TABLE} + value={ListDisplayType.TABLE} + onClick={handleSetViewType} + > + Table + </DropdownMenu.Item> + <DropdownMenu.Item + $isActive={display === ListDisplayType.TABLE_PAGINATED} + value={ListDisplayType.TABLE_PAGINATED} + onClick={handleSetViewType} + > + Table (paginated) + </DropdownMenu.Item> + <DropdownMenu.Divider /> + <DropdownMenu.Label>Item size</DropdownMenu.Label> + <DropdownMenu.Item closeMenuOnClick={false}> + {display === ListDisplayType.CARD || + display === ListDisplayType.POSTER ? ( + <Slider + defaultValue={grid?.itemsPerRow} + label={null} + max={10} + min={2} + onChange={debouncedHandleItemSize} + /> + ) : ( + <Slider + defaultValue={table.rowHeight} + label={null} + max={100} + min={30} + onChange={debouncedHandleItemSize} + /> + )} + </DropdownMenu.Item> + {(display === ListDisplayType.TABLE || + display === ListDisplayType.TABLE_PAGINATED) && ( + <> + <DropdownMenu.Label>Table Columns</DropdownMenu.Label> + <DropdownMenu.Item + closeMenuOnClick={false} + component="div" + sx={{ cursor: 'default' }} + > + <Stack> + <MultiSelect + clearable + data={ALBUMARTIST_TABLE_COLUMNS} + defaultValue={table?.columns.map( + (column) => column.column, + )} + width={300} + onChange={handleTableColumns} + /> + <Group position="apart"> + <Text>Auto Fit Columns</Text> + <Switch + defaultChecked={table.autoFit} + onChange={handleAutoFitColumns} + /> + </Group> + </Stack> + </DropdownMenu.Item> + </> + )} + </DropdownMenu.Dropdown> + </DropdownMenu> + </Group> + </Flex> + ); }; diff --git a/src/renderer/features/artists/components/album-artist-list-header.tsx b/src/renderer/features/artists/components/album-artist-list-header.tsx index e979e9bd..916317d4 100644 --- a/src/renderer/features/artists/components/album-artist-list-header.tsx +++ b/src/renderer/features/artists/components/album-artist-list-header.tsx @@ -11,10 +11,10 @@ import { PageHeader, SearchInput } from '/@/renderer/components'; import { LibraryHeaderBar } from '/@/renderer/features/shared'; import { useContainerQuery } from '/@/renderer/hooks'; import { - AlbumArtistListFilter, - useAlbumArtistListStore, - useCurrentServer, - useListStoreActions, + AlbumArtistListFilter, + useAlbumArtistListStore, + useCurrentServer, + useListStoreActions, } from '/@/renderer/store'; import { ListDisplayType } from '/@/renderer/types'; import { AlbumArtistListHeaderFilters } from '/@/renderer/features/artists/components/album-artist-list-header-filters'; @@ -24,156 +24,158 @@ import { VirtualInfiniteGridRef } from '/@/renderer/components/virtual-grid'; import { LibraryItem } from '/@/renderer/api/types'; interface AlbumArtistListHeaderProps { - gridRef: MutableRefObject<VirtualInfiniteGridRef | null>; - itemCount?: number; - tableRef: MutableRefObject<AgGridReactType | null>; + gridRef: MutableRefObject<VirtualInfiniteGridRef | null>; + itemCount?: number; + tableRef: MutableRefObject<AgGridReactType | null>; } export const AlbumArtistListHeader = ({ - itemCount, - gridRef, - tableRef, + itemCount, + gridRef, + tableRef, }: AlbumArtistListHeaderProps) => { - const queryClient = useQueryClient(); - const server = useCurrentServer(); - const { pageKey } = useAlbumArtistListContext(); - const { display, filter } = useAlbumArtistListStore(); - const { setFilter, setTablePagination } = useListStoreActions(); - const cq = useContainerQuery(); - - const fetch = useCallback( - async (startIndex: number, limit: number, filters: AlbumArtistListFilter) => { - const queryKey = queryKeys.albumArtists.list(server?.id || '', { - limit, - startIndex, - ...filters, - }); - - const albums = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.getAlbumArtistList({ - apiClientProps: { - server, - signal, - }, - query: { - limit, - startIndex, - ...filters, - }, - }), - { cacheTime: 1000 * 60 * 1 }, - ); - - return albums; - }, - [queryClient, server], - ); - - const handleFilterChange = useCallback( - async (filters: AlbumArtistListFilter) => { - if (display === ListDisplayType.TABLE || display === ListDisplayType.TABLE_PAGINATED) { - const dataSource: IDatasource = { - getRows: async (params) => { - const limit = params.endRow - params.startRow; - const startIndex = params.startRow; + const queryClient = useQueryClient(); + const server = useCurrentServer(); + const { pageKey } = useAlbumArtistListContext(); + const { display, filter } = useAlbumArtistListStore(); + const { setFilter, setTablePagination } = useListStoreActions(); + const cq = useContainerQuery(); + const fetch = useCallback( + async (startIndex: number, limit: number, filters: AlbumArtistListFilter) => { const queryKey = queryKeys.albumArtists.list(server?.id || '', { - limit, - startIndex, - ...filters, + limit, + startIndex, + ...filters, }); - const albumArtistsRes = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.getAlbumArtistList({ - apiClientProps: { - server, - signal, - }, - query: { - limit, - startIndex, - ...filters, - }, - }), - { cacheTime: 1000 * 60 * 1 }, + const albums = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.getAlbumArtistList({ + apiClientProps: { + server, + signal, + }, + query: { + limit, + startIndex, + ...filters, + }, + }), + { cacheTime: 1000 * 60 * 1 }, ); - params.successCallback( - albumArtistsRes?.items || [], - albumArtistsRes?.totalRecordCount || 0, - ); - }, - rowCount: undefined, - }; - tableRef.current?.api.setDatasource(dataSource); - tableRef.current?.api.purgeInfiniteCache(); - tableRef.current?.api.ensureIndexVisible(0, 'top'); + return albums; + }, + [queryClient, server], + ); - if (display === ListDisplayType.TABLE_PAGINATED) { - setTablePagination({ data: { currentPage: 0 }, key: pageKey }); - } - } else { - gridRef.current?.scrollTo(0); - gridRef.current?.resetLoadMoreItemsCache(); + const handleFilterChange = useCallback( + async (filters: AlbumArtistListFilter) => { + if (display === ListDisplayType.TABLE || display === ListDisplayType.TABLE_PAGINATED) { + const dataSource: IDatasource = { + getRows: async (params) => { + const limit = params.endRow - params.startRow; + const startIndex = params.startRow; - // Refetching within the virtualized grid may be inconsistent due to it refetching - // using an outdated set of filters. To avoid this, we fetch using the updated filters - // and then set the grid's data here. - const data = await fetch(0, 200, filters); + const queryKey = queryKeys.albumArtists.list(server?.id || '', { + limit, + startIndex, + ...filters, + }); - if (!data?.items) return; - gridRef.current?.setItemData(data.items); - } - }, - [display, tableRef, server, queryClient, setTablePagination, pageKey, gridRef, fetch], - ); + const albumArtistsRes = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.getAlbumArtistList({ + apiClientProps: { + server, + signal, + }, + query: { + limit, + startIndex, + ...filters, + }, + }), + { cacheTime: 1000 * 60 * 1 }, + ); - const handleSearch = debounce((e: ChangeEvent<HTMLInputElement>) => { - const previousSearchTerm = filter.searchTerm; - const searchTerm = e.target.value === '' ? undefined : e.target.value; - const updatedFilters = setFilter({ - data: { searchTerm }, - itemType: LibraryItem.ALBUM_ARTIST, - key: pageKey, - }) as AlbumArtistListFilter; - if (previousSearchTerm !== searchTerm) handleFilterChange(updatedFilters); - }, 500); + params.successCallback( + albumArtistsRes?.items || [], + albumArtistsRes?.totalRecordCount || 0, + ); + }, + rowCount: undefined, + }; + tableRef.current?.api.setDatasource(dataSource); + tableRef.current?.api.purgeInfiniteCache(); + tableRef.current?.api.ensureIndexVisible(0, 'top'); - return ( - <Stack - ref={cq.ref} - spacing={0} - > - <PageHeader backgroundColor="var(--titlebar-bg)"> - <Flex - justify="space-between" - w="100%" + if (display === ListDisplayType.TABLE_PAGINATED) { + setTablePagination({ data: { currentPage: 0 }, key: pageKey }); + } + } else { + gridRef.current?.scrollTo(0); + gridRef.current?.resetLoadMoreItemsCache(); + + // Refetching within the virtualized grid may be inconsistent due to it refetching + // using an outdated set of filters. To avoid this, we fetch using the updated filters + // and then set the grid's data here. + const data = await fetch(0, 200, filters); + + if (!data?.items) return; + gridRef.current?.setItemData(data.items); + } + }, + [display, tableRef, server, queryClient, setTablePagination, pageKey, gridRef, fetch], + ); + + const handleSearch = debounce((e: ChangeEvent<HTMLInputElement>) => { + const previousSearchTerm = filter.searchTerm; + const searchTerm = e.target.value === '' ? undefined : e.target.value; + const updatedFilters = setFilter({ + data: { searchTerm }, + itemType: LibraryItem.ALBUM_ARTIST, + key: pageKey, + }) as AlbumArtistListFilter; + if (previousSearchTerm !== searchTerm) handleFilterChange(updatedFilters); + }, 500); + + return ( + <Stack + ref={cq.ref} + spacing={0} > - <LibraryHeaderBar> - <LibraryHeaderBar.Title>Album Artists</LibraryHeaderBar.Title> - <LibraryHeaderBar.Badge isLoading={itemCount === null || itemCount === undefined}> - {itemCount} - </LibraryHeaderBar.Badge> - </LibraryHeaderBar> - <Group> - <SearchInput - defaultValue={filter.searchTerm} - openedWidth={cq.isMd ? 250 : cq.isSm ? 200 : 150} - onChange={handleSearch} - /> - </Group> - </Flex> - </PageHeader> - <FilterBar> - <AlbumArtistListHeaderFilters - gridRef={gridRef} - tableRef={tableRef} - /> - </FilterBar> - </Stack> - ); + <PageHeader backgroundColor="var(--titlebar-bg)"> + <Flex + justify="space-between" + w="100%" + > + <LibraryHeaderBar> + <LibraryHeaderBar.Title>Album Artists</LibraryHeaderBar.Title> + <LibraryHeaderBar.Badge + isLoading={itemCount === null || itemCount === undefined} + > + {itemCount} + </LibraryHeaderBar.Badge> + </LibraryHeaderBar> + <Group> + <SearchInput + defaultValue={filter.searchTerm} + openedWidth={cq.isMd ? 250 : cq.isSm ? 200 : 150} + onChange={handleSearch} + /> + </Group> + </Flex> + </PageHeader> + <FilterBar> + <AlbumArtistListHeaderFilters + gridRef={gridRef} + tableRef={tableRef} + /> + </FilterBar> + </Stack> + ); }; diff --git a/src/renderer/features/artists/context/album-artist-detail-song-list-context.tsx b/src/renderer/features/artists/context/album-artist-detail-song-list-context.tsx index cf246213..a2b21d83 100644 --- a/src/renderer/features/artists/context/album-artist-detail-song-list-context.tsx +++ b/src/renderer/features/artists/context/album-artist-detail-song-list-context.tsx @@ -2,10 +2,10 @@ import { createContext, useContext } from 'react'; import { ListKey } from '/@/renderer/store'; export const AlbumArtistDetailSongListContext = createContext<{ id?: string; pageKey: ListKey }>({ - pageKey: 'albumArtist', + pageKey: 'albumArtist', }); export const useAlbumArtistDetailSongListContext = () => { - const ctxValue = useContext(AlbumArtistDetailSongListContext); - return ctxValue; + const ctxValue = useContext(AlbumArtistDetailSongListContext); + return ctxValue; }; diff --git a/src/renderer/features/artists/context/album-artist-list-context.tsx b/src/renderer/features/artists/context/album-artist-list-context.tsx index ef5be66d..71f406b5 100644 --- a/src/renderer/features/artists/context/album-artist-list-context.tsx +++ b/src/renderer/features/artists/context/album-artist-list-context.tsx @@ -2,10 +2,10 @@ import { createContext, useContext } from 'react'; import { ListKey } from '/@/renderer/store'; export const AlbumArtistListContext = createContext<{ id?: string; pageKey: ListKey }>({ - pageKey: 'albumArtist', + pageKey: 'albumArtist', }); export const useAlbumArtistListContext = () => { - const ctxValue = useContext(AlbumArtistListContext); - return ctxValue; + const ctxValue = useContext(AlbumArtistListContext); + return ctxValue; }; diff --git a/src/renderer/features/artists/queries/album-artist-detail-query.ts b/src/renderer/features/artists/queries/album-artist-detail-query.ts index 8e323745..9c4db894 100644 --- a/src/renderer/features/artists/queries/album-artist-detail-query.ts +++ b/src/renderer/features/artists/queries/album-artist-detail-query.ts @@ -6,16 +6,19 @@ import { api } from '/@/renderer/api'; import { QueryHookArgs } from '../../../lib/react-query'; export const useAlbumArtistDetail = (args: QueryHookArgs<AlbumArtistDetailQuery>) => { - const { options, query, serverId } = args || {}; - const server = getServerById(serverId); + const { options, query, serverId } = args || {}; + const server = getServerById(serverId); - return useQuery({ - enabled: !!server?.id && !!query.id, - queryFn: ({ signal }) => { - if (!server) throw new Error('Server not found'); - return api.controller.getAlbumArtistDetail({ apiClientProps: { server, signal }, query }); - }, - queryKey: queryKeys.albumArtists.detail(server?.id || '', query), - ...options, - }); + return useQuery({ + enabled: !!server?.id && !!query.id, + queryFn: ({ signal }) => { + if (!server) throw new Error('Server not found'); + return api.controller.getAlbumArtistDetail({ + apiClientProps: { server, signal }, + query, + }); + }, + queryKey: queryKeys.albumArtists.detail(server?.id || '', query), + ...options, + }); }; diff --git a/src/renderer/features/artists/queries/album-artist-list-query.ts b/src/renderer/features/artists/queries/album-artist-list-query.ts index 37f0a8cb..b03aca53 100644 --- a/src/renderer/features/artists/queries/album-artist-list-query.ts +++ b/src/renderer/features/artists/queries/album-artist-list-query.ts @@ -6,16 +6,16 @@ import { api } from '/@/renderer/api'; import { QueryHookArgs } from '../../../lib/react-query'; export const useAlbumArtistList = (args: QueryHookArgs<AlbumArtistListQuery>) => { - const { options, query, serverId } = args || {}; - const server = getServerById(serverId); + const { options, query, serverId } = args || {}; + const server = getServerById(serverId); - return useQuery({ - enabled: !!server?.id, - queryFn: ({ signal }) => { - if (!server) throw new Error('Server not found'); - return api.controller.getAlbumArtistList({ apiClientProps: { server, signal }, query }); - }, - queryKey: queryKeys.albumArtists.list(server?.id || '', query), - ...options, - }); + return useQuery({ + enabled: !!server?.id, + queryFn: ({ signal }) => { + if (!server) throw new Error('Server not found'); + return api.controller.getAlbumArtistList({ apiClientProps: { server, signal }, query }); + }, + queryKey: queryKeys.albumArtists.list(server?.id || '', query), + ...options, + }); }; diff --git a/src/renderer/features/artists/queries/artist-info-query.ts b/src/renderer/features/artists/queries/artist-info-query.ts index f61301ae..a863cadc 100644 --- a/src/renderer/features/artists/queries/artist-info-query.ts +++ b/src/renderer/features/artists/queries/artist-info-query.ts @@ -6,16 +6,19 @@ import { api } from '/@/renderer/api'; import { QueryHookArgs } from '../../../lib/react-query'; export const useAlbumArtistInfo = (args: QueryHookArgs<AlbumArtistDetailQuery>) => { - const { options, query, serverId } = args || {}; - const server = getServerById(serverId); + const { options, query, serverId } = args || {}; + const server = getServerById(serverId); - return useQuery({ - enabled: !!server?.id && !!query.id, - queryFn: ({ signal }) => { - if (!server) throw new Error('Server not found'); - return api.controller.getAlbumArtistDetail({ apiClientProps: { server, signal }, query }); - }, - queryKey: queryKeys.albumArtists.detail(server?.id || '', query), - ...options, - }); + return useQuery({ + enabled: !!server?.id && !!query.id, + queryFn: ({ signal }) => { + if (!server) throw new Error('Server not found'); + return api.controller.getAlbumArtistDetail({ + apiClientProps: { server, signal }, + query, + }); + }, + queryKey: queryKeys.albumArtists.detail(server?.id || '', query), + ...options, + }); }; diff --git a/src/renderer/features/artists/queries/top-songs-list-query.ts b/src/renderer/features/artists/queries/top-songs-list-query.ts index 7524b4f2..adfe44f4 100644 --- a/src/renderer/features/artists/queries/top-songs-list-query.ts +++ b/src/renderer/features/artists/queries/top-songs-list-query.ts @@ -6,16 +6,16 @@ import { getServerById } from '/@/renderer/store'; import { api } from '/@/renderer/api'; export const useTopSongsList = (args: QueryHookArgs<TopSongListQuery>) => { - const { options, query, serverId } = args || {}; - const server = getServerById(serverId); + const { options, query, serverId } = args || {}; + const server = getServerById(serverId); - return useQuery({ - enabled: !!server?.id, - queryFn: ({ signal }) => { - if (!server) throw new Error('Server not found'); - return api.controller.getTopSongList({ apiClientProps: { server, signal }, query }); - }, - queryKey: queryKeys.albumArtists.topSongs(server?.id || '', query), - ...options, - }); + return useQuery({ + enabled: !!server?.id, + queryFn: ({ signal }) => { + if (!server) throw new Error('Server not found'); + return api.controller.getTopSongList({ apiClientProps: { server, signal }, query }); + }, + queryKey: queryKeys.albumArtists.topSongs(server?.id || '', query), + ...options, + }); }; diff --git a/src/renderer/features/artists/routes/album-artist-detail-route.tsx b/src/renderer/features/artists/routes/album-artist-detail-route.tsx index 9ae0de24..1b369ce7 100644 --- a/src/renderer/features/artists/routes/album-artist-detail-route.tsx +++ b/src/renderer/features/artists/routes/album-artist-detail-route.tsx @@ -12,51 +12,56 @@ import { AlbumArtistDetailContent } from '/@/renderer/features/artists/component import { useCurrentServer } from '/@/renderer/store'; const AlbumArtistDetailRoute = () => { - const scrollAreaRef = useRef<HTMLDivElement>(null); - const headerRef = useRef<HTMLDivElement>(null); - const server = useCurrentServer(); + const scrollAreaRef = useRef<HTMLDivElement>(null); + const headerRef = useRef<HTMLDivElement>(null); + const server = useCurrentServer(); - const { albumArtistId } = useParams() as { albumArtistId: string }; - const handlePlayQueueAdd = usePlayQueueAdd(); - const playButtonBehavior = usePlayButtonBehavior(); - const detailQuery = useAlbumArtistDetail({ query: { id: albumArtistId }, serverId: server?.id }); - const background = useFastAverageColor(detailQuery.data?.imageUrl, !detailQuery.isLoading); - - const handlePlay = () => { - handlePlayQueueAdd?.({ - byItemType: { - id: [albumArtistId], - type: LibraryItem.ALBUM_ARTIST, - }, - playType: playButtonBehavior, + const { albumArtistId } = useParams() as { albumArtistId: string }; + const handlePlayQueueAdd = usePlayQueueAdd(); + const playButtonBehavior = usePlayButtonBehavior(); + const detailQuery = useAlbumArtistDetail({ + query: { id: albumArtistId }, + serverId: server?.id, }); - }; + const background = useFastAverageColor(detailQuery.data?.imageUrl, !detailQuery.isLoading); - if (detailQuery.isLoading || !background) return null; + const handlePlay = () => { + handlePlayQueueAdd?.({ + byItemType: { + id: [albumArtistId], + type: LibraryItem.ALBUM_ARTIST, + }, + playType: playButtonBehavior, + }); + }; - return ( - <AnimatedPage key={`album-artist-detail-${albumArtistId}`}> - <NativeScrollArea - ref={scrollAreaRef} - pageHeaderProps={{ - backgroundColor: background, - children: ( - <LibraryHeaderBar> - <LibraryHeaderBar.PlayButton onClick={handlePlay} /> - <LibraryHeaderBar.Title>{detailQuery?.data?.name}</LibraryHeaderBar.Title> - </LibraryHeaderBar> - ), - target: headerRef, - }} - > - <AlbumArtistDetailHeader - ref={headerRef} - background={background} - /> - <AlbumArtistDetailContent /> - </NativeScrollArea> - </AnimatedPage> - ); + if (detailQuery.isLoading || !background) return null; + + return ( + <AnimatedPage key={`album-artist-detail-${albumArtistId}`}> + <NativeScrollArea + ref={scrollAreaRef} + pageHeaderProps={{ + backgroundColor: background, + children: ( + <LibraryHeaderBar> + <LibraryHeaderBar.PlayButton onClick={handlePlay} /> + <LibraryHeaderBar.Title> + {detailQuery?.data?.name} + </LibraryHeaderBar.Title> + </LibraryHeaderBar> + ), + target: headerRef, + }} + > + <AlbumArtistDetailHeader + ref={headerRef} + background={background} + /> + <AlbumArtistDetailContent /> + </NativeScrollArea> + </AnimatedPage> + ); }; export default AlbumArtistDetailRoute; diff --git a/src/renderer/features/artists/routes/album-artist-detail-top-songs-list-route.tsx b/src/renderer/features/artists/routes/album-artist-detail-top-songs-list-route.tsx index e6835c1a..7d33f0e2 100644 --- a/src/renderer/features/artists/routes/album-artist-detail-top-songs-list-route.tsx +++ b/src/renderer/features/artists/routes/album-artist-detail-top-songs-list-route.tsx @@ -9,35 +9,38 @@ import { AnimatedPage } from '/@/renderer/features/shared'; import { useCurrentServer } from '../../../store/auth.store'; const AlbumArtistDetailTopSongsListRoute = () => { - const tableRef = useRef<AgGridReactType | null>(null); - const { albumArtistId } = useParams() as { albumArtistId: string }; - const server = useCurrentServer(); + const tableRef = useRef<AgGridReactType | null>(null); + const { albumArtistId } = useParams() as { albumArtistId: string }; + const server = useCurrentServer(); - const detailQuery = useAlbumArtistDetail({ query: { id: albumArtistId }, serverId: server?.id }); + const detailQuery = useAlbumArtistDetail({ + query: { id: albumArtistId }, + serverId: server?.id, + }); - const topSongsQuery = useTopSongsList({ - options: { enabled: !!detailQuery?.data?.name }, - query: { artist: detailQuery?.data?.name || '', artistId: albumArtistId }, - serverId: server?.id, - }); + const topSongsQuery = useTopSongsList({ + options: { enabled: !!detailQuery?.data?.name }, + query: { artist: detailQuery?.data?.name || '', artistId: albumArtistId }, + serverId: server?.id, + }); - const itemCount = topSongsQuery?.data?.items?.length || 0; + const itemCount = topSongsQuery?.data?.items?.length || 0; - if (detailQuery.isLoading || topSongsQuery?.isLoading) return null; + if (detailQuery.isLoading || topSongsQuery?.isLoading) return null; - return ( - <AnimatedPage> - <AlbumArtistDetailTopSongsListHeader - data={topSongsQuery?.data?.items || []} - itemCount={itemCount} - title={detailQuery?.data?.name || 'Unknown'} - /> - <AlbumArtistDetailTopSongsListContent - data={topSongsQuery?.data?.items || []} - tableRef={tableRef} - /> - </AnimatedPage> - ); + return ( + <AnimatedPage> + <AlbumArtistDetailTopSongsListHeader + data={topSongsQuery?.data?.items || []} + itemCount={itemCount} + title={detailQuery?.data?.name || 'Unknown'} + /> + <AlbumArtistDetailTopSongsListContent + data={topSongsQuery?.data?.items || []} + tableRef={tableRef} + /> + </AnimatedPage> + ); }; export default AlbumArtistDetailTopSongsListRoute; diff --git a/src/renderer/features/artists/routes/album-artist-list-route.tsx b/src/renderer/features/artists/routes/album-artist-list-route.tsx index 37bc6a59..39bf7836 100644 --- a/src/renderer/features/artists/routes/album-artist-list-route.tsx +++ b/src/renderer/features/artists/routes/album-artist-list-route.tsx @@ -10,46 +10,46 @@ import { useCurrentServer } from '../../../store/auth.store'; import { VirtualInfiniteGridRef } from '/@/renderer/components/virtual-grid'; const AlbumArtistListRoute = () => { - const gridRef = useRef<VirtualInfiniteGridRef | null>(null); - const tableRef = useRef<AgGridReactType | null>(null); - const pageKey = generatePageKey('albumArtist', undefined); - const server = useCurrentServer(); + const gridRef = useRef<VirtualInfiniteGridRef | null>(null); + const tableRef = useRef<AgGridReactType | null>(null); + const pageKey = generatePageKey('albumArtist', undefined); + const server = useCurrentServer(); - const albumArtistListFilter = useAlbumArtistListFilter({ id: undefined, key: pageKey }); + const albumArtistListFilter = useAlbumArtistListFilter({ id: undefined, key: pageKey }); - const itemCountCheck = useAlbumArtistList({ - options: { - cacheTime: 1000 * 60, - staleTime: 1000 * 60, - }, - query: { - limit: 1, - startIndex: 0, - ...albumArtistListFilter, - }, - serverId: server?.id, - }); + const itemCountCheck = useAlbumArtistList({ + options: { + cacheTime: 1000 * 60, + staleTime: 1000 * 60, + }, + query: { + limit: 1, + startIndex: 0, + ...albumArtistListFilter, + }, + serverId: server?.id, + }); - const itemCount = - itemCountCheck.data?.totalRecordCount === null - ? undefined - : itemCountCheck.data?.totalRecordCount; + const itemCount = + itemCountCheck.data?.totalRecordCount === null + ? undefined + : itemCountCheck.data?.totalRecordCount; - return ( - <AnimatedPage> - <AlbumArtistListContext.Provider value={{ id: undefined, pageKey }}> - <AlbumArtistListHeader - gridRef={gridRef} - itemCount={itemCount} - tableRef={tableRef} - /> - <AlbumArtistListContent - gridRef={gridRef} - tableRef={tableRef} - /> - </AlbumArtistListContext.Provider> - </AnimatedPage> - ); + return ( + <AnimatedPage> + <AlbumArtistListContext.Provider value={{ id: undefined, pageKey }}> + <AlbumArtistListHeader + gridRef={gridRef} + itemCount={itemCount} + tableRef={tableRef} + /> + <AlbumArtistListContent + gridRef={gridRef} + tableRef={tableRef} + /> + </AlbumArtistListContext.Provider> + </AnimatedPage> + ); }; export default AlbumArtistListRoute; diff --git a/src/renderer/features/context-menu/context-menu-items.tsx b/src/renderer/features/context-menu/context-menu-items.tsx index 69b4191f..b4927b39 100644 --- a/src/renderer/features/context-menu/context-menu-items.tsx +++ b/src/renderer/features/context-menu/context-menu-items.tsx @@ -1,70 +1,70 @@ import { SetContextMenuItems } from '/@/renderer/features/context-menu/events'; export const QUEUE_CONTEXT_MENU_ITEMS: SetContextMenuItems = [ - { divider: true, id: 'removeFromQueue' }, - { id: 'moveToBottomOfQueue' }, - { divider: true, id: 'moveToTopOfQueue' }, - { divider: true, id: 'addToPlaylist' }, - { id: 'addToFavorites' }, - { divider: true, id: 'removeFromFavorites' }, - { children: true, disabled: false, id: 'setRating' }, - { disabled: false, id: 'deselectAll' }, + { divider: true, id: 'removeFromQueue' }, + { id: 'moveToBottomOfQueue' }, + { divider: true, id: 'moveToTopOfQueue' }, + { divider: true, id: 'addToPlaylist' }, + { id: 'addToFavorites' }, + { divider: true, id: 'removeFromFavorites' }, + { children: true, disabled: false, id: 'setRating' }, + { disabled: false, id: 'deselectAll' }, ]; export const SONG_CONTEXT_MENU_ITEMS: SetContextMenuItems = [ - { id: 'play' }, - { id: 'playLast' }, - { divider: true, id: 'playNext' }, - { divider: true, id: 'addToPlaylist' }, - { id: 'addToFavorites' }, - { divider: true, id: 'removeFromFavorites' }, - { children: true, disabled: false, id: 'setRating' }, + { id: 'play' }, + { id: 'playLast' }, + { divider: true, id: 'playNext' }, + { divider: true, id: 'addToPlaylist' }, + { id: 'addToFavorites' }, + { divider: true, id: 'removeFromFavorites' }, + { children: true, disabled: false, id: 'setRating' }, ]; export const PLAYLIST_SONG_CONTEXT_MENU_ITEMS: SetContextMenuItems = [ - { id: 'play' }, - { id: 'playLast' }, - { divider: true, id: 'playNext' }, - { id: 'addToPlaylist' }, - { divider: true, id: 'removeFromPlaylist' }, - { id: 'addToFavorites' }, - { divider: true, id: 'removeFromFavorites' }, - { children: true, disabled: false, id: 'setRating' }, + { id: 'play' }, + { id: 'playLast' }, + { divider: true, id: 'playNext' }, + { id: 'addToPlaylist' }, + { divider: true, id: 'removeFromPlaylist' }, + { id: 'addToFavorites' }, + { divider: true, id: 'removeFromFavorites' }, + { children: true, disabled: false, id: 'setRating' }, ]; export const SMART_PLAYLIST_SONG_CONTEXT_MENU_ITEMS: SetContextMenuItems = [ - { id: 'play' }, - { id: 'playLast' }, - { divider: true, id: 'playNext' }, - { divider: true, id: 'addToPlaylist' }, - { id: 'addToFavorites' }, - { divider: true, id: 'removeFromFavorites' }, - { children: true, disabled: false, id: 'setRating' }, + { id: 'play' }, + { id: 'playLast' }, + { divider: true, id: 'playNext' }, + { divider: true, id: 'addToPlaylist' }, + { id: 'addToFavorites' }, + { divider: true, id: 'removeFromFavorites' }, + { children: true, disabled: false, id: 'setRating' }, ]; export const ALBUM_CONTEXT_MENU_ITEMS: SetContextMenuItems = [ - { id: 'play' }, - { id: 'playLast' }, - { divider: true, id: 'playNext' }, - { divider: true, id: 'addToPlaylist' }, - { id: 'addToFavorites' }, - { id: 'removeFromFavorites' }, - { children: true, disabled: false, id: 'setRating' }, + { id: 'play' }, + { id: 'playLast' }, + { divider: true, id: 'playNext' }, + { divider: true, id: 'addToPlaylist' }, + { id: 'addToFavorites' }, + { id: 'removeFromFavorites' }, + { children: true, disabled: false, id: 'setRating' }, ]; export const ARTIST_CONTEXT_MENU_ITEMS: SetContextMenuItems = [ - { id: 'play' }, - { id: 'playLast' }, - { divider: true, id: 'playNext' }, - { divider: true, id: 'addToPlaylist' }, - { id: 'addToFavorites' }, - { divider: true, id: 'removeFromFavorites' }, - { children: true, disabled: false, id: 'setRating' }, + { id: 'play' }, + { id: 'playLast' }, + { divider: true, id: 'playNext' }, + { divider: true, id: 'addToPlaylist' }, + { id: 'addToFavorites' }, + { divider: true, id: 'removeFromFavorites' }, + { children: true, disabled: false, id: 'setRating' }, ]; export const PLAYLIST_CONTEXT_MENU_ITEMS: SetContextMenuItems = [ - { id: 'play' }, - { id: 'playLast' }, - { divider: true, id: 'playNext' }, - { id: 'deletePlaylist' }, + { id: 'play' }, + { id: 'playLast' }, + { divider: true, id: 'playNext' }, + { id: 'deletePlaylist' }, ]; diff --git a/src/renderer/features/context-menu/context-menu-provider.tsx b/src/renderer/features/context-menu/context-menu-provider.tsx index d010054a..2806d7d6 100644 --- a/src/renderer/features/context-menu/context-menu-provider.tsx +++ b/src/renderer/features/context-menu/context-menu-provider.tsx @@ -2,77 +2,77 @@ import { createContext, Fragment, ReactNode, useState, useMemo, useCallback } fr import { RowNode } from '@ag-grid-community/core'; import { Divider, Group, Portal, Stack } from '@mantine/core'; import { - useClickOutside, - useMergedRef, - useResizeObserver, - useSetState, - useViewportSize, + useClickOutside, + useMergedRef, + useResizeObserver, + useSetState, + useViewportSize, } from '@mantine/hooks'; import { closeAllModals, openContextModal, openModal } from '@mantine/modals'; import { AnimatePresence } from 'framer-motion'; import isElectron from 'is-electron'; import { - RiAddBoxFill, - RiAddCircleFill, - RiArrowDownLine, - RiArrowRightSFill, - RiArrowUpLine, - RiDeleteBinFill, - RiDislikeFill, - RiHeartFill, - RiPlayFill, - RiPlayListAddFill, - RiStarFill, - RiCloseCircleLine, + RiAddBoxFill, + RiAddCircleFill, + RiArrowDownLine, + RiArrowRightSFill, + RiArrowUpLine, + RiDeleteBinFill, + RiDislikeFill, + RiHeartFill, + RiPlayFill, + RiPlayListAddFill, + RiStarFill, + RiCloseCircleLine, } from 'react-icons/ri'; import { AnyLibraryItems, LibraryItem, ServerType, AnyLibraryItem } from '/@/renderer/api/types'; import { - ConfirmModal, - ContextMenu, - ContextMenuButton, - HoverCard, - Rating, - Text, - toast, + ConfirmModal, + ContextMenu, + ContextMenuButton, + HoverCard, + Rating, + Text, + toast, } from '/@/renderer/components'; import { - ContextMenuItemType, - OpenContextMenuProps, - useContextMenuEvents, + ContextMenuItemType, + OpenContextMenuProps, + useContextMenuEvents, } from '/@/renderer/features/context-menu/events'; import { usePlayQueueAdd } from '/@/renderer/features/player'; import { useDeletePlaylist } from '/@/renderer/features/playlists'; import { useRemoveFromPlaylist } from '/@/renderer/features/playlists/mutations/remove-from-playlist-mutation'; import { useCreateFavorite, useDeleteFavorite, useSetRating } from '/@/renderer/features/shared'; import { - useAuthStore, - useCurrentServer, - usePlayerStore, - useQueueControls, + useAuthStore, + useCurrentServer, + usePlayerStore, + useQueueControls, } from '/@/renderer/store'; import { usePlayerType } from '/@/renderer/store/settings.store'; import { Play, PlaybackType } from '/@/renderer/types'; type ContextMenuContextProps = { - closeContextMenu: () => void; - openContextMenu: (args: OpenContextMenuProps) => void; + closeContextMenu: () => void; + openContextMenu: (args: OpenContextMenuProps) => void; }; type ContextMenuItem = { - children?: ContextMenuItem[]; - disabled?: boolean; - id: string; - label: string | ReactNode; - leftIcon?: ReactNode; - onClick?: (...args: any) => any; - rightIcon?: ReactNode; + children?: ContextMenuItem[]; + disabled?: boolean; + id: string; + label: string | ReactNode; + leftIcon?: ReactNode; + onClick?: (...args: any) => any; + rightIcon?: ReactNode; }; const ContextMenuContext = createContext<ContextMenuContextProps>({ - closeContextMenu: () => {}, - openContextMenu: (args: OpenContextMenuProps) => { - return args; - }, + closeContextMenu: () => {}, + openContextMenu: (args: OpenContextMenuProps) => { + return args; + }, }); const JELLYFIN_IGNORED_MENU_ITEMS: ContextMenuItemType[] = ['setRating']; @@ -82,759 +82,780 @@ const JELLYFIN_IGNORED_MENU_ITEMS: ContextMenuItemType[] = ['setRating']; const mpvPlayer = isElectron() ? window.electron.mpvPlayer : null; export interface ContextMenuProviderProps { - children: React.ReactNode; + children: React.ReactNode; } export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => { - const [opened, setOpened] = useState(false); - const clickOutsideRef = useClickOutside(() => setOpened(false)); + const [opened, setOpened] = useState(false); + const clickOutsideRef = useClickOutside(() => setOpened(false)); - const viewport = useViewportSize(); - const server = useCurrentServer(); - const serverType = server?.type; - const [ref, menuRect] = useResizeObserver(); - const [ctx, setCtx] = useSetState<OpenContextMenuProps>({ - data: [], - dataNodes: [], - menuItems: [], - tableApi: undefined, - type: LibraryItem.SONG, - xPos: 0, - yPos: 0, - }); - - const handlePlayQueueAdd = usePlayQueueAdd(); - - const openContextMenu = (args: OpenContextMenuProps) => { - const { xPos, yPos, menuItems, data, type, tableApi, dataNodes, context } = args; - - const serverType = data[0]?.serverType || useAuthStore.getState().currentServer?.type; - let validMenuItems = menuItems; - - if (serverType === ServerType.JELLYFIN) { - validMenuItems = menuItems.filter((item) => !JELLYFIN_IGNORED_MENU_ITEMS.includes(item.id)); - } - - // If the context menu dimension can't be automatically calculated, calculate it manually - // This is a hacky way since resize observer may not automatically recalculate when not rendered - const menuHeight = menuRect.height || (menuItems.length + 1) * 50; - const menuWidth = menuRect.width || 220; - - const shouldReverseY = yPos + menuHeight > viewport.height; - const shouldReverseX = xPos + menuWidth > viewport.width; - - const calculatedXPos = shouldReverseX ? xPos - menuWidth : xPos; - const calculatedYPos = shouldReverseY ? yPos - menuHeight : yPos; - - setCtx({ - context, - data, - dataNodes, - menuItems: validMenuItems, - tableApi, - type, - xPos: calculatedXPos, - yPos: calculatedYPos, + const viewport = useViewportSize(); + const server = useCurrentServer(); + const serverType = server?.type; + const [ref, menuRect] = useResizeObserver(); + const [ctx, setCtx] = useSetState<OpenContextMenuProps>({ + data: [], + dataNodes: [], + menuItems: [], + tableApi: undefined, + type: LibraryItem.SONG, + xPos: 0, + yPos: 0, }); - setOpened(true); - }; - const closeContextMenu = () => { - setOpened(false); - setCtx({ - data: [], - dataNodes: [], - menuItems: [], - tableApi: undefined, - type: LibraryItem.SONG, - xPos: 0, - yPos: 0, - }); - }; + const handlePlayQueueAdd = usePlayQueueAdd(); - useContextMenuEvents({ - closeContextMenu, - openContextMenu, - }); + const openContextMenu = (args: OpenContextMenuProps) => { + const { xPos, yPos, menuItems, data, type, tableApi, dataNodes, context } = args; - const handlePlay = useCallback( - (playType: Play) => { - switch (ctx.type) { - case LibraryItem.ALBUM: - handlePlayQueueAdd?.({ - byItemType: { id: ctx.data.map((item) => item.id), type: ctx.type }, - playType, - }); - break; - case LibraryItem.ARTIST: - handlePlayQueueAdd?.({ - byItemType: { id: ctx.data.map((item) => item.id), type: ctx.type }, - playType, - }); - break; - case LibraryItem.ALBUM_ARTIST: - handlePlayQueueAdd?.({ - byItemType: { id: ctx.data.map((item) => item.id), type: ctx.type }, - playType, - }); - break; - case LibraryItem.SONG: - handlePlayQueueAdd?.({ byData: ctx.data, playType }); - break; - case LibraryItem.PLAYLIST: - for (const item of ctx.data) { - handlePlayQueueAdd?.({ - byItemType: { id: [item.id], type: ctx.type }, - playType, - }); - } + const serverType = data[0]?.serverType || useAuthStore.getState().currentServer?.type; + let validMenuItems = menuItems; - break; - } - }, - [ctx.data, ctx.type, handlePlayQueueAdd], - ); - - const deletePlaylistMutation = useDeletePlaylist({}); - - const handleDeletePlaylist = useCallback(() => { - for (const item of ctx.data) { - deletePlaylistMutation?.mutate( - { query: { id: item.id }, serverId: item.serverId }, - { - onError: (err) => { - toast.error({ - message: err.message, - title: 'Error deleting playlist', - }); - }, - onSuccess: () => { - toast.success({ - message: `Playlist has been deleted`, - }); - }, - }, - ); - } - closeAllModals(); - }, [ctx.data, deletePlaylistMutation]); - - const openDeletePlaylistModal = useCallback(() => { - openModal({ - children: ( - <ConfirmModal onConfirm={handleDeletePlaylist}> - <Stack> - <Text>Are you sure you want to delete the following playlist(s)?</Text> - <ul> - {ctx.data.map((item) => ( - <li key={item.id}> - <Group> - —<Text $secondary>{item.name}</Text> - </Group> - </li> - ))} - </ul> - </Stack> - </ConfirmModal> - ), - title: 'Delete playlist(s)', - }); - }, [ctx.data, handleDeletePlaylist]); - - const createFavoriteMutation = useCreateFavorite({}); - const deleteFavoriteMutation = useDeleteFavorite({}); - const handleAddToFavorites = useCallback(() => { - if (!ctx.dataNodes && !ctx.data) return; - - if (ctx.dataNodes) { - const nodesToFavorite = ctx.dataNodes.filter((item) => !item.data.userFavorite); - - const nodesByServerId = nodesToFavorite.reduce((acc, node) => { - if (!acc[node.data.serverId]) { - acc[node.data.serverId] = []; + if (serverType === ServerType.JELLYFIN) { + validMenuItems = menuItems.filter( + (item) => !JELLYFIN_IGNORED_MENU_ITEMS.includes(item.id), + ); } - acc[node.data.serverId].push(node); - return acc; - }, {} as Record<string, RowNode<any>[]>); - for (const serverId of Object.keys(nodesByServerId)) { - const nodes = nodesByServerId[serverId]; - const items = nodes.map((node) => node.data); + // If the context menu dimension can't be automatically calculated, calculate it manually + // This is a hacky way since resize observer may not automatically recalculate when not rendered + const menuHeight = menuRect.height || (menuItems.length + 1) * 50; + const menuWidth = menuRect.width || 220; - createFavoriteMutation.mutate( - { - query: { - id: items.map((item) => item.id), - type: ctx.type, - }, - serverId, - }, - { - onError: (err) => { - toast.error({ - message: err.message, - title: 'Error adding to favorites', - }); - }, - onSuccess: () => { - for (const node of nodes) { - node.setData({ ...node.data, userFavorite: true }); - } - }, - }, - ); - } - } else { - const itemsToFavorite = ctx.data.filter((item) => !item.userFavorite); - const itemsByServerId = (itemsToFavorite as any[]).reduce((acc, item) => { - if (!acc[item.serverId]) { - acc[item.serverId] = []; - } - acc[item.serverId].push(item); - return acc; - }, {} as Record<string, AnyLibraryItems>); + const shouldReverseY = yPos + menuHeight > viewport.height; + const shouldReverseX = xPos + menuWidth > viewport.width; - for (const serverId of Object.keys(itemsByServerId)) { - const items = itemsByServerId[serverId]; + const calculatedXPos = shouldReverseX ? xPos - menuWidth : xPos; + const calculatedYPos = shouldReverseY ? yPos - menuHeight : yPos; - createFavoriteMutation.mutate( - { - query: { - id: items.map((item: AnyLibraryItem) => item.id), - type: ctx.type, - }, - serverId, - }, - { - onError: (err) => { - toast.error({ - message: err.message, - title: 'Error adding to favorites', - }); - }, - }, - ); - } - } - }, [createFavoriteMutation, ctx.data, ctx.dataNodes, ctx.type]); - - const handleRemoveFromFavorites = useCallback(() => { - if (!ctx.dataNodes && !ctx.data) return; - - if (ctx.dataNodes) { - const nodesToUnfavorite = ctx.dataNodes.filter((item) => item.data.userFavorite); - const nodesByServerId = nodesToUnfavorite.reduce((acc, node) => { - if (!acc[node.data.serverId]) { - acc[node.data.serverId] = []; - } - acc[node.data.serverId].push(node); - return acc; - }, {} as Record<string, RowNode<any>[]>); - - for (const serverId of Object.keys(nodesByServerId)) { - const idsToUnfavorite = nodesByServerId[serverId].map((node) => node.data.id); - deleteFavoriteMutation.mutate( - { - query: { - id: idsToUnfavorite, - type: ctx.type, - }, - serverId, - }, - { - onSuccess: () => { - for (const node of nodesToUnfavorite) { - node.setData({ ...node.data, userFavorite: false }); - } - }, - }, - ); - } - } else { - const itemsToUnfavorite = ctx.data.filter((item) => item.userFavorite); - const itemsByServerId = (itemsToUnfavorite as any[]).reduce((acc, item) => { - if (!acc[item.serverId]) { - acc[item.serverId] = []; - } - acc[item.serverId].push(item); - return acc; - }, {} as Record<string, AnyLibraryItems>); - - for (const serverId of Object.keys(itemsByServerId)) { - const idsToUnfavorite = itemsByServerId[serverId].map((item: AnyLibraryItem) => item.id); - deleteFavoriteMutation.mutate({ - query: { - id: idsToUnfavorite, - type: ctx.type, - }, - serverId, + setCtx({ + context, + data, + dataNodes, + menuItems: validMenuItems, + tableApi, + type, + xPos: calculatedXPos, + yPos: calculatedYPos, }); - } - } - }, [ctx.data, ctx.dataNodes, ctx.type, deleteFavoriteMutation]); - - const handleAddToPlaylist = useCallback(() => { - if (!ctx.dataNodes && !ctx.data) return; - - const albumId: string[] = []; - const artistId: string[] = []; - const songId: string[] = []; - - if (ctx.dataNodes) { - for (const node of ctx.dataNodes) { - switch (node.data.itemType) { - case LibraryItem.ALBUM: - albumId.push(node.data.id); - break; - case LibraryItem.ARTIST: - artistId.push(node.data.id); - break; - case LibraryItem.SONG: - songId.push(node.data.id); - break; - } - } - } else { - for (const item of ctx.data) { - switch (item.itemType) { - case LibraryItem.ALBUM: - albumId.push(item.id); - break; - case LibraryItem.ARTIST: - artistId.push(item.id); - break; - case LibraryItem.SONG: - songId.push(item.id); - break; - } - } - } - - openContextModal({ - innerProps: { - albumId: albumId.length > 0 ? albumId : undefined, - artistId: artistId.length > 0 ? artistId : undefined, - songId: songId.length > 0 ? songId : undefined, - }, - modal: 'addToPlaylist', - size: 'md', - title: 'Add to playlist', - }); - }, [ctx.data, ctx.dataNodes]); - - const removeFromPlaylistMutation = useRemoveFromPlaylist(); - - const handleRemoveFromPlaylist = useCallback(() => { - const songId = - (serverType === ServerType.NAVIDROME || ServerType.JELLYFIN - ? ctx.dataNodes?.map((node) => node.data.playlistItemId) - : ctx.dataNodes?.map((node) => node.data.id)) || []; - - const confirm = () => { - removeFromPlaylistMutation.mutate( - { - query: { - id: ctx.context.playlistId, - songId, - }, - serverId: ctx.data?.[0]?.serverId, - }, - { - onError: (err) => { - toast.error({ - message: err.message, - title: 'Error removing song(s) from playlist', - }); - }, - onSuccess: () => { - toast.success({ - message: `${songId.length} song(s) were removed from the playlist`, - }); - ctx.context?.tableRef?.current?.api?.refreshInfiniteCache(); - closeAllModals(); - }, - }, - ); + setOpened(true); }; - openModal({ - children: ( - <ConfirmModal - loading={removeFromPlaylistMutation.isLoading} - onConfirm={confirm} - > - Are you sure you want to remove the following song(s) from the playlist? - </ConfirmModal> - ), - title: 'Remove song(s) from playlist', - }); - }, [ - ctx.context?.playlistId, - ctx.context?.tableRef, - ctx.data, - ctx.dataNodes, - removeFromPlaylistMutation, - serverType, - ]); - - const updateRatingMutation = useSetRating({}); - - const handleUpdateRating = useCallback( - (rating: number) => { - if (!ctx.dataNodes || !ctx.data) return; - - let uniqueServerIds: string[] = []; - let items: AnyLibraryItems = []; - - if (ctx.dataNodes) { - uniqueServerIds = ctx.dataNodes.reduce((acc, node) => { - if (!acc.includes(node.data.serverId)) { - acc.push(node.data.serverId); - } - return acc; - }, [] as string[]); - } else { - uniqueServerIds = ctx.data.reduce((acc, item) => { - if (!acc.includes(item.serverId)) { - acc.push(item.serverId); - } - return acc; - }, [] as string[]); - } - - for (const serverId of uniqueServerIds) { - if (ctx.dataNodes) { - items = ctx.dataNodes - .filter((node) => node.data.serverId === serverId) - .map((node) => node.data); - } else { - items = ctx.data.filter((item) => item.serverId === serverId); - } - - updateRatingMutation.mutate( - { - query: { - item: items, - rating, - }, - serverId, - }, - { - onSuccess: () => { - if (ctx.dataNodes) { - for (const node of ctx.dataNodes) { - node.setData({ ...node.data, userRating: rating }); - } - } - }, - }, - ); - } - }, - [ctx.data, ctx.dataNodes, updateRatingMutation], - ); - - const playerType = usePlayerType(); - const { moveToBottomOfQueue, moveToTopOfQueue, removeFromQueue } = useQueueControls(); - - const handleMoveToBottom = useCallback(() => { - const uniqueIds = ctx.dataNodes?.map((row) => row.data.uniqueId); - if (!uniqueIds?.length) return; - - const playerData = moveToBottomOfQueue(uniqueIds); - - if (playerType === PlaybackType.LOCAL) { - mpvPlayer.setQueueNext(playerData); - } - }, [ctx.dataNodes, moveToBottomOfQueue, playerType]); - - const handleMoveToTop = useCallback(() => { - const uniqueIds = ctx.dataNodes?.map((row) => row.data.uniqueId); - if (!uniqueIds?.length) return; - - const playerData = moveToTopOfQueue(uniqueIds); - - if (playerType === PlaybackType.LOCAL) { - mpvPlayer.setQueueNext(playerData); - } - }, [ctx.dataNodes, moveToTopOfQueue, playerType]); - - const handleRemoveSelected = useCallback(() => { - const uniqueIds = ctx.dataNodes?.map((row) => row.data.uniqueId); - if (!uniqueIds?.length) return; - - const currentSong = usePlayerStore.getState().current.song; - const playerData = removeFromQueue(uniqueIds); - const isCurrentSongRemoved = currentSong && uniqueIds.includes(currentSong?.uniqueId); - - if (playerType === PlaybackType.LOCAL) { - if (isCurrentSongRemoved) { - mpvPlayer.setQueue(playerData); - } else { - mpvPlayer.setQueueNext(playerData); - } - } - }, [ctx.dataNodes, playerType, removeFromQueue]); - - const handleDeselectAll = useCallback(() => { - ctx.tableApi?.deselectAll(); - }, [ctx.tableApi]); - - const contextMenuItems: Record<ContextMenuItemType, ContextMenuItem> = useMemo(() => { - return { - addToFavorites: { - id: 'addToFavorites', - label: 'Add favorite', - leftIcon: <RiHeartFill size="1.1rem" />, - onClick: handleAddToFavorites, - }, - addToPlaylist: { - id: 'addToPlaylist', - label: 'Add to playlist', - leftIcon: <RiPlayListAddFill size="1.1rem" />, - onClick: handleAddToPlaylist, - }, - createPlaylist: { id: 'createPlaylist', label: 'Create playlist', onClick: () => {} }, - deletePlaylist: { - id: 'deletePlaylist', - label: 'Delete playlist', - leftIcon: <RiDeleteBinFill size="1.1rem" />, - onClick: openDeletePlaylistModal, - }, - deselectAll: { - id: 'deselectAll', - label: 'Deselect all', - leftIcon: <RiCloseCircleLine size="1.1rem" />, - onClick: handleDeselectAll, - }, - moveToBottomOfQueue: { - id: 'moveToBottomOfQueue', - label: 'Move to bottom', - leftIcon: <RiArrowDownLine size="1.1rem" />, - onClick: handleMoveToBottom, - }, - moveToTopOfQueue: { - id: 'moveToTopOfQueue', - label: 'Move to top', - leftIcon: <RiArrowUpLine size="1.1rem" />, - onClick: handleMoveToTop, - }, - play: { - id: 'play', - label: 'Play', - leftIcon: <RiPlayFill size="1.1rem" />, - onClick: () => handlePlay(Play.NOW), - }, - playLast: { - id: 'playLast', - label: 'Add to queue', - leftIcon: <RiAddBoxFill size="1.1rem" />, - onClick: () => handlePlay(Play.LAST), - }, - playNext: { - id: 'playNext', - label: 'Add to queue next', - leftIcon: <RiAddCircleFill size="1.1rem" />, - onClick: () => handlePlay(Play.NEXT), - }, - removeFromFavorites: { - id: 'removeFromFavorites', - label: 'Remove favorite', - leftIcon: <RiDislikeFill size="1.1rem" />, - onClick: handleRemoveFromFavorites, - }, - removeFromPlaylist: { - id: 'removeFromPlaylist', - label: 'Remove from playlist', - leftIcon: <RiDeleteBinFill size="1.1rem" />, - onClick: handleRemoveFromPlaylist, - }, - removeFromQueue: { - id: 'moveToBottomOfQueue', - label: 'Remove songs', - leftIcon: <RiDeleteBinFill size="1.1rem" />, - onClick: handleRemoveSelected, - }, - setRating: { - children: [ - { - id: 'zeroStar', - label: ( - <Rating - readOnly - value={0} - onClick={() => {}} - /> - ), - onClick: () => handleUpdateRating(0), - }, - { - id: 'oneStar', - label: ( - <Rating - readOnly - value={1} - onClick={() => {}} - /> - ), - onClick: () => handleUpdateRating(1), - }, - { - id: 'twoStar', - label: ( - <Rating - readOnly - value={2} - onClick={() => {}} - /> - ), - onClick: () => handleUpdateRating(2), - }, - { - id: 'threeStar', - label: ( - <Rating - readOnly - value={3} - onClick={() => {}} - /> - ), - onClick: () => handleUpdateRating(3), - }, - { - id: 'fourStar', - label: ( - <Rating - readOnly - value={4} - onClick={() => {}} - /> - ), - onClick: () => handleUpdateRating(4), - }, - { - id: 'fiveStar', - label: ( - <Rating - readOnly - value={5} - onClick={() => {}} - /> - ), - onClick: () => handleUpdateRating(5), - }, - ], - id: 'setRating', - label: 'Set rating', - leftIcon: <RiStarFill size="1.1rem" />, - onClick: () => {}, - rightIcon: <RiArrowRightSFill size="1.2rem" />, - }, + const closeContextMenu = () => { + setOpened(false); + setCtx({ + data: [], + dataNodes: [], + menuItems: [], + tableApi: undefined, + type: LibraryItem.SONG, + xPos: 0, + yPos: 0, + }); }; - }, [ - handleAddToFavorites, - handleAddToPlaylist, - handleDeselectAll, - handleMoveToBottom, - handleMoveToTop, - handlePlay, - handleRemoveFromFavorites, - handleRemoveFromPlaylist, - handleRemoveSelected, - handleUpdateRating, - openDeletePlaylistModal, - ]); - const mergedRef = useMergedRef(ref, clickOutsideRef); - - return ( - <ContextMenuContext.Provider - value={{ + useContextMenuEvents({ closeContextMenu, openContextMenu, - }} - > - <Portal> - <AnimatePresence> - {opened && ( - <ContextMenu - ref={mergedRef} - minWidth={125} - xPos={ctx.xPos} - yPos={ctx.yPos} - > - <Stack spacing={0}> - <Stack - spacing={0} - onClick={closeContextMenu} - > - {ctx.menuItems?.map((item) => { - return ( - <Fragment key={`context-menu-${item.id}`}> - {item.children ? ( - <HoverCard - offset={5} - position="right" - > - <HoverCard.Target> - <ContextMenuButton - disabled={item.disabled} - leftIcon={contextMenuItems[item.id].leftIcon} - rightIcon={contextMenuItems[item.id].rightIcon} - onClick={contextMenuItems[item.id].onClick} - > - {contextMenuItems[item.id].label} - </ContextMenuButton> - </HoverCard.Target> - <HoverCard.Dropdown> - <Stack spacing={0}> - {contextMenuItems[item.id].children?.map((child) => ( - <ContextMenuButton - key={`sub-${child.id}`} - disabled={child.disabled} - leftIcon={child.leftIcon} - rightIcon={child.rightIcon} - onClick={child.onClick} - > - {child.label} - </ContextMenuButton> - ))} - </Stack> - </HoverCard.Dropdown> - </HoverCard> - ) : ( - <ContextMenuButton - disabled={item.disabled} - leftIcon={contextMenuItems[item.id].leftIcon} - rightIcon={contextMenuItems[item.id].rightIcon} - onClick={contextMenuItems[item.id].onClick} - > - {contextMenuItems[item.id].label} - </ContextMenuButton> - )} + }); - {item.divider && ( - <Divider - key={`context-menu-divider-${item.id}`} - color="rgb(62, 62, 62)" - size="sm" - /> - )} - </Fragment> - ); - })} - </Stack> - <Divider - color="rgb(62, 62, 62)" - size="sm" - /> - <ContextMenuButton disabled>{ctx.data?.length} selected</ContextMenuButton> - </Stack> - </ContextMenu> - )} - </AnimatePresence> - {children} - </Portal> - </ContextMenuContext.Provider> - ); + const handlePlay = useCallback( + (playType: Play) => { + switch (ctx.type) { + case LibraryItem.ALBUM: + handlePlayQueueAdd?.({ + byItemType: { id: ctx.data.map((item) => item.id), type: ctx.type }, + playType, + }); + break; + case LibraryItem.ARTIST: + handlePlayQueueAdd?.({ + byItemType: { id: ctx.data.map((item) => item.id), type: ctx.type }, + playType, + }); + break; + case LibraryItem.ALBUM_ARTIST: + handlePlayQueueAdd?.({ + byItemType: { id: ctx.data.map((item) => item.id), type: ctx.type }, + playType, + }); + break; + case LibraryItem.SONG: + handlePlayQueueAdd?.({ byData: ctx.data, playType }); + break; + case LibraryItem.PLAYLIST: + for (const item of ctx.data) { + handlePlayQueueAdd?.({ + byItemType: { id: [item.id], type: ctx.type }, + playType, + }); + } + + break; + } + }, + [ctx.data, ctx.type, handlePlayQueueAdd], + ); + + const deletePlaylistMutation = useDeletePlaylist({}); + + const handleDeletePlaylist = useCallback(() => { + for (const item of ctx.data) { + deletePlaylistMutation?.mutate( + { query: { id: item.id }, serverId: item.serverId }, + { + onError: (err) => { + toast.error({ + message: err.message, + title: 'Error deleting playlist', + }); + }, + onSuccess: () => { + toast.success({ + message: `Playlist has been deleted`, + }); + }, + }, + ); + } + closeAllModals(); + }, [ctx.data, deletePlaylistMutation]); + + const openDeletePlaylistModal = useCallback(() => { + openModal({ + children: ( + <ConfirmModal onConfirm={handleDeletePlaylist}> + <Stack> + <Text>Are you sure you want to delete the following playlist(s)?</Text> + <ul> + {ctx.data.map((item) => ( + <li key={item.id}> + <Group> + —<Text $secondary>{item.name}</Text> + </Group> + </li> + ))} + </ul> + </Stack> + </ConfirmModal> + ), + title: 'Delete playlist(s)', + }); + }, [ctx.data, handleDeletePlaylist]); + + const createFavoriteMutation = useCreateFavorite({}); + const deleteFavoriteMutation = useDeleteFavorite({}); + const handleAddToFavorites = useCallback(() => { + if (!ctx.dataNodes && !ctx.data) return; + + if (ctx.dataNodes) { + const nodesToFavorite = ctx.dataNodes.filter((item) => !item.data.userFavorite); + + const nodesByServerId = nodesToFavorite.reduce((acc, node) => { + if (!acc[node.data.serverId]) { + acc[node.data.serverId] = []; + } + acc[node.data.serverId].push(node); + return acc; + }, {} as Record<string, RowNode<any>[]>); + + for (const serverId of Object.keys(nodesByServerId)) { + const nodes = nodesByServerId[serverId]; + const items = nodes.map((node) => node.data); + + createFavoriteMutation.mutate( + { + query: { + id: items.map((item) => item.id), + type: ctx.type, + }, + serverId, + }, + { + onError: (err) => { + toast.error({ + message: err.message, + title: 'Error adding to favorites', + }); + }, + onSuccess: () => { + for (const node of nodes) { + node.setData({ ...node.data, userFavorite: true }); + } + }, + }, + ); + } + } else { + const itemsToFavorite = ctx.data.filter((item) => !item.userFavorite); + const itemsByServerId = (itemsToFavorite as any[]).reduce((acc, item) => { + if (!acc[item.serverId]) { + acc[item.serverId] = []; + } + acc[item.serverId].push(item); + return acc; + }, {} as Record<string, AnyLibraryItems>); + + for (const serverId of Object.keys(itemsByServerId)) { + const items = itemsByServerId[serverId]; + + createFavoriteMutation.mutate( + { + query: { + id: items.map((item: AnyLibraryItem) => item.id), + type: ctx.type, + }, + serverId, + }, + { + onError: (err) => { + toast.error({ + message: err.message, + title: 'Error adding to favorites', + }); + }, + }, + ); + } + } + }, [createFavoriteMutation, ctx.data, ctx.dataNodes, ctx.type]); + + const handleRemoveFromFavorites = useCallback(() => { + if (!ctx.dataNodes && !ctx.data) return; + + if (ctx.dataNodes) { + const nodesToUnfavorite = ctx.dataNodes.filter((item) => item.data.userFavorite); + const nodesByServerId = nodesToUnfavorite.reduce((acc, node) => { + if (!acc[node.data.serverId]) { + acc[node.data.serverId] = []; + } + acc[node.data.serverId].push(node); + return acc; + }, {} as Record<string, RowNode<any>[]>); + + for (const serverId of Object.keys(nodesByServerId)) { + const idsToUnfavorite = nodesByServerId[serverId].map((node) => node.data.id); + deleteFavoriteMutation.mutate( + { + query: { + id: idsToUnfavorite, + type: ctx.type, + }, + serverId, + }, + { + onSuccess: () => { + for (const node of nodesToUnfavorite) { + node.setData({ ...node.data, userFavorite: false }); + } + }, + }, + ); + } + } else { + const itemsToUnfavorite = ctx.data.filter((item) => item.userFavorite); + const itemsByServerId = (itemsToUnfavorite as any[]).reduce((acc, item) => { + if (!acc[item.serverId]) { + acc[item.serverId] = []; + } + acc[item.serverId].push(item); + return acc; + }, {} as Record<string, AnyLibraryItems>); + + for (const serverId of Object.keys(itemsByServerId)) { + const idsToUnfavorite = itemsByServerId[serverId].map( + (item: AnyLibraryItem) => item.id, + ); + deleteFavoriteMutation.mutate({ + query: { + id: idsToUnfavorite, + type: ctx.type, + }, + serverId, + }); + } + } + }, [ctx.data, ctx.dataNodes, ctx.type, deleteFavoriteMutation]); + + const handleAddToPlaylist = useCallback(() => { + if (!ctx.dataNodes && !ctx.data) return; + + const albumId: string[] = []; + const artistId: string[] = []; + const songId: string[] = []; + + if (ctx.dataNodes) { + for (const node of ctx.dataNodes) { + switch (node.data.itemType) { + case LibraryItem.ALBUM: + albumId.push(node.data.id); + break; + case LibraryItem.ARTIST: + artistId.push(node.data.id); + break; + case LibraryItem.SONG: + songId.push(node.data.id); + break; + } + } + } else { + for (const item of ctx.data) { + switch (item.itemType) { + case LibraryItem.ALBUM: + albumId.push(item.id); + break; + case LibraryItem.ARTIST: + artistId.push(item.id); + break; + case LibraryItem.SONG: + songId.push(item.id); + break; + } + } + } + + openContextModal({ + innerProps: { + albumId: albumId.length > 0 ? albumId : undefined, + artistId: artistId.length > 0 ? artistId : undefined, + songId: songId.length > 0 ? songId : undefined, + }, + modal: 'addToPlaylist', + size: 'md', + title: 'Add to playlist', + }); + }, [ctx.data, ctx.dataNodes]); + + const removeFromPlaylistMutation = useRemoveFromPlaylist(); + + const handleRemoveFromPlaylist = useCallback(() => { + const songId = + (serverType === ServerType.NAVIDROME || ServerType.JELLYFIN + ? ctx.dataNodes?.map((node) => node.data.playlistItemId) + : ctx.dataNodes?.map((node) => node.data.id)) || []; + + const confirm = () => { + removeFromPlaylistMutation.mutate( + { + query: { + id: ctx.context.playlistId, + songId, + }, + serverId: ctx.data?.[0]?.serverId, + }, + { + onError: (err) => { + toast.error({ + message: err.message, + title: 'Error removing song(s) from playlist', + }); + }, + onSuccess: () => { + toast.success({ + message: `${songId.length} song(s) were removed from the playlist`, + }); + ctx.context?.tableRef?.current?.api?.refreshInfiniteCache(); + closeAllModals(); + }, + }, + ); + }; + + openModal({ + children: ( + <ConfirmModal + loading={removeFromPlaylistMutation.isLoading} + onConfirm={confirm} + > + Are you sure you want to remove the following song(s) from the playlist? + </ConfirmModal> + ), + title: 'Remove song(s) from playlist', + }); + }, [ + ctx.context?.playlistId, + ctx.context?.tableRef, + ctx.data, + ctx.dataNodes, + removeFromPlaylistMutation, + serverType, + ]); + + const updateRatingMutation = useSetRating({}); + + const handleUpdateRating = useCallback( + (rating: number) => { + if (!ctx.dataNodes || !ctx.data) return; + + let uniqueServerIds: string[] = []; + let items: AnyLibraryItems = []; + + if (ctx.dataNodes) { + uniqueServerIds = ctx.dataNodes.reduce((acc, node) => { + if (!acc.includes(node.data.serverId)) { + acc.push(node.data.serverId); + } + return acc; + }, [] as string[]); + } else { + uniqueServerIds = ctx.data.reduce((acc, item) => { + if (!acc.includes(item.serverId)) { + acc.push(item.serverId); + } + return acc; + }, [] as string[]); + } + + for (const serverId of uniqueServerIds) { + if (ctx.dataNodes) { + items = ctx.dataNodes + .filter((node) => node.data.serverId === serverId) + .map((node) => node.data); + } else { + items = ctx.data.filter((item) => item.serverId === serverId); + } + + updateRatingMutation.mutate( + { + query: { + item: items, + rating, + }, + serverId, + }, + { + onSuccess: () => { + if (ctx.dataNodes) { + for (const node of ctx.dataNodes) { + node.setData({ ...node.data, userRating: rating }); + } + } + }, + }, + ); + } + }, + [ctx.data, ctx.dataNodes, updateRatingMutation], + ); + + const playerType = usePlayerType(); + const { moveToBottomOfQueue, moveToTopOfQueue, removeFromQueue } = useQueueControls(); + + const handleMoveToBottom = useCallback(() => { + const uniqueIds = ctx.dataNodes?.map((row) => row.data.uniqueId); + if (!uniqueIds?.length) return; + + const playerData = moveToBottomOfQueue(uniqueIds); + + if (playerType === PlaybackType.LOCAL) { + mpvPlayer.setQueueNext(playerData); + } + }, [ctx.dataNodes, moveToBottomOfQueue, playerType]); + + const handleMoveToTop = useCallback(() => { + const uniqueIds = ctx.dataNodes?.map((row) => row.data.uniqueId); + if (!uniqueIds?.length) return; + + const playerData = moveToTopOfQueue(uniqueIds); + + if (playerType === PlaybackType.LOCAL) { + mpvPlayer.setQueueNext(playerData); + } + }, [ctx.dataNodes, moveToTopOfQueue, playerType]); + + const handleRemoveSelected = useCallback(() => { + const uniqueIds = ctx.dataNodes?.map((row) => row.data.uniqueId); + if (!uniqueIds?.length) return; + + const currentSong = usePlayerStore.getState().current.song; + const playerData = removeFromQueue(uniqueIds); + const isCurrentSongRemoved = currentSong && uniqueIds.includes(currentSong?.uniqueId); + + if (playerType === PlaybackType.LOCAL) { + if (isCurrentSongRemoved) { + mpvPlayer.setQueue(playerData); + } else { + mpvPlayer.setQueueNext(playerData); + } + } + }, [ctx.dataNodes, playerType, removeFromQueue]); + + const handleDeselectAll = useCallback(() => { + ctx.tableApi?.deselectAll(); + }, [ctx.tableApi]); + + const contextMenuItems: Record<ContextMenuItemType, ContextMenuItem> = useMemo(() => { + return { + addToFavorites: { + id: 'addToFavorites', + label: 'Add favorite', + leftIcon: <RiHeartFill size="1.1rem" />, + onClick: handleAddToFavorites, + }, + addToPlaylist: { + id: 'addToPlaylist', + label: 'Add to playlist', + leftIcon: <RiPlayListAddFill size="1.1rem" />, + onClick: handleAddToPlaylist, + }, + createPlaylist: { id: 'createPlaylist', label: 'Create playlist', onClick: () => {} }, + deletePlaylist: { + id: 'deletePlaylist', + label: 'Delete playlist', + leftIcon: <RiDeleteBinFill size="1.1rem" />, + onClick: openDeletePlaylistModal, + }, + deselectAll: { + id: 'deselectAll', + label: 'Deselect all', + leftIcon: <RiCloseCircleLine size="1.1rem" />, + onClick: handleDeselectAll, + }, + moveToBottomOfQueue: { + id: 'moveToBottomOfQueue', + label: 'Move to bottom', + leftIcon: <RiArrowDownLine size="1.1rem" />, + onClick: handleMoveToBottom, + }, + moveToTopOfQueue: { + id: 'moveToTopOfQueue', + label: 'Move to top', + leftIcon: <RiArrowUpLine size="1.1rem" />, + onClick: handleMoveToTop, + }, + play: { + id: 'play', + label: 'Play', + leftIcon: <RiPlayFill size="1.1rem" />, + onClick: () => handlePlay(Play.NOW), + }, + playLast: { + id: 'playLast', + label: 'Add to queue', + leftIcon: <RiAddBoxFill size="1.1rem" />, + onClick: () => handlePlay(Play.LAST), + }, + playNext: { + id: 'playNext', + label: 'Add to queue next', + leftIcon: <RiAddCircleFill size="1.1rem" />, + onClick: () => handlePlay(Play.NEXT), + }, + removeFromFavorites: { + id: 'removeFromFavorites', + label: 'Remove favorite', + leftIcon: <RiDislikeFill size="1.1rem" />, + onClick: handleRemoveFromFavorites, + }, + removeFromPlaylist: { + id: 'removeFromPlaylist', + label: 'Remove from playlist', + leftIcon: <RiDeleteBinFill size="1.1rem" />, + onClick: handleRemoveFromPlaylist, + }, + removeFromQueue: { + id: 'moveToBottomOfQueue', + label: 'Remove songs', + leftIcon: <RiDeleteBinFill size="1.1rem" />, + onClick: handleRemoveSelected, + }, + setRating: { + children: [ + { + id: 'zeroStar', + label: ( + <Rating + readOnly + value={0} + onClick={() => {}} + /> + ), + onClick: () => handleUpdateRating(0), + }, + { + id: 'oneStar', + label: ( + <Rating + readOnly + value={1} + onClick={() => {}} + /> + ), + onClick: () => handleUpdateRating(1), + }, + { + id: 'twoStar', + label: ( + <Rating + readOnly + value={2} + onClick={() => {}} + /> + ), + onClick: () => handleUpdateRating(2), + }, + { + id: 'threeStar', + label: ( + <Rating + readOnly + value={3} + onClick={() => {}} + /> + ), + onClick: () => handleUpdateRating(3), + }, + { + id: 'fourStar', + label: ( + <Rating + readOnly + value={4} + onClick={() => {}} + /> + ), + onClick: () => handleUpdateRating(4), + }, + { + id: 'fiveStar', + label: ( + <Rating + readOnly + value={5} + onClick={() => {}} + /> + ), + onClick: () => handleUpdateRating(5), + }, + ], + id: 'setRating', + label: 'Set rating', + leftIcon: <RiStarFill size="1.1rem" />, + onClick: () => {}, + rightIcon: <RiArrowRightSFill size="1.2rem" />, + }, + }; + }, [ + handleAddToFavorites, + handleAddToPlaylist, + handleDeselectAll, + handleMoveToBottom, + handleMoveToTop, + handlePlay, + handleRemoveFromFavorites, + handleRemoveFromPlaylist, + handleRemoveSelected, + handleUpdateRating, + openDeletePlaylistModal, + ]); + + const mergedRef = useMergedRef(ref, clickOutsideRef); + + return ( + <ContextMenuContext.Provider + value={{ + closeContextMenu, + openContextMenu, + }} + > + <Portal> + <AnimatePresence> + {opened && ( + <ContextMenu + ref={mergedRef} + minWidth={125} + xPos={ctx.xPos} + yPos={ctx.yPos} + > + <Stack spacing={0}> + <Stack + spacing={0} + onClick={closeContextMenu} + > + {ctx.menuItems?.map((item) => { + return ( + <Fragment key={`context-menu-${item.id}`}> + {item.children ? ( + <HoverCard + offset={5} + position="right" + > + <HoverCard.Target> + <ContextMenuButton + disabled={item.disabled} + leftIcon={ + contextMenuItems[item.id] + .leftIcon + } + rightIcon={ + contextMenuItems[item.id] + .rightIcon + } + onClick={ + contextMenuItems[item.id] + .onClick + } + > + {contextMenuItems[item.id].label} + </ContextMenuButton> + </HoverCard.Target> + <HoverCard.Dropdown> + <Stack spacing={0}> + {contextMenuItems[ + item.id + ].children?.map((child) => ( + <ContextMenuButton + key={`sub-${child.id}`} + disabled={child.disabled} + leftIcon={child.leftIcon} + rightIcon={child.rightIcon} + onClick={child.onClick} + > + {child.label} + </ContextMenuButton> + ))} + </Stack> + </HoverCard.Dropdown> + </HoverCard> + ) : ( + <ContextMenuButton + disabled={item.disabled} + leftIcon={ + contextMenuItems[item.id].leftIcon + } + rightIcon={ + contextMenuItems[item.id].rightIcon + } + onClick={contextMenuItems[item.id].onClick} + > + {contextMenuItems[item.id].label} + </ContextMenuButton> + )} + + {item.divider && ( + <Divider + key={`context-menu-divider-${item.id}`} + color="rgb(62, 62, 62)" + size="sm" + /> + )} + </Fragment> + ); + })} + </Stack> + <Divider + color="rgb(62, 62, 62)" + size="sm" + /> + <ContextMenuButton disabled> + {ctx.data?.length} selected + </ContextMenuButton> + </Stack> + </ContextMenu> + )} + </AnimatePresence> + {children} + </Portal> + </ContextMenuContext.Provider> + ); }; diff --git a/src/renderer/features/context-menu/events.ts b/src/renderer/features/context-menu/events.ts index c4bdb3e5..3fbff9bb 100644 --- a/src/renderer/features/context-menu/events.ts +++ b/src/renderer/features/context-menu/events.ts @@ -3,47 +3,47 @@ import { createUseExternalEvents } from '@mantine/utils'; import { LibraryItem } from '/@/renderer/api/types'; export type OpenContextMenuProps = { - context?: any; - data: any[]; - dataNodes?: RowNode[]; - menuItems: SetContextMenuItems; - tableApi?: GridOptions['api']; - type: LibraryItem; - xPos: number; - yPos: number; + context?: any; + data: any[]; + dataNodes?: RowNode[]; + menuItems: SetContextMenuItems; + tableApi?: GridOptions['api']; + type: LibraryItem; + xPos: number; + yPos: number; }; export type ContextMenuEvents = { - closeContextMenu: () => void; - openContextMenu: (args: OpenContextMenuProps) => void; + closeContextMenu: () => void; + openContextMenu: (args: OpenContextMenuProps) => void; }; export type ContextMenuItemType = - | 'play' - | 'playLast' - | 'playNext' - | 'addToPlaylist' - | 'removeFromPlaylist' - | 'addToFavorites' - | 'removeFromFavorites' - | 'setRating' - | 'deletePlaylist' - | 'createPlaylist' - | 'moveToBottomOfQueue' - | 'moveToTopOfQueue' - | 'removeFromQueue' - | 'deselectAll'; + | 'play' + | 'playLast' + | 'playNext' + | 'addToPlaylist' + | 'removeFromPlaylist' + | 'addToFavorites' + | 'removeFromFavorites' + | 'setRating' + | 'deletePlaylist' + | 'createPlaylist' + | 'moveToBottomOfQueue' + | 'moveToTopOfQueue' + | 'removeFromQueue' + | 'deselectAll'; export type SetContextMenuItems = { - children?: boolean; - disabled?: boolean; - divider?: boolean; - id: ContextMenuItemType; - onClick?: () => void; + children?: boolean; + disabled?: boolean; + divider?: boolean; + id: ContextMenuItemType; + onClick?: () => void; }[]; export const [useContextMenuEvents, createEvent] = - createUseExternalEvents<ContextMenuEvents>('context-menu'); + createUseExternalEvents<ContextMenuEvents>('context-menu'); export const openContextMenu = createEvent('openContextMenu'); export const closeContextMenu = createEvent('closeContextMenu'); diff --git a/src/renderer/features/context-menu/hooks/use-handle-context-menu.ts b/src/renderer/features/context-menu/hooks/use-handle-context-menu.ts index 17b66fd8..38478da7 100644 --- a/src/renderer/features/context-menu/hooks/use-handle-context-menu.ts +++ b/src/renderer/features/context-menu/hooks/use-handle-context-menu.ts @@ -4,69 +4,71 @@ import { Album, AlbumArtist, Artist, LibraryItem, QueueSong, Song } from '/@/ren import { openContextMenu, SetContextMenuItems } from '/@/renderer/features/context-menu/events'; export const useHandleTableContextMenu = ( - itemType: LibraryItem, - contextMenuItems: SetContextMenuItems, - context?: any, + itemType: LibraryItem, + contextMenuItems: SetContextMenuItems, + context?: any, ) => { - const handleContextMenu = (e: CellContextMenuEvent) => { - if (!e.event) return; - const clickEvent = e.event as MouseEvent; - clickEvent.preventDefault(); + const handleContextMenu = (e: CellContextMenuEvent) => { + if (!e.event) return; + const clickEvent = e.event as MouseEvent; + clickEvent.preventDefault(); - let selectedNodes = sortBy(e.api.getSelectedNodes(), ['rowIndex']); - let selectedRows = selectedNodes.map((node) => node.data); + let selectedNodes = sortBy(e.api.getSelectedNodes(), ['rowIndex']); + let selectedRows = selectedNodes.map((node) => node.data); - if (!e.data?.id) { - return; - } + if (!e.data?.id) { + return; + } - const shouldReplaceSelected = !selectedNodes.map((node) => node.data.id).includes(e.data.id); + const shouldReplaceSelected = !selectedNodes + .map((node) => node.data.id) + .includes(e.data.id); - if (shouldReplaceSelected) { - e.api.deselectAll(); - e.node.setSelected(true); - selectedRows = [e.data]; - selectedNodes = e.api.getSelectedNodes(); - } + if (shouldReplaceSelected) { + e.api.deselectAll(); + e.node.setSelected(true); + selectedRows = [e.data]; + selectedNodes = e.api.getSelectedNodes(); + } - openContextMenu({ - context, - data: selectedRows, - dataNodes: selectedNodes, - menuItems: contextMenuItems, - tableApi: e.api, - type: itemType, - xPos: clickEvent.clientX, - yPos: clickEvent.clientY, - }); - }; + openContextMenu({ + context, + data: selectedRows, + dataNodes: selectedNodes, + menuItems: contextMenuItems, + tableApi: e.api, + type: itemType, + xPos: clickEvent.clientX, + yPos: clickEvent.clientY, + }); + }; - return handleContextMenu; + return handleContextMenu; }; export const useHandleGeneralContextMenu = ( - itemType: LibraryItem, - contextMenuItems: SetContextMenuItems, - context?: any, + itemType: LibraryItem, + contextMenuItems: SetContextMenuItems, + context?: any, ) => { - const handleContextMenu = ( - e: any, - data: Song[] | QueueSong[] | AlbumArtist[] | Artist[] | Album[], - ) => { - if (!e) return; - const clickEvent = e as MouseEvent; - clickEvent.preventDefault(); + const handleContextMenu = ( + e: any, + data: Song[] | QueueSong[] | AlbumArtist[] | Artist[] | Album[], + ) => { + if (!e) return; + const clickEvent = e as MouseEvent; + clickEvent.preventDefault(); - openContextMenu({ - context, - data, - dataNodes: undefined, - menuItems: contextMenuItems, - type: itemType, - xPos: clickEvent.clientX + 15, - yPos: clickEvent.clientY + 5, - }); - }; + openContextMenu({ + context, + data, + dataNodes: undefined, + menuItems: contextMenuItems, + type: itemType, + xPos: clickEvent.clientX + 15, + yPos: clickEvent.clientY + 5, + }); + }; - return handleContextMenu; + return handleContextMenu; }; diff --git a/src/renderer/features/genres/queries/genre-list-query.ts b/src/renderer/features/genres/queries/genre-list-query.ts index 317e6bff..5b8b1b9e 100644 --- a/src/renderer/features/genres/queries/genre-list-query.ts +++ b/src/renderer/features/genres/queries/genre-list-query.ts @@ -6,18 +6,18 @@ import type { QueryHookArgs } from '/@/renderer/lib/react-query'; import { getServerById } from '/@/renderer/store'; export const useGenreList = (args: QueryHookArgs<GenreListQuery>) => { - const { options, query, serverId } = args || {}; - const server = getServerById(serverId); + const { options, query, serverId } = args || {}; + const server = getServerById(serverId); - return useQuery({ - cacheTime: 1000 * 60 * 60 * 2, - enabled: !!server, - queryFn: ({ signal }) => { - if (!server) throw new Error('Server not found'); - return controller.getGenreList({ apiClientProps: { server, signal }, query }); - }, - queryKey: queryKeys.genres.list(server?.id || ''), - staleTime: 1000 * 60 * 60, - ...options, - }); + return useQuery({ + cacheTime: 1000 * 60 * 60 * 2, + enabled: !!server, + queryFn: ({ signal }) => { + if (!server) throw new Error('Server not found'); + return controller.getGenreList({ apiClientProps: { server, signal }, query }); + }, + queryKey: queryKeys.genres.list(server?.id || ''), + staleTime: 1000 * 60 * 60, + ...options, + }); }; diff --git a/src/renderer/features/home/queries/recently-played-query.ts b/src/renderer/features/home/queries/recently-played-query.ts index 2e91454b..6e4bd565 100644 --- a/src/renderer/features/home/queries/recently-played-query.ts +++ b/src/renderer/features/home/queries/recently-played-query.ts @@ -6,31 +6,31 @@ import { getServerById } from '/@/renderer/store'; import { QueryHookArgs } from '/@/renderer/lib/react-query'; export const useRecentlyPlayed = (args: QueryHookArgs<Partial<AlbumListQuery>>) => { - const { options, query, serverId } = args; - const server = getServerById(serverId); + const { options, query, serverId } = args; + const server = getServerById(serverId); - const requestQuery: AlbumListQuery = { - limit: 5, - sortBy: AlbumListSort.RECENTLY_PLAYED, - sortOrder: SortOrder.ASC, - startIndex: 0, - ...query, - }; + const requestQuery: AlbumListQuery = { + limit: 5, + sortBy: AlbumListSort.RECENTLY_PLAYED, + sortOrder: SortOrder.ASC, + startIndex: 0, + ...query, + }; - return useQuery({ - enabled: !!server?.id, - queryFn: ({ signal }) => { - if (!server) throw new Error('Server not found'); - return api.controller.getAlbumList({ - apiClientProps: { - server, - signal, + return useQuery({ + enabled: !!server?.id, + queryFn: ({ signal }) => { + if (!server) throw new Error('Server not found'); + return api.controller.getAlbumList({ + apiClientProps: { + server, + signal, + }, + query: requestQuery, + }); }, - query: requestQuery, - }); - }, - queryKey: queryKeys.albums.list(server?.id || '', requestQuery), - ...options, - }); + queryKey: queryKeys.albums.list(server?.id || '', requestQuery), + ...options, + }); }; diff --git a/src/renderer/features/home/routes/home-route.tsx b/src/renderer/features/home/routes/home-route.tsx index f3462516..00b1a3d6 100644 --- a/src/renderer/features/home/routes/home-route.tsx +++ b/src/renderer/features/home/routes/home-route.tsx @@ -11,186 +11,191 @@ import { SwiperGridCarousel } from '/@/renderer/components/grid-carousel'; import { Platform } from '/@/renderer/types'; const HomeRoute = () => { - const scrollAreaRef = useRef<HTMLDivElement>(null); - const server = useCurrentServer(); - const itemsPerPage = 15; - const { windowBarStyle } = useWindowSettings(); + const scrollAreaRef = useRef<HTMLDivElement>(null); + const server = useCurrentServer(); + const itemsPerPage = 15; + const { windowBarStyle } = useWindowSettings(); - const feature = useAlbumList({ - options: { - cacheTime: 1000 * 60, - staleTime: 1000 * 60, - }, - query: { - limit: 20, - sortBy: AlbumListSort.RANDOM, - sortOrder: SortOrder.DESC, - startIndex: 0, - }, - serverId: server?.id, - }); + const feature = useAlbumList({ + options: { + cacheTime: 1000 * 60, + staleTime: 1000 * 60, + }, + query: { + limit: 20, + sortBy: AlbumListSort.RANDOM, + sortOrder: SortOrder.DESC, + startIndex: 0, + }, + serverId: server?.id, + }); - const featureItemsWithImage = useMemo(() => { - return feature.data?.items?.filter((item) => item.imageUrl) ?? []; - }, [feature.data?.items]); + const featureItemsWithImage = useMemo(() => { + return feature.data?.items?.filter((item) => item.imageUrl) ?? []; + }, [feature.data?.items]); - const random = useAlbumList({ - options: { - staleTime: 1000 * 60 * 5, - }, - query: { - limit: itemsPerPage, - sortBy: AlbumListSort.RANDOM, - sortOrder: SortOrder.ASC, - startIndex: 0, - }, - serverId: server?.id, - }); + const random = useAlbumList({ + options: { + staleTime: 1000 * 60 * 5, + }, + query: { + limit: itemsPerPage, + sortBy: AlbumListSort.RANDOM, + sortOrder: SortOrder.ASC, + startIndex: 0, + }, + serverId: server?.id, + }); - const recentlyPlayed = useRecentlyPlayed({ - options: { - staleTime: 0, - }, - query: { - limit: itemsPerPage, - sortBy: AlbumListSort.RECENTLY_PLAYED, - sortOrder: SortOrder.DESC, - startIndex: 0, - }, - serverId: server?.id, - }); + const recentlyPlayed = useRecentlyPlayed({ + options: { + staleTime: 0, + }, + query: { + limit: itemsPerPage, + sortBy: AlbumListSort.RECENTLY_PLAYED, + sortOrder: SortOrder.DESC, + startIndex: 0, + }, + serverId: server?.id, + }); - const recentlyAdded = useAlbumList({ - options: { - staleTime: 0, - }, - query: { - limit: itemsPerPage, - sortBy: AlbumListSort.RECENTLY_ADDED, - sortOrder: SortOrder.DESC, - startIndex: 0, - }, - serverId: server?.id, - }); + const recentlyAdded = useAlbumList({ + options: { + staleTime: 0, + }, + query: { + limit: itemsPerPage, + sortBy: AlbumListSort.RECENTLY_ADDED, + sortOrder: SortOrder.DESC, + startIndex: 0, + }, + serverId: server?.id, + }); - const mostPlayed = useAlbumList({ - options: { - staleTime: 0, - }, - query: { - limit: itemsPerPage, - sortBy: AlbumListSort.PLAY_COUNT, - sortOrder: SortOrder.DESC, - startIndex: 0, - }, - serverId: server?.id, - }); + const mostPlayed = useAlbumList({ + options: { + staleTime: 0, + }, + query: { + limit: itemsPerPage, + sortBy: AlbumListSort.PLAY_COUNT, + sortOrder: SortOrder.DESC, + startIndex: 0, + }, + serverId: server?.id, + }); - const isLoading = - random.isFetching || - recentlyPlayed.isFetching || - recentlyAdded.isFetching || - mostPlayed.isFetching; + const isLoading = + random.isFetching || + recentlyPlayed.isFetching || + recentlyAdded.isFetching || + mostPlayed.isFetching; - if (isLoading) { - return <Spinner container />; - } + if (isLoading) { + return <Spinner container />; + } - const carousels = [ - { - data: random?.data?.items, - title: 'Explore from your library', - uniqueId: 'random', - }, - { - data: recentlyPlayed?.data?.items, - pagination: { - itemsPerPage, - }, - title: 'Recently played', - uniqueId: 'recentlyPlayed', - }, - { - data: recentlyAdded?.data?.items, - pagination: { - itemsPerPage, - }, - title: 'Newly added releases', - uniqueId: 'recentlyAdded', - }, - { - data: mostPlayed?.data?.items, - pagination: { - itemsPerPage, - }, - title: 'Most played', - uniqueId: 'mostPlayed', - }, - ]; + const carousels = [ + { + data: random?.data?.items, + title: 'Explore from your library', + uniqueId: 'random', + }, + { + data: recentlyPlayed?.data?.items, + pagination: { + itemsPerPage, + }, + title: 'Recently played', + uniqueId: 'recentlyPlayed', + }, + { + data: recentlyAdded?.data?.items, + pagination: { + itemsPerPage, + }, + title: 'Newly added releases', + uniqueId: 'recentlyAdded', + }, + { + data: mostPlayed?.data?.items, + pagination: { + itemsPerPage, + }, + title: 'Most played', + uniqueId: 'mostPlayed', + }, + ]; - return ( - <AnimatedPage> - <NativeScrollArea - ref={scrollAreaRef} - pageHeaderProps={{ - backgroundColor: 'var(--titlebar-bg)', - children: ( - <LibraryHeaderBar> - <LibraryHeaderBar.Title>Home</LibraryHeaderBar.Title> - </LibraryHeaderBar> - ), - offset: ['0px', '200px'], - }} - > - <Stack - mb="5rem" - pt={windowBarStyle === Platform.WEB ? '5rem' : '3rem'} - px="2rem" - spacing="lg" - > - <FeatureCarousel data={featureItemsWithImage} /> - {carousels - .filter((carousel) => { - if (server?.type === ServerType.JELLYFIN && carousel.uniqueId === 'recentlyPlayed') { - return null; - } - - return carousel; - }) - .map((carousel) => ( - <SwiperGridCarousel - key={`carousel-${carousel.uniqueId}`} - cardRows={[ - { - property: 'name', - route: { - route: AppRoute.LIBRARY_ALBUMS_DETAIL, - slugs: [{ idProperty: 'id', slugProperty: 'albumId' }], - }, - }, - { - arrayProperty: 'name', - property: 'albumArtists', - route: { - route: AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, - slugs: [{ idProperty: 'id', slugProperty: 'albumArtistId' }], - }, - }, - ]} - data={carousel.data} - itemType={LibraryItem.ALBUM} - route={{ - route: AppRoute.LIBRARY_ALBUMS_DETAIL, - slugs: [{ idProperty: 'id', slugProperty: 'albumId' }], + return ( + <AnimatedPage> + <NativeScrollArea + ref={scrollAreaRef} + pageHeaderProps={{ + backgroundColor: 'var(--titlebar-bg)', + children: ( + <LibraryHeaderBar> + <LibraryHeaderBar.Title>Home</LibraryHeaderBar.Title> + </LibraryHeaderBar> + ), + offset: ['0px', '200px'], }} - title={{ label: carousel.title }} - uniqueId={carousel.uniqueId} - /> - ))} - </Stack> - </NativeScrollArea> - </AnimatedPage> - ); + > + <Stack + mb="5rem" + pt={windowBarStyle === Platform.WEB ? '5rem' : '3rem'} + px="2rem" + spacing="lg" + > + <FeatureCarousel data={featureItemsWithImage} /> + {carousels + .filter((carousel) => { + if ( + server?.type === ServerType.JELLYFIN && + carousel.uniqueId === 'recentlyPlayed' + ) { + return null; + } + + return carousel; + }) + .map((carousel) => ( + <SwiperGridCarousel + key={`carousel-${carousel.uniqueId}`} + cardRows={[ + { + property: 'name', + route: { + route: AppRoute.LIBRARY_ALBUMS_DETAIL, + slugs: [{ idProperty: 'id', slugProperty: 'albumId' }], + }, + }, + { + arrayProperty: 'name', + property: 'albumArtists', + route: { + route: AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, + slugs: [ + { idProperty: 'id', slugProperty: 'albumArtistId' }, + ], + }, + }, + ]} + data={carousel.data} + itemType={LibraryItem.ALBUM} + route={{ + route: AppRoute.LIBRARY_ALBUMS_DETAIL, + slugs: [{ idProperty: 'id', slugProperty: 'albumId' }], + }} + title={{ label: carousel.title }} + uniqueId={carousel.uniqueId} + /> + ))} + </Stack> + </NativeScrollArea> + </AnimatedPage> + ); }; export default HomeRoute; diff --git a/src/renderer/features/lyrics/components/lyrics-search-form.tsx b/src/renderer/features/lyrics/components/lyrics-search-form.tsx index effe6a2b..ac979338 100644 --- a/src/renderer/features/lyrics/components/lyrics-search-form.tsx +++ b/src/renderer/features/lyrics/components/lyrics-search-form.tsx @@ -6,170 +6,170 @@ import { openModal } from '@mantine/modals'; import orderBy from 'lodash/orderBy'; import styled from 'styled-components'; import { - InternetProviderLyricSearchResponse, - LyricSource, - LyricsOverride, + InternetProviderLyricSearchResponse, + LyricSource, + LyricsOverride, } from '../../../api/types'; import { useLyricSearch } from '../queries/lyric-search-query'; import { ScrollArea, Spinner, Text, TextInput } from '/@/renderer/components'; const SearchItem = styled.button` - all: unset; - box-sizing: border-box !important; - padding: 0.5rem; - border-radius: 5px; - cursor: pointer; + all: unset; + box-sizing: border-box !important; + padding: 0.5rem; + border-radius: 5px; + cursor: pointer; - &:hover, - &:focus-visible { - color: var(--btn-default-fg-hover); - background: var(--btn-default-bg-hover); - } + &:hover, + &:focus-visible { + color: var(--btn-default-fg-hover); + background: var(--btn-default-bg-hover); + } `; interface SearchResultProps { - data: InternetProviderLyricSearchResponse; - onClick?: () => void; + data: InternetProviderLyricSearchResponse; + onClick?: () => void; } const SearchResult = ({ data, onClick }: SearchResultProps) => { - const { artist, name, source, score, id } = data; + const { artist, name, source, score, id } = data; - const percentageScore = useMemo(() => { - if (!score) return 0; - return ((1 - score) * 100).toFixed(2); - }, [score]); + const percentageScore = useMemo(() => { + if (!score) return 0; + return ((1 - score) * 100).toFixed(2); + }, [score]); - const cleanId = - source === LyricSource.GENIUS ? id.replace(/^((http[s]?|ftp):\/)?\/?([^:/\s]+)/g, '') : id; + const cleanId = + source === LyricSource.GENIUS ? id.replace(/^((http[s]?|ftp):\/)?\/?([^:/\s]+)/g, '') : id; - return ( - <SearchItem onClick={onClick}> - <Group - noWrap - position="apart" - > - <Stack - maw="65%" - spacing={0} - > - <Text - size="md" - weight={600} - > - {name} - </Text> - <Text $secondary>{artist}</Text> - <Group - noWrap - spacing="sm" - > - <Text - $secondary - size="sm" + return ( + <SearchItem onClick={onClick}> + <Group + noWrap + position="apart" > - {[source, cleanId].join(' — ')} - </Text> - </Group> - </Stack> - <Text>{percentageScore}%</Text> - </Group> - </SearchItem> - ); + <Stack + maw="65%" + spacing={0} + > + <Text + size="md" + weight={600} + > + {name} + </Text> + <Text $secondary>{artist}</Text> + <Group + noWrap + spacing="sm" + > + <Text + $secondary + size="sm" + > + {[source, cleanId].join(' — ')} + </Text> + </Group> + </Stack> + <Text>{percentageScore}%</Text> + </Group> + </SearchItem> + ); }; interface LyricSearchFormProps { - artist?: string; - name?: string; - onSearchOverride?: (params: LyricsOverride) => void; + artist?: string; + name?: string; + onSearchOverride?: (params: LyricsOverride) => void; } export const LyricsSearchForm = ({ artist, name, onSearchOverride }: LyricSearchFormProps) => { - const form = useForm({ - initialValues: { - artist: artist || '', - name: name || '', - }, - }); - - const [debouncedArtist] = useDebouncedValue(form.values.artist, 500); - const [debouncedName] = useDebouncedValue(form.values.name, 500); - - const { data, isInitialLoading } = useLyricSearch({ - query: { artist: debouncedArtist, name: debouncedName }, - }); - - const searchResults = useMemo(() => { - if (!data) return []; - - const results: InternetProviderLyricSearchResponse[] = []; - Object.keys(data).forEach((key) => { - (data[key as keyof typeof data] || []).forEach((result) => results.push(result)); + const form = useForm({ + initialValues: { + artist: artist || '', + name: name || '', + }, }); - const scoredResults = orderBy(results, ['score'], ['asc']); + const [debouncedArtist] = useDebouncedValue(form.values.artist, 500); + const [debouncedName] = useDebouncedValue(form.values.name, 500); - return scoredResults; - }, [data]); + const { data, isInitialLoading } = useLyricSearch({ + query: { artist: debouncedArtist, name: debouncedName }, + }); - return ( - <Stack w="100%"> - <form> - <Group grow> - <TextInput - data-autofocus - label="Name" - {...form.getInputProps('name')} - /> - <TextInput - label="Artist" - {...form.getInputProps('artist')} - /> - </Group> - </form> - <Divider /> - {isInitialLoading ? ( - <Spinner container /> - ) : ( - <ScrollArea - offsetScrollbars - h={400} - pr="1rem" - type="auto" - w="100%" - > - <Stack spacing="md"> - {searchResults.map((result) => ( - <SearchResult - key={`${result.source}-${result.id}`} - data={result} - onClick={() => { - onSearchOverride?.({ - artist: result.artist, - id: result.id, - name: result.name, - remote: true, - source: result.source as LyricSource, - }); - }} - /> - ))} - </Stack> - </ScrollArea> - )} - </Stack> - ); + const searchResults = useMemo(() => { + if (!data) return []; + + const results: InternetProviderLyricSearchResponse[] = []; + Object.keys(data).forEach((key) => { + (data[key as keyof typeof data] || []).forEach((result) => results.push(result)); + }); + + const scoredResults = orderBy(results, ['score'], ['asc']); + + return scoredResults; + }, [data]); + + return ( + <Stack w="100%"> + <form> + <Group grow> + <TextInput + data-autofocus + label="Name" + {...form.getInputProps('name')} + /> + <TextInput + label="Artist" + {...form.getInputProps('artist')} + /> + </Group> + </form> + <Divider /> + {isInitialLoading ? ( + <Spinner container /> + ) : ( + <ScrollArea + offsetScrollbars + h={400} + pr="1rem" + type="auto" + w="100%" + > + <Stack spacing="md"> + {searchResults.map((result) => ( + <SearchResult + key={`${result.source}-${result.id}`} + data={result} + onClick={() => { + onSearchOverride?.({ + artist: result.artist, + id: result.id, + name: result.name, + remote: true, + source: result.source as LyricSource, + }); + }} + /> + ))} + </Stack> + </ScrollArea> + )} + </Stack> + ); }; export const openLyricSearchModal = ({ artist, name, onSearchOverride }: LyricSearchFormProps) => { - openModal({ - children: ( - <LyricsSearchForm - artist={artist} - name={name} - onSearchOverride={onSearchOverride} - /> - ), - size: 'lg', - title: 'Lyrics Search', - }); + openModal({ + children: ( + <LyricsSearchForm + artist={artist} + name={name} + onSearchOverride={onSearchOverride} + /> + ), + size: 'lg', + title: 'Lyrics Search', + }); }; diff --git a/src/renderer/features/lyrics/lyric-line.tsx b/src/renderer/features/lyrics/lyric-line.tsx index 7b592f0a..18dad99d 100644 --- a/src/renderer/features/lyrics/lyric-line.tsx +++ b/src/renderer/features/lyrics/lyric-line.tsx @@ -3,29 +3,29 @@ import { TextTitle } from '/@/renderer/components/text-title'; import styled from 'styled-components'; interface LyricLineProps extends ComponentPropsWithoutRef<'div'> { - text: string; + text: string; } const StyledText = styled(TextTitle)` - color: var(--main-fg); - font-weight: 400; - font-size: 2.5vmax; - transform: scale(0.95); - opacity: 0.5; + color: var(--main-fg); + font-weight: 400; + font-size: 2.5vmax; + transform: scale(0.95); + opacity: 0.5; - &.active { - font-weight: 800; - transform: scale(1); - opacity: 1; - } + &.active { + font-weight: 800; + transform: scale(1); + opacity: 1; + } - &.active.unsynchronized { - opacity: 0.8; - } + &.active.unsynchronized { + opacity: 0.8; + } - transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out; + transition: opacity 0.3s ease-in-out, transform 0.3s ease-in-out; `; export const LyricLine = ({ text, ...props }: LyricLineProps) => { - return <StyledText {...props}>{text}</StyledText>; + return <StyledText {...props}>{text}</StyledText>; }; diff --git a/src/renderer/features/lyrics/lyrics-actions.tsx b/src/renderer/features/lyrics/lyrics-actions.tsx index 5b28397c..8e4fa9b7 100644 --- a/src/renderer/features/lyrics/lyrics-actions.tsx +++ b/src/renderer/features/lyrics/lyrics-actions.tsx @@ -4,88 +4,88 @@ import { LyricsOverride } from '/@/renderer/api/types'; import { Button, NumberInput, Tooltip } from '/@/renderer/components'; import { openLyricSearchModal } from '/@/renderer/features/lyrics/components/lyrics-search-form'; import { - useCurrentSong, - useLyricsSettings, - useSettingsStore, - useSettingsStoreActions, + useCurrentSong, + useLyricsSettings, + useSettingsStore, + useSettingsStoreActions, } from '/@/renderer/store'; interface LyricsActionsProps { - onRemoveLyric: () => void; - onSearchOverride: (params: LyricsOverride) => void; + onRemoveLyric: () => void; + onSearchOverride: (params: LyricsOverride) => void; } export const LyricsActions = ({ onRemoveLyric, onSearchOverride }: LyricsActionsProps) => { - const currentSong = useCurrentSong(); - const { setSettings } = useSettingsStoreActions(); - const { delayMs, sources } = useLyricsSettings(); + const currentSong = useCurrentSong(); + const { setSettings } = useSettingsStoreActions(); + const { delayMs, sources } = useLyricsSettings(); - const handleLyricOffset = (e: number) => { - setSettings({ - lyrics: { - ...useSettingsStore.getState().lyrics, - delayMs: e, - }, - }); - }; + const handleLyricOffset = (e: number) => { + setSettings({ + lyrics: { + ...useSettingsStore.getState().lyrics, + delayMs: e, + }, + }); + }; - const isActionsDisabled = !currentSong; - const isDesktop = isElectron(); + const isActionsDisabled = !currentSong; + const isDesktop = isElectron(); - return ( - <> - {isDesktop && sources.length ? ( - <Button - uppercase - disabled={isActionsDisabled} - variant="subtle" - onClick={() => - openLyricSearchModal({ - artist: currentSong?.artistName, - name: currentSong?.name, - onSearchOverride, - }) - } - > - Search - </Button> - ) : null} - <Button - aria-label="Decrease lyric offset" - variant="subtle" - onClick={() => handleLyricOffset(delayMs - 50)} - > - <RiSubtractFill /> - </Button> - <Tooltip - label="Offset (ms)" - openDelay={500} - > - <NumberInput - aria-label="Lyric offset" - styles={{ input: { textAlign: 'center' } }} - value={delayMs || 0} - width={55} - onChange={handleLyricOffset} - /> - </Tooltip> - <Button - aria-label="Increase lyric offset" - variant="subtle" - onClick={() => handleLyricOffset(delayMs + 50)} - > - <RiAddFill /> - </Button> - {isDesktop && sources.length ? ( - <Button - uppercase - disabled={isActionsDisabled} - variant="subtle" - onClick={onRemoveLyric} - > - Clear - </Button> - ) : null} - </> - ); + return ( + <> + {isDesktop && sources.length ? ( + <Button + uppercase + disabled={isActionsDisabled} + variant="subtle" + onClick={() => + openLyricSearchModal({ + artist: currentSong?.artistName, + name: currentSong?.name, + onSearchOverride, + }) + } + > + Search + </Button> + ) : null} + <Button + aria-label="Decrease lyric offset" + variant="subtle" + onClick={() => handleLyricOffset(delayMs - 50)} + > + <RiSubtractFill /> + </Button> + <Tooltip + label="Offset (ms)" + openDelay={500} + > + <NumberInput + aria-label="Lyric offset" + styles={{ input: { textAlign: 'center' } }} + value={delayMs || 0} + width={55} + onChange={handleLyricOffset} + /> + </Tooltip> + <Button + aria-label="Increase lyric offset" + variant="subtle" + onClick={() => handleLyricOffset(delayMs + 50)} + > + <RiAddFill /> + </Button> + {isDesktop && sources.length ? ( + <Button + uppercase + disabled={isActionsDisabled} + variant="subtle" + onClick={onRemoveLyric} + > + Clear + </Button> + ) : null} + </> + ); }; diff --git a/src/renderer/features/lyrics/lyrics.tsx b/src/renderer/features/lyrics/lyrics.tsx index b09ace89..1ccf6d1f 100644 --- a/src/renderer/features/lyrics/lyrics.tsx +++ b/src/renderer/features/lyrics/lyrics.tsx @@ -11,196 +11,198 @@ import { ErrorFallback } from '/@/renderer/features/action-required'; import { UnsynchronizedLyrics } from '/@/renderer/features/lyrics/unsynchronized-lyrics'; import { getServerById, useCurrentSong, usePlayerStore } from '/@/renderer/store'; import { - FullLyricsMetadata, - LyricsOverride, - SynchronizedLyricMetadata, - UnsynchronizedLyricMetadata, + FullLyricsMetadata, + LyricsOverride, + SynchronizedLyricMetadata, + UnsynchronizedLyricMetadata, } from '/@/renderer/api/types'; import { LyricsActions } from '/@/renderer/features/lyrics/lyrics-actions'; const ActionsContainer = styled.div` - position: absolute; - bottom: 0; - left: 0; - z-index: 50; - display: flex; - gap: 0.5rem; - align-items: center; - justify-content: center; - width: 100%; - opacity: 0; - transition: opacity 0.2s ease-in-out; + position: absolute; + bottom: 0; + left: 0; + z-index: 50; + display: flex; + gap: 0.5rem; + align-items: center; + justify-content: center; + width: 100%; + opacity: 0; + transition: opacity 0.2s ease-in-out; - &:hover { - opacity: 1 !important; - } + &:hover { + opacity: 1 !important; + } - &:focus-within { - opacity: 1 !important; - } + &:focus-within { + opacity: 1 !important; + } `; const LyricsContainer = styled.div` - position: relative; - display: flex; - width: 100%; - height: 100%; + position: relative; + display: flex; + width: 100%; + height: 100%; - &:hover { - ${ActionsContainer} { - opacity: 0.6; + &:hover { + ${ActionsContainer} { + opacity: 0.6; + } } - } `; const ScrollContainer = styled(motion.div)` - position: relative; - z-index: 1; - width: 100%; - height: 100%; - text-align: center; - - mask-image: linear-gradient( - 180deg, - transparent 5%, - rgba(0, 0, 0, 100%) 20%, - rgba(0, 0, 0, 100%) 85%, - transparent 95% - ); - - &.mantine-ScrollArea-root { + position: relative; + z-index: 1; width: 100%; height: 100%; - } + text-align: center; - & .mantine-ScrollArea-viewport { - height: 100% !important; - } + mask-image: linear-gradient( + 180deg, + transparent 5%, + rgba(0, 0, 0, 100%) 20%, + rgba(0, 0, 0, 100%) 85%, + transparent 95% + ); - & .mantine-ScrollArea-viewport > div { - height: 100%; - } + &.mantine-ScrollArea-root { + width: 100%; + height: 100%; + } + + & .mantine-ScrollArea-viewport { + height: 100% !important; + } + + & .mantine-ScrollArea-viewport > div { + height: 100%; + } `; function isSynchronized( - data: Partial<FullLyricsMetadata> | undefined, + data: Partial<FullLyricsMetadata> | undefined, ): data is SynchronizedLyricMetadata { - // Type magic. The only difference between Synchronized and Unsynchhronized is - // the datatype of lyrics. This makes Typescript happier later... - if (!data) return false; - return Array.isArray(data.lyrics); + // Type magic. The only difference between Synchronized and Unsynchhronized is + // the datatype of lyrics. This makes Typescript happier later... + if (!data) return false; + return Array.isArray(data.lyrics); } export const Lyrics = () => { - const currentSong = useCurrentSong(); - const currentServer = getServerById(currentSong?.serverId); + const currentSong = useCurrentSong(); + const currentServer = getServerById(currentSong?.serverId); - const [clear, setClear] = useState(false); + const [clear, setClear] = useState(false); - const { data, isInitialLoading } = useSongLyricsBySong( - { - query: { songId: currentSong?.id || '' }, - serverId: currentServer?.id, - }, - currentSong, - ); - - const [override, setOverride] = useState<LyricsOverride | undefined>(undefined); - - const handleOnSearchOverride = useCallback((params: LyricsOverride) => { - setOverride(params); - setClear(false); - }, []); - - const { data: overrideLyrics, isInitialLoading: isOverrideLoading } = useSongLyricsByRemoteId({ - options: { - enabled: !!override, - }, - query: { - remoteSongId: override?.id, - remoteSource: override?.source, - }, - serverId: currentServer?.id, - }); - - useEffect(() => { - const unsubSongChange = usePlayerStore.subscribe( - (state) => state.current.song, - () => { - setOverride(undefined); - setClear(false); - }, - { equalityFn: (a, b) => a?.id === b?.id }, + const { data, isInitialLoading } = useSongLyricsBySong( + { + query: { songId: currentSong?.id || '' }, + serverId: currentServer?.id, + }, + currentSong, ); - return () => { - unsubSongChange(); - }; - }, []); + const [override, setOverride] = useState<LyricsOverride | undefined>(undefined); - const isLoadingLyrics = isInitialLoading || isOverrideLoading; + const handleOnSearchOverride = useCallback((params: LyricsOverride) => { + setOverride(params); + setClear(false); + }, []); - const hasNoLyrics = (!data?.lyrics && !overrideLyrics) || clear; + const { data: overrideLyrics, isInitialLoading: isOverrideLoading } = useSongLyricsByRemoteId({ + options: { + enabled: !!override, + }, + query: { + remoteSongId: override?.id, + remoteSource: override?.source, + }, + serverId: currentServer?.id, + }); - const lyricsMetadata: - | Partial<SynchronizedLyricMetadata> - | Partial<UnsynchronizedLyricMetadata> - | undefined = overrideLyrics - ? { - artist: override?.artist, - lyrics: overrideLyrics, - name: override?.name, - remote: true, - source: override?.source, - } - : data; + useEffect(() => { + const unsubSongChange = usePlayerStore.subscribe( + (state) => state.current.song, + () => { + setOverride(undefined); + setClear(false); + }, + { equalityFn: (a, b) => a?.id === b?.id }, + ); - const isSynchronizedLyrics = isSynchronized(lyricsMetadata); + return () => { + unsubSongChange(); + }; + }, []); - return ( - <ErrorBoundary FallbackComponent={ErrorFallback}> - <LyricsContainer> - {isLoadingLyrics ? ( - <Spinner - container - size={25} - /> - ) : ( - <AnimatePresence mode="sync"> - {hasNoLyrics ? ( - <Center w="100%"> - <Group> - <RiInformationFill size="2rem" /> - <TextTitle - order={3} - weight={700} - > - No lyrics found - </TextTitle> - </Group> - </Center> - ) : ( - <ScrollContainer - animate={{ opacity: 1 }} - initial={{ opacity: 0 }} - transition={{ duration: 0.5 }} - > - {isSynchronizedLyrics ? ( - <SynchronizedLyrics {...lyricsMetadata} /> + const isLoadingLyrics = isInitialLoading || isOverrideLoading; + + const hasNoLyrics = (!data?.lyrics && !overrideLyrics) || clear; + + const lyricsMetadata: + | Partial<SynchronizedLyricMetadata> + | Partial<UnsynchronizedLyricMetadata> + | undefined = overrideLyrics + ? { + artist: override?.artist, + lyrics: overrideLyrics, + name: override?.name, + remote: true, + source: override?.source, + } + : data; + + const isSynchronizedLyrics = isSynchronized(lyricsMetadata); + + return ( + <ErrorBoundary FallbackComponent={ErrorFallback}> + <LyricsContainer> + {isLoadingLyrics ? ( + <Spinner + container + size={25} + /> ) : ( - <UnsynchronizedLyrics {...(lyricsMetadata as UnsynchronizedLyricMetadata)} /> + <AnimatePresence mode="sync"> + {hasNoLyrics ? ( + <Center w="100%"> + <Group> + <RiInformationFill size="2rem" /> + <TextTitle + order={3} + weight={700} + > + No lyrics found + </TextTitle> + </Group> + </Center> + ) : ( + <ScrollContainer + animate={{ opacity: 1 }} + initial={{ opacity: 0 }} + transition={{ duration: 0.5 }} + > + {isSynchronizedLyrics ? ( + <SynchronizedLyrics {...lyricsMetadata} /> + ) : ( + <UnsynchronizedLyrics + {...(lyricsMetadata as UnsynchronizedLyricMetadata)} + /> + )} + </ScrollContainer> + )} + </AnimatePresence> )} - </ScrollContainer> - )} - </AnimatePresence> - )} - <ActionsContainer> - <LyricsActions - onRemoveLyric={() => setClear(true)} - onSearchOverride={handleOnSearchOverride} - /> - </ActionsContainer> - </LyricsContainer> - </ErrorBoundary> - ); + <ActionsContainer> + <LyricsActions + onRemoveLyric={() => setClear(true)} + onSearchOverride={handleOnSearchOverride} + /> + </ActionsContainer> + </LyricsContainer> + </ErrorBoundary> + ); }; diff --git a/src/renderer/features/lyrics/queries/lyric-query.ts b/src/renderer/features/lyrics/queries/lyric-query.ts index 95a17dcc..fc48a396 100644 --- a/src/renderer/features/lyrics/queries/lyric-query.ts +++ b/src/renderer/features/lyrics/queries/lyric-query.ts @@ -1,11 +1,11 @@ import { UseQueryResult, useQuery } from '@tanstack/react-query'; import { - LyricsQuery, - QueueSong, - SynchronizedLyricsArray, - InternetProviderLyricResponse, - FullLyricsMetadata, - LyricGetQuery, + LyricsQuery, + QueueSong, + SynchronizedLyricsArray, + InternetProviderLyricResponse, + FullLyricsMetadata, + LyricGetQuery, } from '/@/renderer/api/types'; import { QueryHookArgs } from '/@/renderer/lib/react-query'; import { getServerById, useLyricsSettings } from '/@/renderer/store'; @@ -25,142 +25,144 @@ const timeExp = /\[(\d{2,}):(\d{2})(?:\.(\d{2,3}))?]([^\n]+)\n/g; const alternateTimeExp = /\[(\d*),(\d*)]([^\n]+)\n/g; const formatLyrics = (lyrics: string) => { - const synchronizedLines = lyrics.matchAll(timeExp); - const formattedLyrics: SynchronizedLyricsArray = []; + const synchronizedLines = lyrics.matchAll(timeExp); + const formattedLyrics: SynchronizedLyricsArray = []; - for (const line of synchronizedLines) { - const [, minute, sec, ms, text] = line; - const minutes = parseInt(minute, 10); - const seconds = parseInt(sec, 10); - const milis = ms?.length === 3 ? parseInt(ms, 10) : parseInt(ms, 10) * 10; + for (const line of synchronizedLines) { + const [, minute, sec, ms, text] = line; + const minutes = parseInt(minute, 10); + const seconds = parseInt(sec, 10); + const milis = ms?.length === 3 ? parseInt(ms, 10) : parseInt(ms, 10) * 10; - const timeInMilis = (minutes * 60 + seconds) * 1000 + milis; + const timeInMilis = (minutes * 60 + seconds) * 1000 + milis; - formattedLyrics.push([timeInMilis, text]); - } + formattedLyrics.push([timeInMilis, text]); + } - if (formattedLyrics.length > 0) return formattedLyrics; + if (formattedLyrics.length > 0) return formattedLyrics; - const alternateSynchronizedLines = lyrics.matchAll(alternateTimeExp); - for (const line of alternateSynchronizedLines) { - const [, timeInMilis, , text] = line; - const cleanText = text - .replaceAll(/\(\d+,\d+\)/g, '') - .replaceAll(/\s,/g, ',') - .replaceAll(/\s\./g, '.'); - formattedLyrics.push([Number(timeInMilis), cleanText]); - } + const alternateSynchronizedLines = lyrics.matchAll(alternateTimeExp); + for (const line of alternateSynchronizedLines) { + const [, timeInMilis, , text] = line; + const cleanText = text + .replaceAll(/\(\d+,\d+\)/g, '') + .replaceAll(/\s,/g, ',') + .replaceAll(/\s\./g, '.'); + formattedLyrics.push([Number(timeInMilis), cleanText]); + } - if (formattedLyrics.length > 0) return formattedLyrics; + if (formattedLyrics.length > 0) return formattedLyrics; - // If no synchronized lyrics were found, return the original lyrics - return lyrics; + // If no synchronized lyrics were found, return the original lyrics + return lyrics; }; export const useServerLyrics = ( - args: QueryHookArgs<LyricsQuery>, + args: QueryHookArgs<LyricsQuery>, ): UseQueryResult<string | null> => { - const { query, serverId } = args; - const server = getServerById(serverId); + const { query, serverId } = args; + const server = getServerById(serverId); - return useQuery({ - // Note: This currently fetches for every song, even if it shouldn't have - // lyrics, because for some reason HasLyrics is not exposed. Thus, ignore the error - onError: () => {}, - queryFn: ({ signal }) => { - if (!server) throw new Error('Server not found'); - // This should only be called for Jellyfin. Return null to ignore errors - if (server.type !== ServerType.JELLYFIN) return null; - return api.controller.getLyrics({ apiClientProps: { server, signal }, query }); - }, - queryKey: queryKeys.songs.lyrics(server?.id || '', query), - }); + return useQuery({ + // Note: This currently fetches for every song, even if it shouldn't have + // lyrics, because for some reason HasLyrics is not exposed. Thus, ignore the error + onError: () => {}, + queryFn: ({ signal }) => { + if (!server) throw new Error('Server not found'); + // This should only be called for Jellyfin. Return null to ignore errors + if (server.type !== ServerType.JELLYFIN) return null; + return api.controller.getLyrics({ apiClientProps: { server, signal }, query }); + }, + queryKey: queryKeys.songs.lyrics(server?.id || '', query), + }); }; export const useSongLyricsBySong = ( - args: QueryHookArgs<LyricsQuery>, - song: QueueSong | undefined, + args: QueryHookArgs<LyricsQuery>, + song: QueueSong | undefined, ): UseQueryResult<FullLyricsMetadata> => { - const { query } = args; - const { fetch } = useLyricsSettings(); - const server = getServerById(song?.serverId); + const { query } = args; + const { fetch } = useLyricsSettings(); + const server = getServerById(song?.serverId); - return useQuery({ - cacheTime: 1000 * 60 * 10, - enabled: !!song && !!server, - onError: () => {}, - queryFn: async ({ signal }) => { - if (!server) throw new Error('Server not found'); - if (!song) return null; + return useQuery({ + cacheTime: 1000 * 60 * 10, + enabled: !!song && !!server, + onError: () => {}, + queryFn: async ({ signal }) => { + if (!server) throw new Error('Server not found'); + if (!song) return null; - if (song.lyrics) { - return { - artist: song.artists?.[0]?.name, - lyrics: formatLyrics(song.lyrics), - name: song.name, - remote: false, - source: server?.name ?? 'music server', - }; - } + if (song.lyrics) { + return { + artist: song.artists?.[0]?.name, + lyrics: formatLyrics(song.lyrics), + name: song.name, + remote: false, + source: server?.name ?? 'music server', + }; + } - if (server.type === ServerType.JELLYFIN) { - const jfLyrics = await api.controller - .getLyrics({ - apiClientProps: { server, signal }, - query: { songId: song.id }, - }) - .catch((err) => console.log(err)); + if (server.type === ServerType.JELLYFIN) { + const jfLyrics = await api.controller + .getLyrics({ + apiClientProps: { server, signal }, + query: { songId: song.id }, + }) + .catch((err) => console.log(err)); - if (jfLyrics) { - return { - artist: song.artists?.[0]?.name, - lyrics: jfLyrics, - name: song.name, - remote: false, - source: server?.name ?? 'music server', - }; - } - } + if (jfLyrics) { + return { + artist: song.artists?.[0]?.name, + lyrics: jfLyrics, + name: song.name, + remote: false, + source: server?.name ?? 'music server', + }; + } + } - if (fetch) { - const remoteLyricsResult: InternetProviderLyricResponse | null = - await lyricsIpc?.getRemoteLyricsBySong(song); + if (fetch) { + const remoteLyricsResult: InternetProviderLyricResponse | null = + await lyricsIpc?.getRemoteLyricsBySong(song); - if (remoteLyricsResult) { - return { - ...remoteLyricsResult, - lyrics: formatLyrics(remoteLyricsResult.lyrics), - remote: true, - }; - } - } + if (remoteLyricsResult) { + return { + ...remoteLyricsResult, + lyrics: formatLyrics(remoteLyricsResult.lyrics), + remote: true, + }; + } + } - return null; - }, - queryKey: queryKeys.songs.lyrics(server?.id || '', query), - staleTime: 1000 * 60 * 2, - }); + return null; + }, + queryKey: queryKeys.songs.lyrics(server?.id || '', query), + staleTime: 1000 * 60 * 2, + }); }; export const useSongLyricsByRemoteId = ( - args: QueryHookArgs<Partial<LyricGetQuery>>, + args: QueryHookArgs<Partial<LyricGetQuery>>, ): UseQueryResult<string | null> => { - const { query } = args; + const { query } = args; - return useQuery({ - cacheTime: 1000 * 60 * 10, - enabled: !!query.remoteSongId && !!query.remoteSource, - onError: () => {}, - queryFn: async () => { - const remoteLyricsResult: string | null = await lyricsIpc?.getRemoteLyricsByRemoteId(query); + return useQuery({ + cacheTime: 1000 * 60 * 10, + enabled: !!query.remoteSongId && !!query.remoteSource, + onError: () => {}, + queryFn: async () => { + const remoteLyricsResult: string | null = await lyricsIpc?.getRemoteLyricsByRemoteId( + query, + ); - if (remoteLyricsResult) { - return formatLyrics(remoteLyricsResult); - } + if (remoteLyricsResult) { + return formatLyrics(remoteLyricsResult); + } - return null; - }, - queryKey: queryKeys.songs.lyricsByRemoteId(query), - staleTime: 1000 * 60 * 5, - }); + return null; + }, + queryKey: queryKeys.songs.lyricsByRemoteId(query), + staleTime: 1000 * 60 * 5, + }); }; diff --git a/src/renderer/features/lyrics/queries/lyric-search-query.ts b/src/renderer/features/lyrics/queries/lyric-search-query.ts index 19db9f02..b4e580d8 100644 --- a/src/renderer/features/lyrics/queries/lyric-search-query.ts +++ b/src/renderer/features/lyrics/queries/lyric-search-query.ts @@ -2,23 +2,23 @@ import { useQuery } from '@tanstack/react-query'; import isElectron from 'is-electron'; import { queryKeys } from '/@/renderer/api/query-keys'; import { - InternetProviderLyricSearchResponse, - LyricSearchQuery, - LyricSource, + InternetProviderLyricSearchResponse, + LyricSearchQuery, + LyricSource, } from '/@/renderer/api/types'; import { QueryHookArgs } from '/@/renderer/lib/react-query'; const lyricsIpc = isElectron() ? window.electron.lyrics : null; export const useLyricSearch = (args: Omit<QueryHookArgs<LyricSearchQuery>, 'serverId'>) => { - const { options, query } = args; + const { options, query } = args; - return useQuery<Record<LyricSource, InternetProviderLyricSearchResponse[]>>({ - cacheTime: 1000 * 60 * 1, - enabled: !!query.artist || !!query.name, - queryFn: () => lyricsIpc?.searchRemoteLyrics(query), - queryKey: queryKeys.songs.lyricsSearch(query), - staleTime: 1000 * 60 * 1, - ...options, - }); + return useQuery<Record<LyricSource, InternetProviderLyricSearchResponse[]>>({ + cacheTime: 1000 * 60 * 1, + enabled: !!query.artist || !!query.name, + queryFn: () => lyricsIpc?.searchRemoteLyrics(query), + queryKey: queryKeys.songs.lyricsSearch(query), + staleTime: 1000 * 60 * 1, + ...options, + }); }; diff --git a/src/renderer/features/lyrics/synchronized-lyrics.tsx b/src/renderer/features/lyrics/synchronized-lyrics.tsx index c51304c1..13b43539 100644 --- a/src/renderer/features/lyrics/synchronized-lyrics.tsx +++ b/src/renderer/features/lyrics/synchronized-lyrics.tsx @@ -1,10 +1,10 @@ import { useCallback, useEffect, useRef } from 'react'; import { - useCurrentStatus, - useCurrentTime, - useLyricsSettings, - usePlayerType, - useSeeked, + useCurrentStatus, + useCurrentTime, + useLyricsSettings, + usePlayerType, + useSeeked, } from '/@/renderer/store'; import { PlaybackType, PlayerStatus } from '/@/renderer/types'; import { LyricLine } from '/@/renderer/features/lyrics/lyric-line'; @@ -16,303 +16,310 @@ import styled from 'styled-components'; const mpvPlayer = isElectron() ? window.electron.mpvPlayer : null; const SynchronizedLyricsContainer = styled.div` - display: flex; - flex-direction: column; - gap: 2rem; - width: 100%; - height: 100%; - padding: 10vh 0 6vh; - overflow: scroll; - transform: translateY(-2rem); + display: flex; + flex-direction: column; + gap: 2rem; + width: 100%; + height: 100%; + padding: 10vh 0 6vh; + overflow: scroll; + transform: translateY(-2rem); - mask-image: linear-gradient( - 180deg, - transparent 5%, - rgba(0, 0, 0, 100%) 20%, - rgba(0, 0, 0, 100%) 85%, - transparent 95% - ); + mask-image: linear-gradient( + 180deg, + transparent 5%, + rgba(0, 0, 0, 100%) 20%, + rgba(0, 0, 0, 100%) 85%, + transparent 95% + ); - @media screen and (max-width: 768px) { - padding: 5vh 0; - } + @media screen and (max-width: 768px) { + padding: 5vh 0; + } `; interface SynchronizedLyricsProps extends Omit<FullLyricsMetadata, 'lyrics'> { - lyrics: SynchronizedLyricsArray; + lyrics: SynchronizedLyricsArray; } export const SynchronizedLyrics = ({ - artist, - lyrics, - name, - remote, - source, + artist, + lyrics, + name, + remote, + source, }: SynchronizedLyricsProps) => { - const playersRef = PlayersRef; - const status = useCurrentStatus(); - const playerType = usePlayerType(); - const now = useCurrentTime(); - const settings = useLyricsSettings(); + const playersRef = PlayersRef; + const status = useCurrentStatus(); + const playerType = usePlayerType(); + const now = useCurrentTime(); + const settings = useLyricsSettings(); - const seeked = useSeeked(); + const seeked = useSeeked(); - // A reference to the timeout handler - const lyricTimer = useRef<ReturnType<typeof setTimeout>>(); + // A reference to the timeout handler + const lyricTimer = useRef<ReturnType<typeof setTimeout>>(); - // A reference to the lyrics. This is necessary for the - // timers, which are not part of react necessarily, to always - // have the most updated values - const lyricRef = useRef<SynchronizedLyricsArray>(); + // A reference to the lyrics. This is necessary for the + // timers, which are not part of react necessarily, to always + // have the most updated values + const lyricRef = useRef<SynchronizedLyricsArray>(); - // A constantly increasing value, used to tell timers that may be out of date - // whether to proceed or stop - const timerEpoch = useRef(0); + // A constantly increasing value, used to tell timers that may be out of date + // whether to proceed or stop + const timerEpoch = useRef(0); - const delayMsRef = useRef(settings.delayMs); - const followRef = useRef(settings.follow); + const delayMsRef = useRef(settings.delayMs); + const followRef = useRef(settings.follow); - const getCurrentLyric = (timeInMs: number) => { - if (lyricRef.current) { - const activeLyrics = lyricRef.current; - for (let idx = 0; idx < activeLyrics.length; idx += 1) { - if (timeInMs <= activeLyrics[idx][0]) { - return idx === 0 ? idx : idx - 1; - } - } + const getCurrentLyric = (timeInMs: number) => { + if (lyricRef.current) { + const activeLyrics = lyricRef.current; + for (let idx = 0; idx < activeLyrics.length; idx += 1) { + if (timeInMs <= activeLyrics[idx][0]) { + return idx === 0 ? idx : idx - 1; + } + } - return activeLyrics.length - 1; - } - - return -1; - }; - - const getCurrentTime = useCallback(async () => { - if (isElectron() && playerType !== PlaybackType.WEB) { - if (mpvPlayer) { - return mpvPlayer.getCurrentTime(); - } - return 0; - } - - if (playersRef.current === undefined) { - return 0; - } - - const player = (playersRef.current.player1 ?? playersRef.current.player2).getInternalPlayer(); - - // If it is null, this probably means we added a new song while the lyrics tab is open - // and the queue was previously empty - if (!player) return 0; - - return player.currentTime; - }, [playerType, playersRef]); - - const setCurrentLyric = useCallback((timeInMs: number, epoch?: number, targetIndex?: number) => { - const start = performance.now(); - let nextEpoch: number; - - if (epoch === undefined) { - timerEpoch.current = (timerEpoch.current + 1) % 10000; - nextEpoch = timerEpoch.current; - } else if (epoch !== timerEpoch.current) { - return; - } else { - nextEpoch = epoch; - } - - let index: number; - - if (targetIndex === undefined) { - index = getCurrentLyric(timeInMs); - } else { - index = targetIndex; - } - - // Directly modify the dom instead of using react to prevent rerender - document - .querySelectorAll('.synchronized-lyrics .active') - .forEach((node) => node.classList.remove('active')); - - if (index === -1) { - lyricRef.current = undefined; - return; - } - - const doc = document.getElementById('sychronized-lyrics-scroll-container') as HTMLElement; - const currentLyric = document.querySelector(`#lyric-${index}`) as HTMLElement; - const offsetTop = currentLyric?.offsetTop - doc?.clientHeight / 2 ?? 0; - - if (currentLyric === null) { - lyricRef.current = undefined; - return; - } - - currentLyric.classList.add('active'); - - if (followRef.current) { - doc?.scroll({ behavior: 'smooth', top: offsetTop }); - } - - if (index !== lyricRef.current!.length - 1) { - const nextTime = lyricRef.current![index + 1][0]; - - const elapsed = performance.now() - start; - - lyricTimer.current = setTimeout(() => { - setCurrentLyric(nextTime, nextEpoch, index + 1); - }, nextTime - timeInMs - elapsed); - } - }, []); - - useEffect(() => { - // Copy the follow settings into a ref that can be accessed in the timeout - followRef.current = settings.follow; - }, [settings.follow]); - - useEffect(() => { - // This handler is used to handle when lyrics change. It is in some sense the - // 'primary' handler for parsing lyrics, as unlike the other callbacks, it will - // ALSO remove listeners on close. Use the promisified getCurrentTime(), because - // we don't want to be dependent on npw, which may not be precise - lyricRef.current = lyrics; - - if (status === PlayerStatus.PLAYING) { - let rejected = false; - - getCurrentTime() - .then((timeInSec: number) => { - if (rejected) { - return false; - } - - setCurrentLyric(timeInSec * 1000 - delayMsRef.current); - - return true; - }) - .catch(console.error); - - return () => { - // Case 1: cleanup happens before we hear back from - // the main process. In this case, when the promise resolves, ignore the result - rejected = true; - - // Case 2: Cleanup happens after we hear back from main process but - // (potentially) before the next lyric. In this case, clear the timer. - // Do NOT do this for other cleanup functions, as it should only be done - // when switching to a new song (or an empty one) - if (lyricTimer.current) clearTimeout(lyricTimer.current); - }; - } - - return () => {}; - }, [getCurrentTime, lyrics, playerType, setCurrentLyric, status]); - - useEffect(() => { - // This handler is used to deal with changes to the current delay. If the offset - // changes, we should immediately stop the current listening set and calculate - // the correct one using the new offset. Afterwards, timing can be calculated like normal - const changed = delayMsRef.current !== settings.delayMs; - - if (!changed) { - return () => {}; - } - - if (lyricTimer.current) { - clearTimeout(lyricTimer.current); - } - - let rejected = false; - - delayMsRef.current = settings.delayMs; - - getCurrentTime() - .then((timeInSec: number) => { - if (rejected) { - return false; + return activeLyrics.length - 1; } - setCurrentLyric(timeInSec * 1000 - delayMsRef.current); - - return true; - }) - .catch(console.error); - - return () => { - // In the event this ends earlier, just kill the promise. Cleanup of - // timeouts is otherwise handled by another handler - rejected = true; + return -1; }; - }, [getCurrentTime, setCurrentLyric, settings.delayMs]); - useEffect(() => { - // This handler is used specifically for dealing with seeking. In this case, - // we assume that now is the accurate time - if (status !== PlayerStatus.PLAYING) { - if (lyricTimer.current) { - clearTimeout(lyricTimer.current); - } + const getCurrentTime = useCallback(async () => { + if (isElectron() && playerType !== PlaybackType.WEB) { + if (mpvPlayer) { + return mpvPlayer.getCurrentTime(); + } + return 0; + } - return; - } - if (!seeked) { - return; - } + if (playersRef.current === undefined) { + return 0; + } - if (lyricTimer.current) { - clearTimeout(lyricTimer.current); - } + const player = ( + playersRef.current.player1 ?? playersRef.current.player2 + ).getInternalPlayer(); - setCurrentLyric(now * 1000 - delayMsRef.current); - }, [now, seeked, setCurrentLyric, status]); + // If it is null, this probably means we added a new song while the lyrics tab is open + // and the queue was previously empty + if (!player) return 0; - useEffect(() => { - // Guaranteed cleanup; stop the timer, and just in case also increment - // the epoch to instruct any dangling timers to stop - if (lyricTimer.current) { - clearTimeout(lyricTimer.current); - } + return player.currentTime; + }, [playerType, playersRef]); - timerEpoch.current += 1; - }, []); + const setCurrentLyric = useCallback( + (timeInMs: number, epoch?: number, targetIndex?: number) => { + const start = performance.now(); + let nextEpoch: number; - const hideScrollbar = () => { - const doc = document.getElementById('sychronized-lyrics-scroll-container') as HTMLElement; - doc.classList.add('hide-scrollbar'); - }; + if (epoch === undefined) { + timerEpoch.current = (timerEpoch.current + 1) % 10000; + nextEpoch = timerEpoch.current; + } else if (epoch !== timerEpoch.current) { + return; + } else { + nextEpoch = epoch; + } - const showScrollbar = () => { - const doc = document.getElementById('sychronized-lyrics-scroll-container') as HTMLElement; - doc.classList.remove('hide-scrollbar'); - }; + let index: number; - return ( - <SynchronizedLyricsContainer - className="synchronized-lyrics overlay-scrollbar" - id="sychronized-lyrics-scroll-container" - onMouseEnter={showScrollbar} - onMouseLeave={hideScrollbar} - > - {source && ( - <LyricLine - className="lyric-credit" - text={`Provided by ${source}`} - /> - )} - {remote && ( - <LyricLine - className="lyric-credit" - text={`"${name} by ${artist}"`} - /> - )} - {lyrics.map(([, text], idx) => ( - <LyricLine - key={idx} - className="lyric-line synchronized" - id={`lyric-${idx}`} - text={text} - /> - ))} - </SynchronizedLyricsContainer> - ); + if (targetIndex === undefined) { + index = getCurrentLyric(timeInMs); + } else { + index = targetIndex; + } + + // Directly modify the dom instead of using react to prevent rerender + document + .querySelectorAll('.synchronized-lyrics .active') + .forEach((node) => node.classList.remove('active')); + + if (index === -1) { + lyricRef.current = undefined; + return; + } + + const doc = document.getElementById( + 'sychronized-lyrics-scroll-container', + ) as HTMLElement; + const currentLyric = document.querySelector(`#lyric-${index}`) as HTMLElement; + const offsetTop = currentLyric?.offsetTop - doc?.clientHeight / 2 ?? 0; + + if (currentLyric === null) { + lyricRef.current = undefined; + return; + } + + currentLyric.classList.add('active'); + + if (followRef.current) { + doc?.scroll({ behavior: 'smooth', top: offsetTop }); + } + + if (index !== lyricRef.current!.length - 1) { + const nextTime = lyricRef.current![index + 1][0]; + + const elapsed = performance.now() - start; + + lyricTimer.current = setTimeout(() => { + setCurrentLyric(nextTime, nextEpoch, index + 1); + }, nextTime - timeInMs - elapsed); + } + }, + [], + ); + + useEffect(() => { + // Copy the follow settings into a ref that can be accessed in the timeout + followRef.current = settings.follow; + }, [settings.follow]); + + useEffect(() => { + // This handler is used to handle when lyrics change. It is in some sense the + // 'primary' handler for parsing lyrics, as unlike the other callbacks, it will + // ALSO remove listeners on close. Use the promisified getCurrentTime(), because + // we don't want to be dependent on npw, which may not be precise + lyricRef.current = lyrics; + + if (status === PlayerStatus.PLAYING) { + let rejected = false; + + getCurrentTime() + .then((timeInSec: number) => { + if (rejected) { + return false; + } + + setCurrentLyric(timeInSec * 1000 - delayMsRef.current); + + return true; + }) + .catch(console.error); + + return () => { + // Case 1: cleanup happens before we hear back from + // the main process. In this case, when the promise resolves, ignore the result + rejected = true; + + // Case 2: Cleanup happens after we hear back from main process but + // (potentially) before the next lyric. In this case, clear the timer. + // Do NOT do this for other cleanup functions, as it should only be done + // when switching to a new song (or an empty one) + if (lyricTimer.current) clearTimeout(lyricTimer.current); + }; + } + + return () => {}; + }, [getCurrentTime, lyrics, playerType, setCurrentLyric, status]); + + useEffect(() => { + // This handler is used to deal with changes to the current delay. If the offset + // changes, we should immediately stop the current listening set and calculate + // the correct one using the new offset. Afterwards, timing can be calculated like normal + const changed = delayMsRef.current !== settings.delayMs; + + if (!changed) { + return () => {}; + } + + if (lyricTimer.current) { + clearTimeout(lyricTimer.current); + } + + let rejected = false; + + delayMsRef.current = settings.delayMs; + + getCurrentTime() + .then((timeInSec: number) => { + if (rejected) { + return false; + } + + setCurrentLyric(timeInSec * 1000 - delayMsRef.current); + + return true; + }) + .catch(console.error); + + return () => { + // In the event this ends earlier, just kill the promise. Cleanup of + // timeouts is otherwise handled by another handler + rejected = true; + }; + }, [getCurrentTime, setCurrentLyric, settings.delayMs]); + + useEffect(() => { + // This handler is used specifically for dealing with seeking. In this case, + // we assume that now is the accurate time + if (status !== PlayerStatus.PLAYING) { + if (lyricTimer.current) { + clearTimeout(lyricTimer.current); + } + + return; + } + if (!seeked) { + return; + } + + if (lyricTimer.current) { + clearTimeout(lyricTimer.current); + } + + setCurrentLyric(now * 1000 - delayMsRef.current); + }, [now, seeked, setCurrentLyric, status]); + + useEffect(() => { + // Guaranteed cleanup; stop the timer, and just in case also increment + // the epoch to instruct any dangling timers to stop + if (lyricTimer.current) { + clearTimeout(lyricTimer.current); + } + + timerEpoch.current += 1; + }, []); + + const hideScrollbar = () => { + const doc = document.getElementById('sychronized-lyrics-scroll-container') as HTMLElement; + doc.classList.add('hide-scrollbar'); + }; + + const showScrollbar = () => { + const doc = document.getElementById('sychronized-lyrics-scroll-container') as HTMLElement; + doc.classList.remove('hide-scrollbar'); + }; + + return ( + <SynchronizedLyricsContainer + className="synchronized-lyrics overlay-scrollbar" + id="sychronized-lyrics-scroll-container" + onMouseEnter={showScrollbar} + onMouseLeave={hideScrollbar} + > + {source && ( + <LyricLine + className="lyric-credit" + text={`Provided by ${source}`} + /> + )} + {remote && ( + <LyricLine + className="lyric-credit" + text={`"${name} by ${artist}"`} + /> + )} + {lyrics.map(([, text], idx) => ( + <LyricLine + key={idx} + className="lyric-line synchronized" + id={`lyric-${idx}`} + text={text} + /> + ))} + </SynchronizedLyricsContainer> + ); }; diff --git a/src/renderer/features/lyrics/unsynchronized-lyrics.tsx b/src/renderer/features/lyrics/unsynchronized-lyrics.tsx index f498a9b9..fcb0d76b 100644 --- a/src/renderer/features/lyrics/unsynchronized-lyrics.tsx +++ b/src/renderer/features/lyrics/unsynchronized-lyrics.tsx @@ -4,65 +4,65 @@ import { LyricLine } from '/@/renderer/features/lyrics/lyric-line'; import { FullLyricsMetadata } from '/@/renderer/api/types'; interface UnsynchronizedLyricsProps extends Omit<FullLyricsMetadata, 'lyrics'> { - lyrics: string; + lyrics: string; } const UnsynchronizedLyricsContainer = styled.div` - display: flex; - flex-direction: column; - gap: 2rem; - width: 100%; - height: 100%; - padding: 10vh 0 6vh; - overflow: scroll; - transform: translateY(-2rem); + display: flex; + flex-direction: column; + gap: 2rem; + width: 100%; + height: 100%; + padding: 10vh 0 6vh; + overflow: scroll; + transform: translateY(-2rem); - mask-image: linear-gradient( - 180deg, - transparent 5%, - rgba(0, 0, 0, 100%) 20%, - rgba(0, 0, 0, 100%) 85%, - transparent 95% - ); + mask-image: linear-gradient( + 180deg, + transparent 5%, + rgba(0, 0, 0, 100%) 20%, + rgba(0, 0, 0, 100%) 85%, + transparent 95% + ); - @media screen and (max-width: 768px) { - padding: 5vh 0; - } + @media screen and (max-width: 768px) { + padding: 5vh 0; + } `; export const UnsynchronizedLyrics = ({ - artist, - lyrics, - name, - remote, - source, + artist, + lyrics, + name, + remote, + source, }: UnsynchronizedLyricsProps) => { - const lines = useMemo(() => { - return lyrics.split('\n'); - }, [lyrics]); + const lines = useMemo(() => { + return lyrics.split('\n'); + }, [lyrics]); - return ( - <UnsynchronizedLyricsContainer className="unsynchronized-lyrics"> - {source && ( - <LyricLine - className="lyric-credit" - text={`Provided by ${source}`} - /> - )} - {remote && ( - <LyricLine - className="lyric-credit" - text={`"${name} by ${artist}"`} - /> - )} - {lines.map((text, idx) => ( - <LyricLine - key={idx} - className="lyric-line" - id={`lyric-${idx}`} - text={text} - /> - ))} - </UnsynchronizedLyricsContainer> - ); + return ( + <UnsynchronizedLyricsContainer className="unsynchronized-lyrics"> + {source && ( + <LyricLine + className="lyric-credit" + text={`Provided by ${source}`} + /> + )} + {remote && ( + <LyricLine + className="lyric-credit" + text={`"${name} by ${artist}"`} + /> + )} + {lines.map((text, idx) => ( + <LyricLine + key={idx} + className="lyric-line" + id={`lyric-${idx}`} + text={text} + /> + ))} + </UnsynchronizedLyricsContainer> + ); }; diff --git a/src/renderer/features/now-playing/components/drawer-play-queue.tsx b/src/renderer/features/now-playing/components/drawer-play-queue.tsx index f1e7a718..057bcc7d 100644 --- a/src/renderer/features/now-playing/components/drawer-play-queue.tsx +++ b/src/renderer/features/now-playing/components/drawer-play-queue.tsx @@ -6,32 +6,32 @@ import { Song } from '/@/renderer/api/types'; import { PlayQueue } from '/@/renderer/features/now-playing/components/play-queue'; export const DrawerPlayQueue = () => { - const queueRef = useRef<{ grid: AgGridReactType<Song> } | null>(null); + const queueRef = useRef<{ grid: AgGridReactType<Song> } | null>(null); - return ( - <Flex - direction="column" - h="100%" - > - <Box - bg="var(--main-bg)" - sx={{ borderRadius: '10px' }} - > - <PlayQueueListControls - tableRef={queueRef} - type="sideQueue" - /> - </Box> - <Flex - bg="var(--main-bg)" - h="100%" - mb="0.6rem" - > - <PlayQueue - ref={queueRef} - type="sideQueue" - /> - </Flex> - </Flex> - ); + return ( + <Flex + direction="column" + h="100%" + > + <Box + bg="var(--main-bg)" + sx={{ borderRadius: '10px' }} + > + <PlayQueueListControls + tableRef={queueRef} + type="sideQueue" + /> + </Box> + <Flex + bg="var(--main-bg)" + h="100%" + mb="0.6rem" + > + <PlayQueue + ref={queueRef} + type="sideQueue" + /> + </Flex> + </Flex> + ); }; diff --git a/src/renderer/features/now-playing/components/now-playing-header.tsx b/src/renderer/features/now-playing/components/now-playing-header.tsx index 9c5aab1d..bfa80520 100644 --- a/src/renderer/features/now-playing/components/now-playing-header.tsx +++ b/src/renderer/features/now-playing/components/now-playing-header.tsx @@ -2,14 +2,14 @@ import { PageHeader } from '/@/renderer/components'; import { LibraryHeaderBar } from '/@/renderer/features/shared'; export const NowPlayingHeader = () => { - // const currentSong = useCurrentSong(); - // const theme = useTheme(); + // const currentSong = useCurrentSong(); + // const theme = useTheme(); - return ( - <PageHeader backgroundColor="var(--titlebar-bg)"> - <LibraryHeaderBar> - <LibraryHeaderBar.Title>Queue</LibraryHeaderBar.Title> - </LibraryHeaderBar> - </PageHeader> - ); + return ( + <PageHeader backgroundColor="var(--titlebar-bg)"> + <LibraryHeaderBar> + <LibraryHeaderBar.Title>Queue</LibraryHeaderBar.Title> + </LibraryHeaderBar> + </PageHeader> + ); }; diff --git a/src/renderer/features/now-playing/components/play-queue-list-controls.tsx b/src/renderer/features/now-playing/components/play-queue-list-controls.tsx index be1570c0..08c8cf9d 100644 --- a/src/renderer/features/now-playing/components/play-queue-list-controls.tsx +++ b/src/renderer/features/now-playing/components/play-queue-list-controls.tsx @@ -4,12 +4,12 @@ import { Group } from '@mantine/core'; import { Button, Popover } from '/@/renderer/components'; import isElectron from 'is-electron'; import { - RiArrowDownLine, - RiArrowUpLine, - RiShuffleLine, - RiDeleteBinLine, - RiListSettingsLine, - RiEraserLine, + RiArrowDownLine, + RiArrowUpLine, + RiShuffleLine, + RiDeleteBinLine, + RiListSettingsLine, + RiEraserLine, } from 'react-icons/ri'; import { Song } from '/@/renderer/api/types'; import { usePlayerControls, useQueueControls } from '/@/renderer/store'; @@ -21,156 +21,156 @@ import { TableConfigDropdown } from '/@/renderer/components/virtual-table'; const mpvPlayer = isElectron() ? window.electron.mpvPlayer : null; interface PlayQueueListOptionsProps { - tableRef: MutableRefObject<{ grid: AgGridReactType<Song> } | null>; - type: TableType; + tableRef: MutableRefObject<{ grid: AgGridReactType<Song> } | null>; + type: TableType; } export const PlayQueueListControls = ({ type, tableRef }: PlayQueueListOptionsProps) => { - const { clearQueue, moveToBottomOfQueue, moveToTopOfQueue, shuffleQueue, removeFromQueue } = - useQueueControls(); + const { clearQueue, moveToBottomOfQueue, moveToTopOfQueue, shuffleQueue, removeFromQueue } = + useQueueControls(); - const { pause } = usePlayerControls(); + const { pause } = usePlayerControls(); - const playerType = usePlayerType(); - const setCurrentTime = useSetCurrentTime(); + const playerType = usePlayerType(); + const setCurrentTime = useSetCurrentTime(); - const handleMoveToBottom = () => { - const selectedRows = tableRef?.current?.grid.api.getSelectedRows(); - const uniqueIds = selectedRows?.map((row) => row.uniqueId); - if (!uniqueIds?.length) return; + const handleMoveToBottom = () => { + const selectedRows = tableRef?.current?.grid.api.getSelectedRows(); + const uniqueIds = selectedRows?.map((row) => row.uniqueId); + if (!uniqueIds?.length) return; - const playerData = moveToBottomOfQueue(uniqueIds); + const playerData = moveToBottomOfQueue(uniqueIds); - if (playerType === PlaybackType.LOCAL) { - mpvPlayer.setQueueNext(playerData); - } - }; + if (playerType === PlaybackType.LOCAL) { + mpvPlayer.setQueueNext(playerData); + } + }; - const handleMoveToTop = () => { - const selectedRows = tableRef?.current?.grid.api.getSelectedRows(); - const uniqueIds = selectedRows?.map((row) => row.uniqueId); - if (!uniqueIds?.length) return; + const handleMoveToTop = () => { + const selectedRows = tableRef?.current?.grid.api.getSelectedRows(); + const uniqueIds = selectedRows?.map((row) => row.uniqueId); + if (!uniqueIds?.length) return; - const playerData = moveToTopOfQueue(uniqueIds); + const playerData = moveToTopOfQueue(uniqueIds); - if (playerType === PlaybackType.LOCAL) { - mpvPlayer.setQueueNext(playerData); - } - }; + if (playerType === PlaybackType.LOCAL) { + mpvPlayer.setQueueNext(playerData); + } + }; - const handleRemoveSelected = () => { - const selectedRows = tableRef?.current?.grid.api.getSelectedRows(); - const uniqueIds = selectedRows?.map((row) => row.uniqueId); - if (!uniqueIds?.length) return; + const handleRemoveSelected = () => { + const selectedRows = tableRef?.current?.grid.api.getSelectedRows(); + const uniqueIds = selectedRows?.map((row) => row.uniqueId); + if (!uniqueIds?.length) return; - const currentSong = usePlayerStore.getState().current.song; - const playerData = removeFromQueue(uniqueIds); - const isCurrentSongRemoved = currentSong && uniqueIds.includes(currentSong.uniqueId); + const currentSong = usePlayerStore.getState().current.song; + const playerData = removeFromQueue(uniqueIds); + const isCurrentSongRemoved = currentSong && uniqueIds.includes(currentSong.uniqueId); - if (playerType === PlaybackType.LOCAL) { - if (isCurrentSongRemoved) { - mpvPlayer.setQueue(playerData); - } else { - mpvPlayer.setQueueNext(playerData); - } - } - }; + if (playerType === PlaybackType.LOCAL) { + if (isCurrentSongRemoved) { + mpvPlayer.setQueue(playerData); + } else { + mpvPlayer.setQueueNext(playerData); + } + } + }; - const handleClearQueue = () => { - const playerData = clearQueue(); + const handleClearQueue = () => { + const playerData = clearQueue(); - if (playerType === PlaybackType.LOCAL) { - mpvPlayer.setQueue(playerData); - mpvPlayer.pause(); - } + if (playerType === PlaybackType.LOCAL) { + mpvPlayer.setQueue(playerData); + mpvPlayer.pause(); + } - setCurrentTime(0); - pause(); - }; + setCurrentTime(0); + pause(); + }; - const handleShuffleQueue = () => { - const playerData = shuffleQueue(); + const handleShuffleQueue = () => { + const playerData = shuffleQueue(); - if (playerType === PlaybackType.LOCAL) { - mpvPlayer.setQueueNext(playerData); - } - }; + if (playerType === PlaybackType.LOCAL) { + mpvPlayer.setQueueNext(playerData); + } + }; - return ( - <Group - position="apart" - px="1rem" - py="1rem" - sx={{ alignItems: 'center' }} - w="100%" - > - <Group spacing="sm"> - <Button - compact - size="md" - tooltip={{ label: 'Shuffle queue' }} - variant="default" - onClick={handleShuffleQueue} + return ( + <Group + position="apart" + px="1rem" + py="1rem" + sx={{ alignItems: 'center' }} + w="100%" > - <RiShuffleLine size="1.1rem" /> - </Button> - <Button - compact - size="md" - tooltip={{ label: 'Move selected to bottom' }} - variant="default" - onClick={handleMoveToBottom} - > - <RiArrowDownLine size="1.1rem" /> - </Button> - <Button - compact - size="md" - tooltip={{ label: 'Move selected to top' }} - variant="default" - onClick={handleMoveToTop} - > - <RiArrowUpLine size="1.1rem" /> - </Button> - <Button - compact - size="md" - tooltip={{ label: 'Remove selected' }} - variant="default" - onClick={handleRemoveSelected} - > - <RiEraserLine size="1.1rem" /> - </Button> - <Button - compact - size="md" - tooltip={{ label: 'Clear queue' }} - variant="default" - onClick={handleClearQueue} - > - <RiDeleteBinLine size="1.1rem" /> - </Button> - </Group> - <Group> - <Popover - position="top-end" - transitionProps={{ transition: 'fade' }} - > - <Popover.Target> - <Button - compact - size="md" - tooltip={{ label: 'Configure' }} - variant="subtle" - > - <RiListSettingsLine size="1.1rem" /> - </Button> - </Popover.Target> - <Popover.Dropdown> - <TableConfigDropdown type={type} /> - </Popover.Dropdown> - </Popover> - </Group> - </Group> - ); + <Group spacing="sm"> + <Button + compact + size="md" + tooltip={{ label: 'Shuffle queue' }} + variant="default" + onClick={handleShuffleQueue} + > + <RiShuffleLine size="1.1rem" /> + </Button> + <Button + compact + size="md" + tooltip={{ label: 'Move selected to bottom' }} + variant="default" + onClick={handleMoveToBottom} + > + <RiArrowDownLine size="1.1rem" /> + </Button> + <Button + compact + size="md" + tooltip={{ label: 'Move selected to top' }} + variant="default" + onClick={handleMoveToTop} + > + <RiArrowUpLine size="1.1rem" /> + </Button> + <Button + compact + size="md" + tooltip={{ label: 'Remove selected' }} + variant="default" + onClick={handleRemoveSelected} + > + <RiEraserLine size="1.1rem" /> + </Button> + <Button + compact + size="md" + tooltip={{ label: 'Clear queue' }} + variant="default" + onClick={handleClearQueue} + > + <RiDeleteBinLine size="1.1rem" /> + </Button> + </Group> + <Group> + <Popover + position="top-end" + transitionProps={{ transition: 'fade' }} + > + <Popover.Target> + <Button + compact + size="md" + tooltip={{ label: 'Configure' }} + variant="subtle" + > + <RiListSettingsLine size="1.1rem" /> + </Button> + </Popover.Target> + <Popover.Dropdown> + <TableConfigDropdown type={type} /> + </Popover.Dropdown> + </Popover> + </Group> + </Group> + ); }; diff --git a/src/renderer/features/now-playing/components/play-queue.tsx b/src/renderer/features/now-playing/components/play-queue.tsx index f7ff9f58..3c6061ba 100644 --- a/src/renderer/features/now-playing/components/play-queue.tsx +++ b/src/renderer/features/now-playing/components/play-queue.tsx @@ -1,26 +1,26 @@ import type { Ref } from 'react'; import { useState, forwardRef, useEffect, useImperativeHandle, useMemo, useRef } from 'react'; import type { - CellDoubleClickedEvent, - RowClassRules, - RowDragEvent, - RowNode, + CellDoubleClickedEvent, + RowClassRules, + RowDragEvent, + RowNode, } from '@ag-grid-community/core'; import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact'; import '@ag-grid-community/styles/ag-theme-alpine.css'; import { - useAppStoreActions, - useCurrentSong, - useDefaultQueue, - usePlayerControls, - usePreviousSong, - useQueueControls, + useAppStoreActions, + useCurrentSong, + useDefaultQueue, + usePlayerControls, + usePreviousSong, + useQueueControls, } from '/@/renderer/store'; import { - usePlayerType, - useSettingsStore, - useSettingsStoreActions, - useTableSettings, + usePlayerType, + useSettingsStore, + useSettingsStoreActions, + useTableSettings, } from '/@/renderer/store/settings.store'; import { useMergedRef } from '@mantine/hooks'; import isElectron from 'is-electron'; @@ -39,194 +39,200 @@ const utils = isElectron() ? window.electron.utils : null; const mpris = isElectron() && utils?.isLinux() ? window.electron.mpris : null; type QueueProps = { - type: TableType; + type: TableType; }; export const PlayQueue = forwardRef(({ type }: QueueProps, ref: Ref<any>) => { - const tableRef = useRef<AgGridReactType | null>(null); - const mergedRef = useMergedRef(ref, tableRef); - const queue = useDefaultQueue(); - const { reorderQueue, setCurrentTrack } = useQueueControls(); - const currentSong = useCurrentSong(); - const previousSong = usePreviousSong(); - const { setSettings } = useSettingsStoreActions(); - const { setAppStore } = useAppStoreActions(); - const tableConfig = useTableSettings(type); - const [gridApi, setGridApi] = useState<AgGridReactType | undefined>(); - const playerType = usePlayerType(); - const { play } = usePlayerControls(); + const tableRef = useRef<AgGridReactType | null>(null); + const mergedRef = useMergedRef(ref, tableRef); + const queue = useDefaultQueue(); + const { reorderQueue, setCurrentTrack } = useQueueControls(); + const currentSong = useCurrentSong(); + const previousSong = usePreviousSong(); + const { setSettings } = useSettingsStoreActions(); + const { setAppStore } = useAppStoreActions(); + const tableConfig = useTableSettings(type); + const [gridApi, setGridApi] = useState<AgGridReactType | undefined>(); + const playerType = usePlayerType(); + const { play } = usePlayerControls(); - useEffect(() => { - if (tableRef.current) { - setGridApi(tableRef.current); - } - }, []); - - useImperativeHandle(ref, () => ({ - get grid() { - return gridApi; - }, - })); - - const columnDefs = useMemo(() => getColumnDefs(tableConfig.columns), [tableConfig.columns]); - - const handleDoubleClick = (e: CellDoubleClickedEvent) => { - const playerData = setCurrentTrack(e.data.uniqueId); - mpris?.updateSong({ - currentTime: 0, - song: playerData.current.song, - status: 'Playing', - }); - - if (playerType === PlaybackType.LOCAL) { - mpvPlayer.setQueue(playerData); - mpvPlayer.play(); - } - - play(); - }; - - const handleDragStart = () => { - if (type === 'sideDrawerQueue') { - setAppStore({ isReorderingQueue: true }); - } - }; - - let timeout: any; - const handleDragEnd = (e: RowDragEvent<QueueSong>) => { - if (!e.nodes.length) return; - const selectedUniqueIds = e.nodes - .map((node) => node.data?.uniqueId) - .filter((e) => e !== undefined); - - const playerData = reorderQueue(selectedUniqueIds as string[], e.overNode?.data?.uniqueId); - - if (playerType === PlaybackType.LOCAL) { - mpvPlayer.setQueueNext(playerData); - } - - if (type === 'sideDrawerQueue') { - setAppStore({ isReorderingQueue: false }); - } - - const { api } = tableRef?.current || {}; - clearTimeout(timeout); - timeout = setTimeout(() => api?.redrawRows(), 250); - }; - - const handleGridReady = () => { - const { api } = tableRef?.current || {}; - - if (currentSong?.uniqueId) { - const currentNode = api?.getRowNode(currentSong?.uniqueId); - - if (!currentNode) return; - api?.ensureNodeVisible(currentNode, 'middle'); - } - }; - - const handleColumnChange = () => { - const { columnApi } = tableRef?.current || {}; - const columnsOrder = columnApi?.getAllGridColumns(); - if (!columnsOrder) return; - - const columnsInSettings = useSettingsStore.getState().tables[type].columns; - - const updatedColumns = []; - for (const column of columnsOrder) { - const columnInSettings = columnsInSettings.find((c) => c.column === column.getColDef().colId); - - if (columnInSettings) { - updatedColumns.push({ - ...columnInSettings, - ...(!useSettingsStore.getState().tables[type].autoFit && { - width: column.getActualWidth(), - }), - }); - } - } - - setSettings({ - tables: { - ...useSettingsStore.getState().tables, - [type]: { - ...useSettingsStore.getState().tables[type], - columns: updatedColumns, - }, - }, - }); - }; - - const debouncedColumnChange = debounce(handleColumnChange, 250); - - const handleGridSizeChange = () => { - if (tableConfig.autoFit) { - tableRef?.current?.api.sizeColumnsToFit(); - } - }; - - const rowClassRules = useMemo<RowClassRules | undefined>(() => { - return { - 'current-song': (params) => { - return params.data.uniqueId === currentSong?.uniqueId; - }, - }; - }, [currentSong?.uniqueId]); - - // Redraw the current song row when the previous song changes - useEffect(() => { - if (tableRef?.current) { - const { api, columnApi } = tableRef?.current || {}; - if (api == null || columnApi == null) { - return; - } - - const currentNode = currentSong?.uniqueId ? api.getRowNode(currentSong.uniqueId) : undefined; - const previousNode = previousSong?.uniqueId - ? api.getRowNode(previousSong?.uniqueId) - : undefined; - - const rowNodes = [currentNode, previousNode].filter((e) => e !== undefined) as RowNode<any>[]; - - if (rowNodes) { - api.redrawRows({ rowNodes }); - if (tableConfig.followCurrentSong) { - if (!currentNode) return; - api.ensureNodeVisible(currentNode, 'middle'); + useEffect(() => { + if (tableRef.current) { + setGridApi(tableRef.current); } - } - } - }, [currentSong, previousSong, tableConfig.followCurrentSong]); + }, []); - const handleContextMenu = useHandleTableContextMenu(LibraryItem.SONG, QUEUE_CONTEXT_MENU_ITEMS); + useImperativeHandle(ref, () => ({ + get grid() { + return gridApi; + }, + })); - return ( - <ErrorBoundary FallbackComponent={ErrorFallback}> - <VirtualGridAutoSizerContainer> - <VirtualTable - ref={mergedRef} - alwaysShowHorizontalScroll - rowDragEntireRow - rowDragMultiRow - autoFitColumns={tableConfig.autoFit} - columnDefs={columnDefs} - deselectOnClickOutside={type === 'fullScreen'} - getRowId={(data) => data.data.uniqueId} - rowBuffer={50} - rowClassRules={rowClassRules} - rowData={queue} - rowHeight={tableConfig.rowHeight || 40} - suppressCellFocus={type === 'fullScreen'} - onCellContextMenu={handleContextMenu} - onCellDoubleClicked={handleDoubleClick} - onColumnMoved={handleColumnChange} - onColumnResized={debouncedColumnChange} - onDragStarted={handleDragStart} - onGridReady={handleGridReady} - onGridSizeChanged={handleGridSizeChange} - onRowDragEnd={handleDragEnd} - /> - </VirtualGridAutoSizerContainer> - </ErrorBoundary> - ); + const columnDefs = useMemo(() => getColumnDefs(tableConfig.columns), [tableConfig.columns]); + + const handleDoubleClick = (e: CellDoubleClickedEvent) => { + const playerData = setCurrentTrack(e.data.uniqueId); + mpris?.updateSong({ + currentTime: 0, + song: playerData.current.song, + status: 'Playing', + }); + + if (playerType === PlaybackType.LOCAL) { + mpvPlayer.setQueue(playerData); + mpvPlayer.play(); + } + + play(); + }; + + const handleDragStart = () => { + if (type === 'sideDrawerQueue') { + setAppStore({ isReorderingQueue: true }); + } + }; + + let timeout: any; + const handleDragEnd = (e: RowDragEvent<QueueSong>) => { + if (!e.nodes.length) return; + const selectedUniqueIds = e.nodes + .map((node) => node.data?.uniqueId) + .filter((e) => e !== undefined); + + const playerData = reorderQueue(selectedUniqueIds as string[], e.overNode?.data?.uniqueId); + + if (playerType === PlaybackType.LOCAL) { + mpvPlayer.setQueueNext(playerData); + } + + if (type === 'sideDrawerQueue') { + setAppStore({ isReorderingQueue: false }); + } + + const { api } = tableRef?.current || {}; + clearTimeout(timeout); + timeout = setTimeout(() => api?.redrawRows(), 250); + }; + + const handleGridReady = () => { + const { api } = tableRef?.current || {}; + + if (currentSong?.uniqueId) { + const currentNode = api?.getRowNode(currentSong?.uniqueId); + + if (!currentNode) return; + api?.ensureNodeVisible(currentNode, 'middle'); + } + }; + + const handleColumnChange = () => { + const { columnApi } = tableRef?.current || {}; + const columnsOrder = columnApi?.getAllGridColumns(); + if (!columnsOrder) return; + + const columnsInSettings = useSettingsStore.getState().tables[type].columns; + + const updatedColumns = []; + for (const column of columnsOrder) { + const columnInSettings = columnsInSettings.find( + (c) => c.column === column.getColDef().colId, + ); + + if (columnInSettings) { + updatedColumns.push({ + ...columnInSettings, + ...(!useSettingsStore.getState().tables[type].autoFit && { + width: column.getActualWidth(), + }), + }); + } + } + + setSettings({ + tables: { + ...useSettingsStore.getState().tables, + [type]: { + ...useSettingsStore.getState().tables[type], + columns: updatedColumns, + }, + }, + }); + }; + + const debouncedColumnChange = debounce(handleColumnChange, 250); + + const handleGridSizeChange = () => { + if (tableConfig.autoFit) { + tableRef?.current?.api.sizeColumnsToFit(); + } + }; + + const rowClassRules = useMemo<RowClassRules | undefined>(() => { + return { + 'current-song': (params) => { + return params.data.uniqueId === currentSong?.uniqueId; + }, + }; + }, [currentSong?.uniqueId]); + + // Redraw the current song row when the previous song changes + useEffect(() => { + if (tableRef?.current) { + const { api, columnApi } = tableRef?.current || {}; + if (api == null || columnApi == null) { + return; + } + + const currentNode = currentSong?.uniqueId + ? api.getRowNode(currentSong.uniqueId) + : undefined; + const previousNode = previousSong?.uniqueId + ? api.getRowNode(previousSong?.uniqueId) + : undefined; + + const rowNodes = [currentNode, previousNode].filter( + (e) => e !== undefined, + ) as RowNode<any>[]; + + if (rowNodes) { + api.redrawRows({ rowNodes }); + if (tableConfig.followCurrentSong) { + if (!currentNode) return; + api.ensureNodeVisible(currentNode, 'middle'); + } + } + } + }, [currentSong, previousSong, tableConfig.followCurrentSong]); + + const handleContextMenu = useHandleTableContextMenu(LibraryItem.SONG, QUEUE_CONTEXT_MENU_ITEMS); + + return ( + <ErrorBoundary FallbackComponent={ErrorFallback}> + <VirtualGridAutoSizerContainer> + <VirtualTable + ref={mergedRef} + alwaysShowHorizontalScroll + rowDragEntireRow + rowDragMultiRow + autoFitColumns={tableConfig.autoFit} + columnDefs={columnDefs} + deselectOnClickOutside={type === 'fullScreen'} + getRowId={(data) => data.data.uniqueId} + rowBuffer={50} + rowClassRules={rowClassRules} + rowData={queue} + rowHeight={tableConfig.rowHeight || 40} + suppressCellFocus={type === 'fullScreen'} + onCellContextMenu={handleContextMenu} + onCellDoubleClicked={handleDoubleClick} + onColumnMoved={handleColumnChange} + onColumnResized={debouncedColumnChange} + onDragStarted={handleDragStart} + onGridReady={handleGridReady} + onGridSizeChanged={handleGridSizeChange} + onRowDragEnd={handleDragEnd} + /> + </VirtualGridAutoSizerContainer> + </ErrorBoundary> + ); }); diff --git a/src/renderer/features/now-playing/components/sidebar-play-queue.tsx b/src/renderer/features/now-playing/components/sidebar-play-queue.tsx index bb921d77..7e1d6fbf 100644 --- a/src/renderer/features/now-playing/components/sidebar-play-queue.tsx +++ b/src/renderer/features/now-playing/components/sidebar-play-queue.tsx @@ -10,30 +10,30 @@ import { Platform } from '/@/renderer/types'; import { VirtualGridContainer } from '/@/renderer/components/virtual-grid'; export const SidebarPlayQueue = () => { - const queueRef = useRef<{ grid: AgGridReactType<Song> } | null>(null); - const { windowBarStyle } = useWindowSettings(); + const queueRef = useRef<{ grid: AgGridReactType<Song> } | null>(null); + const { windowBarStyle } = useWindowSettings(); - const isWeb = windowBarStyle === Platform.WEB; - return ( - <VirtualGridContainer> - {isWeb && ( - <Stack mr={isWeb ? '130px' : undefined}> - <PageHeader backgroundColor="var(--titlebar-bg)" /> - </Stack> - )} - <Paper - display={!isWeb ? 'flex' : undefined} - h={!isWeb ? '65px' : undefined} - > - <PlayQueueListControls - tableRef={queueRef} - type="sideQueue" - /> - </Paper> - <PlayQueue - ref={queueRef} - type="sideQueue" - /> - </VirtualGridContainer> - ); + const isWeb = windowBarStyle === Platform.WEB; + return ( + <VirtualGridContainer> + {isWeb && ( + <Stack mr={isWeb ? '130px' : undefined}> + <PageHeader backgroundColor="var(--titlebar-bg)" /> + </Stack> + )} + <Paper + display={!isWeb ? 'flex' : undefined} + h={!isWeb ? '65px' : undefined} + > + <PlayQueueListControls + tableRef={queueRef} + type="sideQueue" + /> + </Paper> + <PlayQueue + ref={queueRef} + type="sideQueue" + /> + </VirtualGridContainer> + ); }; diff --git a/src/renderer/features/now-playing/routes/now-playing-route.tsx b/src/renderer/features/now-playing/routes/now-playing-route.tsx index b393acbc..8f2b0321 100644 --- a/src/renderer/features/now-playing/routes/now-playing-route.tsx +++ b/src/renderer/features/now-playing/routes/now-playing-route.tsx @@ -9,25 +9,25 @@ import { PlayQueueListControls } from '/@/renderer/features/now-playing/componen import { VirtualGridContainer } from '/@/renderer/components/virtual-grid'; const NowPlayingRoute = () => { - const queueRef = useRef<{ grid: AgGridReactType<Song> } | null>(null); + const queueRef = useRef<{ grid: AgGridReactType<Song> } | null>(null); - return ( - <AnimatedPage> - <VirtualGridContainer> - <NowPlayingHeader /> - <Paper sx={{ borderTop: '1px solid var(--generic-border-color)' }}> - <PlayQueueListControls - tableRef={queueRef} - type="nowPlaying" - /> - </Paper> - <PlayQueue - ref={queueRef} - type="nowPlaying" - /> - </VirtualGridContainer> - </AnimatedPage> - ); + return ( + <AnimatedPage> + <VirtualGridContainer> + <NowPlayingHeader /> + <Paper sx={{ borderTop: '1px solid var(--generic-border-color)' }}> + <PlayQueueListControls + tableRef={queueRef} + type="nowPlaying" + /> + </Paper> + <PlayQueue + ref={queueRef} + type="nowPlaying" + /> + </VirtualGridContainer> + </AnimatedPage> + ); }; export default NowPlayingRoute; diff --git a/src/renderer/features/player/components/center-controls.tsx b/src/renderer/features/player/components/center-controls.tsx index f7723d68..5fc119ef 100644 --- a/src/renderer/features/player/components/center-controls.tsx +++ b/src/renderer/features/player/components/center-controls.tsx @@ -5,34 +5,34 @@ import formatDuration from 'format-duration'; import isElectron from 'is-electron'; import { IoIosPause } from 'react-icons/io'; import { - RiMenuAddFill, - RiPlayFill, - RiRepeat2Line, - RiRepeatOneLine, - RiRewindFill, - RiShuffleFill, - RiSkipBackFill, - RiSkipForwardFill, - RiSpeedFill, - RiStopFill, + RiMenuAddFill, + RiPlayFill, + RiRepeat2Line, + RiRepeatOneLine, + RiRewindFill, + RiShuffleFill, + RiSkipBackFill, + RiSkipForwardFill, + RiSpeedFill, + RiStopFill, } from 'react-icons/ri'; import styled from 'styled-components'; import { Text } from '/@/renderer/components'; import { useCenterControls } from '../hooks/use-center-controls'; import { PlayerButton } from './player-button'; import { - useCurrentSong, - useCurrentStatus, - useCurrentPlayer, - useSetCurrentTime, - useRepeatStatus, - useShuffleStatus, - useCurrentTime, + useCurrentSong, + useCurrentStatus, + useCurrentPlayer, + useSetCurrentTime, + useRepeatStatus, + useShuffleStatus, + useCurrentTime, } from '/@/renderer/store'; import { - useHotkeySettings, - usePlayerType, - useSettingsStore, + useHotkeySettings, + usePlayerType, + useSettingsStore, } from '/@/renderer/store/settings.store'; import { PlayerStatus, PlaybackType, PlayerShuffle, PlayerRepeat } from '/@/renderer/types'; import { PlayerbarSlider } from '/@/renderer/features/player/components/playerbar-slider'; @@ -40,282 +40,286 @@ import { openShuffleAllModal } from './shuffle-all-modal'; import { usePlayQueueAdd } from '/@/renderer/features/player/hooks/use-playqueue-add'; interface CenterControlsProps { - playersRef: any; + playersRef: any; } const ButtonsContainer = styled.div` - display: flex; - gap: 0.5rem; - align-items: center; + display: flex; + gap: 0.5rem; + align-items: center; `; const SliderContainer = styled.div` - display: flex; - width: 95%; - height: 20px; + display: flex; + width: 95%; + height: 20px; `; const SliderValueWrapper = styled.div<{ position: 'left' | 'right' }>` - display: flex; - flex: 1; - align-self: flex-end; - justify-content: center; - max-width: 50px; + display: flex; + flex: 1; + align-self: flex-end; + justify-content: center; + max-width: 50px; - @media (max-width: 768px) { - display: none; - } + @media (max-width: 768px) { + display: none; + } `; const SliderWrapper = styled.div` - display: flex; - flex: 6; - align-items: center; - height: 100%; + display: flex; + flex: 6; + align-items: center; + height: 100%; `; const ControlsContainer = styled.div` - display: flex; - align-items: center; - justify-content: center; - height: 35px; + display: flex; + align-items: center; + justify-content: center; + height: 35px; - @media (max-width: 768px) { - ${ButtonsContainer} { - gap: 0; - } + @media (max-width: 768px) { + ${ButtonsContainer} { + gap: 0; + } - ${SliderValueWrapper} { - display: none; + ${SliderValueWrapper} { + display: none; + } } - } `; export const CenterControls = ({ playersRef }: CenterControlsProps) => { - const queryClient = useQueryClient(); - const [isSeeking, setIsSeeking] = useState(false); - const currentSong = useCurrentSong(); - const songDuration = currentSong?.duration; - const skip = useSettingsStore((state) => state.general.skipButtons); - const playerType = usePlayerType(); - const player1 = playersRef?.current?.player1; - const player2 = playersRef?.current?.player2; - const status = useCurrentStatus(); - const player = useCurrentPlayer(); - const setCurrentTime = useSetCurrentTime(); - const repeat = useRepeatStatus(); - const shuffle = useShuffleStatus(); - const { bindings } = useHotkeySettings(); + const queryClient = useQueryClient(); + const [isSeeking, setIsSeeking] = useState(false); + const currentSong = useCurrentSong(); + const songDuration = currentSong?.duration; + const skip = useSettingsStore((state) => state.general.skipButtons); + const playerType = usePlayerType(); + const player1 = playersRef?.current?.player1; + const player2 = playersRef?.current?.player2; + const status = useCurrentStatus(); + const player = useCurrentPlayer(); + const setCurrentTime = useSetCurrentTime(); + const repeat = useRepeatStatus(); + const shuffle = useShuffleStatus(); + const { bindings } = useHotkeySettings(); - const { - handleNextTrack, - handlePlayPause, - handlePrevTrack, - handleSeekSlider, - handleSkipBackward, - handleSkipForward, - handleToggleRepeat, - handleToggleShuffle, - handleStop, - handlePause, - handlePlay, - } = useCenterControls({ playersRef }); - const handlePlayQueueAdd = usePlayQueueAdd(); + const { + handleNextTrack, + handlePlayPause, + handlePrevTrack, + handleSeekSlider, + handleSkipBackward, + handleSkipForward, + handleToggleRepeat, + handleToggleShuffle, + handleStop, + handlePause, + handlePlay, + } = useCenterControls({ playersRef }); + const handlePlayQueueAdd = usePlayQueueAdd(); - const currentTime = useCurrentTime(); - const currentPlayerRef = player === 1 ? player1 : player2; - const duration = formatDuration((songDuration || 0) * 1000); - const formattedTime = formatDuration(currentTime * 1000 || 0); + const currentTime = useCurrentTime(); + const currentPlayerRef = player === 1 ? player1 : player2; + const duration = formatDuration((songDuration || 0) * 1000); + const formattedTime = formatDuration(currentTime * 1000 || 0); - useEffect(() => { - let interval: any; + useEffect(() => { + let interval: any; - if (status === PlayerStatus.PLAYING && !isSeeking) { - if (!isElectron() || playerType === PlaybackType.WEB) { - interval = setInterval(() => { - setCurrentTime(currentPlayerRef.getCurrentTime()); - }, 1000); - } - } else { - clearInterval(interval); - } - - return () => clearInterval(interval); - }, [currentPlayerRef, isSeeking, setCurrentTime, playerType, status]); - - const [seekValue, setSeekValue] = useState(0); - - useHotkeys([ - [bindings.playPause.isGlobal ? '' : bindings.playPause.hotkey, handlePlayPause], - [bindings.play.isGlobal ? '' : bindings.play.hotkey, handlePlay], - [bindings.pause.isGlobal ? '' : bindings.pause.hotkey, handlePause], - [bindings.stop.isGlobal ? '' : bindings.stop.hotkey, handleStop], - [bindings.next.isGlobal ? '' : bindings.next.hotkey, handleNextTrack], - [bindings.previous.isGlobal ? '' : bindings.previous.hotkey, handlePrevTrack], - [bindings.toggleRepeat.isGlobal ? '' : bindings.toggleRepeat.hotkey, handleToggleRepeat], - [bindings.toggleShuffle.isGlobal ? '' : bindings.toggleShuffle.hotkey, handleToggleShuffle], - [ - bindings.skipBackward.isGlobal ? '' : bindings.skipBackward.hotkey, - () => handleSkipBackward(skip?.skipBackwardSeconds || 5), - ], - [ - bindings.skipForward.isGlobal ? '' : bindings.skipForward.hotkey, - () => handleSkipForward(skip?.skipForwardSeconds || 5), - ], - ]); - - return ( - <> - <ControlsContainer> - <ButtonsContainer> - <PlayerButton - icon={<RiStopFill size={15} />} - tooltip={{ - label: 'Stop', - openDelay: 500, - }} - variant="tertiary" - onClick={handleStop} - /> - <PlayerButton - $isActive={shuffle !== PlayerShuffle.NONE} - icon={<RiShuffleFill size={15} />} - tooltip={{ - label: - shuffle === PlayerShuffle.NONE - ? 'Shuffle disabled' - : shuffle === PlayerShuffle.TRACK - ? 'Shuffle tracks' - : 'Shuffle albums', - openDelay: 500, - }} - variant="tertiary" - onClick={handleToggleShuffle} - /> - <PlayerButton - icon={<RiSkipBackFill size={15} />} - tooltip={{ label: 'Previous track', openDelay: 500 }} - variant="secondary" - onClick={handlePrevTrack} - /> - {skip?.enabled && ( - <PlayerButton - icon={<RiRewindFill size={15} />} - tooltip={{ - label: `Skip backwards ${skip?.skipBackwardSeconds} seconds`, - openDelay: 500, - }} - variant="secondary" - onClick={() => handleSkipBackward(skip?.skipBackwardSeconds)} - /> - )} - <PlayerButton - icon={ - status === PlayerStatus.PAUSED ? <RiPlayFill size={20} /> : <IoIosPause size={20} /> + if (status === PlayerStatus.PLAYING && !isSeeking) { + if (!isElectron() || playerType === PlaybackType.WEB) { + interval = setInterval(() => { + setCurrentTime(currentPlayerRef.getCurrentTime()); + }, 1000); } - tooltip={{ - label: status === PlayerStatus.PAUSED ? 'Play' : 'Pause', - openDelay: 500, - }} - variant="main" - onClick={handlePlayPause} - /> - {skip?.enabled && ( - <PlayerButton - icon={<RiSpeedFill size={15} />} - tooltip={{ - label: `Skip forwards ${skip?.skipForwardSeconds} seconds`, - openDelay: 500, - }} - variant="secondary" - onClick={() => handleSkipForward(skip?.skipForwardSeconds)} - /> - )} - <PlayerButton - icon={<RiSkipForwardFill size={15} />} - tooltip={{ label: 'Next track', openDelay: 500 }} - variant="secondary" - onClick={handleNextTrack} - /> - <PlayerButton - $isActive={repeat !== PlayerRepeat.NONE} - icon={ - repeat === PlayerRepeat.ONE ? ( - <RiRepeatOneLine size={15} /> - ) : ( - <RiRepeat2Line size={15} /> - ) - } - tooltip={{ - label: `${ - repeat === PlayerRepeat.NONE - ? 'Repeat disabled' - : repeat === PlayerRepeat.ALL - ? 'Repeat all' - : 'Repeat one' - }`, - openDelay: 500, - }} - variant="tertiary" - onClick={handleToggleRepeat} - /> + } else { + clearInterval(interval); + } - <PlayerButton - icon={<RiMenuAddFill size={15} />} - tooltip={{ - label: 'Shuffle all', - openDelay: 500, - }} - variant="tertiary" - onClick={() => - openShuffleAllModal({ - handlePlayQueueAdd, - queryClient, - }) - } - /> - </ButtonsContainer> - </ControlsContainer> - <SliderContainer> - <SliderValueWrapper position="left"> - <Text - $noSelect - $secondary - size="xs" - weight={600} - > - {formattedTime} - </Text> - </SliderValueWrapper> - <SliderWrapper> - <PlayerbarSlider - label={(value) => formatDuration(value * 1000)} - max={songDuration} - min={0} - size={6} - value={!isSeeking ? currentTime : seekValue} - w="100%" - onChange={(e) => { - setIsSeeking(true); - setSeekValue(e); - }} - onChangeEnd={(e) => { - handleSeekSlider(e); - setIsSeeking(false); - }} - /> - </SliderWrapper> - <SliderValueWrapper position="right"> - <Text - $noSelect - $secondary - size="xs" - weight={600} - > - {duration} - </Text> - </SliderValueWrapper> - </SliderContainer> - </> - ); + return () => clearInterval(interval); + }, [currentPlayerRef, isSeeking, setCurrentTime, playerType, status]); + + const [seekValue, setSeekValue] = useState(0); + + useHotkeys([ + [bindings.playPause.isGlobal ? '' : bindings.playPause.hotkey, handlePlayPause], + [bindings.play.isGlobal ? '' : bindings.play.hotkey, handlePlay], + [bindings.pause.isGlobal ? '' : bindings.pause.hotkey, handlePause], + [bindings.stop.isGlobal ? '' : bindings.stop.hotkey, handleStop], + [bindings.next.isGlobal ? '' : bindings.next.hotkey, handleNextTrack], + [bindings.previous.isGlobal ? '' : bindings.previous.hotkey, handlePrevTrack], + [bindings.toggleRepeat.isGlobal ? '' : bindings.toggleRepeat.hotkey, handleToggleRepeat], + [bindings.toggleShuffle.isGlobal ? '' : bindings.toggleShuffle.hotkey, handleToggleShuffle], + [ + bindings.skipBackward.isGlobal ? '' : bindings.skipBackward.hotkey, + () => handleSkipBackward(skip?.skipBackwardSeconds || 5), + ], + [ + bindings.skipForward.isGlobal ? '' : bindings.skipForward.hotkey, + () => handleSkipForward(skip?.skipForwardSeconds || 5), + ], + ]); + + return ( + <> + <ControlsContainer> + <ButtonsContainer> + <PlayerButton + icon={<RiStopFill size={15} />} + tooltip={{ + label: 'Stop', + openDelay: 500, + }} + variant="tertiary" + onClick={handleStop} + /> + <PlayerButton + $isActive={shuffle !== PlayerShuffle.NONE} + icon={<RiShuffleFill size={15} />} + tooltip={{ + label: + shuffle === PlayerShuffle.NONE + ? 'Shuffle disabled' + : shuffle === PlayerShuffle.TRACK + ? 'Shuffle tracks' + : 'Shuffle albums', + openDelay: 500, + }} + variant="tertiary" + onClick={handleToggleShuffle} + /> + <PlayerButton + icon={<RiSkipBackFill size={15} />} + tooltip={{ label: 'Previous track', openDelay: 500 }} + variant="secondary" + onClick={handlePrevTrack} + /> + {skip?.enabled && ( + <PlayerButton + icon={<RiRewindFill size={15} />} + tooltip={{ + label: `Skip backwards ${skip?.skipBackwardSeconds} seconds`, + openDelay: 500, + }} + variant="secondary" + onClick={() => handleSkipBackward(skip?.skipBackwardSeconds)} + /> + )} + <PlayerButton + icon={ + status === PlayerStatus.PAUSED ? ( + <RiPlayFill size={20} /> + ) : ( + <IoIosPause size={20} /> + ) + } + tooltip={{ + label: status === PlayerStatus.PAUSED ? 'Play' : 'Pause', + openDelay: 500, + }} + variant="main" + onClick={handlePlayPause} + /> + {skip?.enabled && ( + <PlayerButton + icon={<RiSpeedFill size={15} />} + tooltip={{ + label: `Skip forwards ${skip?.skipForwardSeconds} seconds`, + openDelay: 500, + }} + variant="secondary" + onClick={() => handleSkipForward(skip?.skipForwardSeconds)} + /> + )} + <PlayerButton + icon={<RiSkipForwardFill size={15} />} + tooltip={{ label: 'Next track', openDelay: 500 }} + variant="secondary" + onClick={handleNextTrack} + /> + <PlayerButton + $isActive={repeat !== PlayerRepeat.NONE} + icon={ + repeat === PlayerRepeat.ONE ? ( + <RiRepeatOneLine size={15} /> + ) : ( + <RiRepeat2Line size={15} /> + ) + } + tooltip={{ + label: `${ + repeat === PlayerRepeat.NONE + ? 'Repeat disabled' + : repeat === PlayerRepeat.ALL + ? 'Repeat all' + : 'Repeat one' + }`, + openDelay: 500, + }} + variant="tertiary" + onClick={handleToggleRepeat} + /> + + <PlayerButton + icon={<RiMenuAddFill size={15} />} + tooltip={{ + label: 'Shuffle all', + openDelay: 500, + }} + variant="tertiary" + onClick={() => + openShuffleAllModal({ + handlePlayQueueAdd, + queryClient, + }) + } + /> + </ButtonsContainer> + </ControlsContainer> + <SliderContainer> + <SliderValueWrapper position="left"> + <Text + $noSelect + $secondary + size="xs" + weight={600} + > + {formattedTime} + </Text> + </SliderValueWrapper> + <SliderWrapper> + <PlayerbarSlider + label={(value) => formatDuration(value * 1000)} + max={songDuration} + min={0} + size={6} + value={!isSeeking ? currentTime : seekValue} + w="100%" + onChange={(e) => { + setIsSeeking(true); + setSeekValue(e); + }} + onChangeEnd={(e) => { + handleSeekSlider(e); + setIsSeeking(false); + }} + /> + </SliderWrapper> + <SliderValueWrapper position="right"> + <Text + $noSelect + $secondary + size="xs" + weight={600} + > + {duration} + </Text> + </SliderValueWrapper> + </SliderContainer> + </> + ); }; diff --git a/src/renderer/features/player/components/full-screen-player-image.tsx b/src/renderer/features/player/components/full-screen-player-image.tsx index 94594542..b8991c1f 100644 --- a/src/renderer/features/player/components/full-screen-player-image.tsx +++ b/src/renderer/features/player/components/full-screen-player-image.tsx @@ -11,10 +11,10 @@ import { Badge, Text, TextTitle } from '/@/renderer/components'; import { useFastAverageColor } from '/@/renderer/hooks'; import { AppRoute } from '/@/renderer/router/routes'; import { - PlayerData, - useFullScreenPlayerStore, - usePlayerData, - usePlayerStore, + PlayerData, + useFullScreenPlayerStore, + usePlayerData, + usePlayerStore, } from '/@/renderer/store'; const Image = styled(motion.img)<{ $useAspectRatio: boolean }>` @@ -28,247 +28,249 @@ const Image = styled(motion.img)<{ $useAspectRatio: boolean }>` `; const ImageContainer = styled(motion.div)` - position: relative; - display: flex; - align-items: flex-end; - max-width: 100%; - aspect-ratio: 1/1; - height: 65%; - margin-bottom: 1rem; + position: relative; + display: flex; + align-items: flex-end; + max-width: 100%; + aspect-ratio: 1/1; + height: 65%; + margin-bottom: 1rem; `; const MetadataContainer = styled(Stack)` - h1 { - font-size: 3.5vh; - } + h1 { + font-size: 3.5vh; + } `; const PlayerContainer = styled(Flex)` - @media screen and (max-height: 640px) { - .full-screen-player-image-metadata { - display: none; - height: 100%; - margin-bottom: 0; - } + @media screen and (max-height: 640px) { + .full-screen-player-image-metadata { + display: none; + height: 100%; + margin-bottom: 0; + } - ${ImageContainer} { - height: 100%; - margin-bottom: 0; + ${ImageContainer} { + height: 100%; + margin-bottom: 0; + } } - } `; const imageVariants: Variants = { - closed: { - opacity: 0, - transition: { - duration: 0.8, - ease: 'linear', + closed: { + opacity: 0, + transition: { + duration: 0.8, + ease: 'linear', + }, + }, + initial: { + opacity: 0, + }, + open: (custom) => { + const { isOpen } = custom; + return { + opacity: isOpen ? 1 : 0, + transition: { + duration: 0.4, + ease: 'linear', + }, + }; }, - }, - initial: { - opacity: 0, - }, - open: (custom) => { - const { isOpen } = custom; - return { - opacity: isOpen ? 1 : 0, - transition: { - duration: 0.4, - ease: 'linear', - }, - }; - }, }; const scaleImageUrl = (url?: string | null) => { - return url - ?.replace(/&size=\d+/, '&size=500') - .replace(/\?width=\d+/, '?width=500') - .replace(/&height=\d+/, '&height=500'); + return url + ?.replace(/&size=\d+/, '&size=500') + .replace(/\?width=\d+/, '?width=500') + .replace(/&height=\d+/, '&height=500'); }; const ImageWithPlaceholder = ({ - useAspectRatio, - ...props + useAspectRatio, + ...props }: HTMLMotionProps<'img'> & { useAspectRatio: boolean }) => { - if (!props.src) { - return ( - <Center - sx={{ - background: 'var(--placeholder-bg)', - borderRadius: 'var(--card-default-radius)', - height: '100%', - width: '100%', - }} - > - <RiAlbumFill - color="var(--placeholder-fg)" - size="25%" - /> - </Center> - ); - } + if (!props.src) { + return ( + <Center + sx={{ + background: 'var(--placeholder-bg)', + borderRadius: 'var(--card-default-radius)', + height: '100%', + width: '100%', + }} + > + <RiAlbumFill + color="var(--placeholder-fg)" + size="25%" + /> + </Center> + ); + } - return ( - <Image - $useAspectRatio={useAspectRatio} - {...props} - /> - ); + return ( + <Image + $useAspectRatio={useAspectRatio} + {...props} + /> + ); }; export const FullScreenPlayerImage = () => { - const { queue } = usePlayerData(); - const useImageAspectRatio = useFullScreenPlayerStore((state) => state.useImageAspectRatio); - const currentSong = queue.current; - const background = useFastAverageColor(queue.current?.imageUrl, true, 'dominant'); - const imageKey = `image-${background}`; + const { queue } = usePlayerData(); + const useImageAspectRatio = useFullScreenPlayerStore((state) => state.useImageAspectRatio); + const currentSong = queue.current; + const background = useFastAverageColor(queue.current?.imageUrl, true, 'dominant'); + const imageKey = `image-${background}`; - const [imageState, setImageState] = useSetState({ - bottomImage: scaleImageUrl(queue.next?.imageUrl), - current: 0, - topImage: scaleImageUrl(queue.current?.imageUrl), - }); + const [imageState, setImageState] = useSetState({ + bottomImage: scaleImageUrl(queue.next?.imageUrl), + current: 0, + topImage: scaleImageUrl(queue.current?.imageUrl), + }); - useEffect(() => { - const unsubSongChange = usePlayerStore.subscribe( - (state) => [state.current.song, state.actions.getPlayerData().queue], - (state) => { - const isTop = imageState.current === 0; - const queue = state[1] as PlayerData['queue']; + useEffect(() => { + const unsubSongChange = usePlayerStore.subscribe( + (state) => [state.current.song, state.actions.getPlayerData().queue], + (state) => { + const isTop = imageState.current === 0; + const queue = state[1] as PlayerData['queue']; - const currentImageUrl = scaleImageUrl(queue.current?.imageUrl); - const nextImageUrl = scaleImageUrl(queue.next?.imageUrl); + const currentImageUrl = scaleImageUrl(queue.current?.imageUrl); + const nextImageUrl = scaleImageUrl(queue.next?.imageUrl); - setImageState({ - bottomImage: isTop ? currentImageUrl : nextImageUrl, - current: isTop ? 1 : 0, - topImage: isTop ? nextImageUrl : currentImageUrl, - }); - }, - { equalityFn: (a, b) => (a[0] as QueueSong)?.id === (b[0] as QueueSong)?.id }, - ); + setImageState({ + bottomImage: isTop ? currentImageUrl : nextImageUrl, + current: isTop ? 1 : 0, + topImage: isTop ? nextImageUrl : currentImageUrl, + }); + }, + { equalityFn: (a, b) => (a[0] as QueueSong)?.id === (b[0] as QueueSong)?.id }, + ); - return () => { - unsubSongChange(); - }; - }, [imageState, queue, setImageState]); + return () => { + unsubSongChange(); + }; + }, [imageState, queue, setImageState]); - return ( - <PlayerContainer - align="center" - className="full-screen-player-image-container" - direction="column" - justify="flex-start" - p="1rem" - > - <ImageContainer> - <AnimatePresence - initial={false} - mode="sync" - > - {imageState.current === 0 && ( - <ImageWithPlaceholder - key={imageKey} - animate="open" - className="full-screen-player-image" - custom={{ isOpen: imageState.current === 0 }} - draggable={false} - exit="closed" - initial="closed" - placeholder="var(--placeholder-bg)" - src={imageState.topImage || ''} - useAspectRatio={useImageAspectRatio} - variants={imageVariants} - /> - )} - - {imageState.current === 1 && ( - <ImageWithPlaceholder - key={imageKey} - animate="open" - className="full-screen-player-image" - custom={{ isOpen: imageState.current === 1 }} - draggable={false} - exit="closed" - initial="closed" - placeholder="var(--placeholder-bg)" - src={imageState.bottomImage || ''} - useAspectRatio={useImageAspectRatio} - variants={imageVariants} - /> - )} - </AnimatePresence> - </ImageContainer> - <MetadataContainer - className="full-screen-player-image-metadata" - maw="100%" - spacing="xs" - > - <TextTitle - align="center" - order={1} - overflow="hidden" - w="100%" - weight={900} - > - {currentSong?.name} - </TextTitle> - <TextTitle - $link - $secondary - align="center" - component={Link} - order={2} - overflow="hidden" - to={generatePath(AppRoute.LIBRARY_ALBUMS_DETAIL, { - albumId: currentSong?.albumId || '', - })} - w="100%" - weight={600} - > - {currentSong?.album}{' '} - </TextTitle> - {currentSong?.artists?.map((artist, index) => ( - <TextTitle - key={`fs-artist-${artist.id}`} - $secondary + return ( + <PlayerContainer align="center" - order={4} - > - {index > 0 && ( - <Text - sx={{ - display: 'inline-block', - padding: '0 0.5rem', - }} - > - • - </Text> - )} - <Text - $link - $secondary - component={Link} - to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, { - albumArtistId: artist.id, - })} - weight={600} + className="full-screen-player-image-container" + direction="column" + justify="flex-start" + p="1rem" + > + <ImageContainer> + <AnimatePresence + initial={false} + mode="sync" + > + {imageState.current === 0 && ( + <ImageWithPlaceholder + key={imageKey} + animate="open" + className="full-screen-player-image" + custom={{ isOpen: imageState.current === 0 }} + draggable={false} + exit="closed" + initial="closed" + placeholder="var(--placeholder-bg)" + src={imageState.topImage || ''} + useAspectRatio={useImageAspectRatio} + variants={imageVariants} + /> + )} + + {imageState.current === 1 && ( + <ImageWithPlaceholder + key={imageKey} + animate="open" + className="full-screen-player-image" + custom={{ isOpen: imageState.current === 1 }} + draggable={false} + exit="closed" + initial="closed" + placeholder="var(--placeholder-bg)" + src={imageState.bottomImage || ''} + useAspectRatio={useImageAspectRatio} + variants={imageVariants} + /> + )} + </AnimatePresence> + </ImageContainer> + <MetadataContainer + className="full-screen-player-image-metadata" + maw="100%" + spacing="xs" > - {artist.name} - </Text> - </TextTitle> - ))} - <Group position="center"> - {currentSong?.container && ( - <Badge size="lg"> - {currentSong?.container} {currentSong?.bitRate} - </Badge> - )} - {currentSong?.releaseYear && <Badge size="lg">{currentSong?.releaseYear}</Badge>} - </Group> - </MetadataContainer> - </PlayerContainer> - ); + <TextTitle + align="center" + order={1} + overflow="hidden" + w="100%" + weight={900} + > + {currentSong?.name} + </TextTitle> + <TextTitle + $link + $secondary + align="center" + component={Link} + order={2} + overflow="hidden" + to={generatePath(AppRoute.LIBRARY_ALBUMS_DETAIL, { + albumId: currentSong?.albumId || '', + })} + w="100%" + weight={600} + > + {currentSong?.album}{' '} + </TextTitle> + {currentSong?.artists?.map((artist, index) => ( + <TextTitle + key={`fs-artist-${artist.id}`} + $secondary + align="center" + order={4} + > + {index > 0 && ( + <Text + sx={{ + display: 'inline-block', + padding: '0 0.5rem', + }} + > + • + </Text> + )} + <Text + $link + $secondary + component={Link} + to={generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, { + albumArtistId: artist.id, + })} + weight={600} + > + {artist.name} + </Text> + </TextTitle> + ))} + <Group position="center"> + {currentSong?.container && ( + <Badge size="lg"> + {currentSong?.container} {currentSong?.bitRate} + </Badge> + )} + {currentSong?.releaseYear && ( + <Badge size="lg">{currentSong?.releaseYear}</Badge> + )} + </Group> + </MetadataContainer> + </PlayerContainer> + ); }; diff --git a/src/renderer/features/player/components/full-screen-player-queue.tsx b/src/renderer/features/player/components/full-screen-player-queue.tsx index e15b709c..00db00f6 100644 --- a/src/renderer/features/player/components/full-screen-player-queue.tsx +++ b/src/renderer/features/player/components/full-screen-player-queue.tsx @@ -6,122 +6,122 @@ import styled from 'styled-components'; import { Button, TextTitle } from '/@/renderer/components'; import { PlayQueue } from '/@/renderer/features/now-playing'; import { - useFullScreenPlayerStore, - useFullScreenPlayerStoreActions, + useFullScreenPlayerStore, + useFullScreenPlayerStoreActions, } from '/@/renderer/store/full-screen-player.store'; import { Lyrics } from '/@/renderer/features/lyrics/lyrics'; const QueueContainer = styled.div` - position: relative; - display: flex; - height: 100%; + position: relative; + display: flex; + height: 100%; - .ag-theme-alpine-dark { - --ag-header-background-color: rgba(0, 0, 0, 0%) !important; - --ag-background-color: rgba(0, 0, 0, 0%) !important; - --ag-odd-row-background-color: rgba(0, 0, 0, 0%) !important; - } + .ag-theme-alpine-dark { + --ag-header-background-color: rgba(0, 0, 0, 0%) !important; + --ag-background-color: rgba(0, 0, 0, 0%) !important; + --ag-odd-row-background-color: rgba(0, 0, 0, 0%) !important; + } - .ag-header { - display: none !important; - } + .ag-header { + display: none !important; + } `; const ActiveTabIndicator = styled(motion.div)` - position: absolute; - bottom: 0; - left: 0; - width: 100%; - height: 2px; - background: var(--main-fg); + position: absolute; + bottom: 0; + left: 0; + width: 100%; + height: 2px; + background: var(--main-fg); `; const HeaderItemWrapper = styled.div` - position: relative; - z-index: 2; + position: relative; + z-index: 2; `; const GridContainer = styled.div` - display: grid; - grid-template-rows: auto minmax(0, 1fr); - grid-template-columns: 1fr; + display: grid; + grid-template-rows: auto minmax(0, 1fr); + grid-template-columns: 1fr; `; export const FullScreenPlayerQueue = () => { - const { activeTab } = useFullScreenPlayerStore(); - const { setStore } = useFullScreenPlayerStoreActions(); + const { activeTab } = useFullScreenPlayerStore(); + const { setStore } = useFullScreenPlayerStoreActions(); - const headerItems = [ - { - active: activeTab === 'queue', - icon: <RiFileMusicLine size="1.5rem" />, - label: 'Up Next', - onClick: () => setStore({ activeTab: 'queue' }), - }, - { - active: activeTab === 'related', - icon: <HiOutlineQueueList size="1.5rem" />, - label: 'Related', - onClick: () => setStore({ activeTab: 'related' }), - }, - { - active: activeTab === 'lyrics', - icon: <RiFileTextLine size="1.5rem" />, - label: 'Lyrics', - onClick: () => setStore({ activeTab: 'lyrics' }), - }, - ]; + const headerItems = [ + { + active: activeTab === 'queue', + icon: <RiFileMusicLine size="1.5rem" />, + label: 'Up Next', + onClick: () => setStore({ activeTab: 'queue' }), + }, + { + active: activeTab === 'related', + icon: <HiOutlineQueueList size="1.5rem" />, + label: 'Related', + onClick: () => setStore({ activeTab: 'related' }), + }, + { + active: activeTab === 'lyrics', + icon: <RiFileTextLine size="1.5rem" />, + label: 'Lyrics', + onClick: () => setStore({ activeTab: 'lyrics' }), + }, + ]; - return ( - <GridContainer className="full-screen-player-queue-container"> - <Group - grow - align="center" - position="center" - > - {headerItems.map((item) => ( - <HeaderItemWrapper key={`tab-${item.label}`}> - <Button - fullWidth - uppercase - fw="600" - pos="relative" - size="lg" - sx={{ - alignItems: 'center', - color: item.active - ? 'var(--main-fg) !important' - : 'var(--main-fg-secondary) !important', - letterSpacing: '1px', - }} - variant="subtle" - onClick={item.onClick} + return ( + <GridContainer className="full-screen-player-queue-container"> + <Group + grow + align="center" + position="center" > - {item.label} - </Button> - {item.active ? <ActiveTabIndicator layoutId="underline" /> : null} - </HeaderItemWrapper> - ))} - </Group> - {activeTab === 'queue' ? ( - <QueueContainer> - <PlayQueue type="fullScreen" /> - </QueueContainer> - ) : activeTab === 'related' ? ( - <Center> - <Group> - <RiInformationFill size="2rem" /> - <TextTitle - order={3} - weight={700} - > - COMING SOON - </TextTitle> - </Group> - </Center> - ) : activeTab === 'lyrics' ? ( - <Lyrics /> - ) : null} - </GridContainer> - ); + {headerItems.map((item) => ( + <HeaderItemWrapper key={`tab-${item.label}`}> + <Button + fullWidth + uppercase + fw="600" + pos="relative" + size="lg" + sx={{ + alignItems: 'center', + color: item.active + ? 'var(--main-fg) !important' + : 'var(--main-fg-secondary) !important', + letterSpacing: '1px', + }} + variant="subtle" + onClick={item.onClick} + > + {item.label} + </Button> + {item.active ? <ActiveTabIndicator layoutId="underline" /> : null} + </HeaderItemWrapper> + ))} + </Group> + {activeTab === 'queue' ? ( + <QueueContainer> + <PlayQueue type="fullScreen" /> + </QueueContainer> + ) : activeTab === 'related' ? ( + <Center> + <Group> + <RiInformationFill size="2rem" /> + <TextTitle + order={3} + weight={700} + > + COMING SOON + </TextTitle> + </Group> + </Center> + ) : activeTab === 'lyrics' ? ( + <Lyrics /> + ) : null} + </GridContainer> + ); }; diff --git a/src/renderer/features/player/components/full-screen-player.tsx b/src/renderer/features/player/components/full-screen-player.tsx index 20f72042..c16f72de 100644 --- a/src/renderer/features/player/components/full-screen-player.tsx +++ b/src/renderer/features/player/components/full-screen-player.tsx @@ -7,10 +7,10 @@ import { useLocation } from 'react-router'; import styled from 'styled-components'; import { Button, Option, Popover, Switch } from '/@/renderer/components'; import { - useCurrentSong, - useFullScreenPlayerStore, - useFullScreenPlayerStoreActions, - useWindowSettings, + useCurrentSong, + useFullScreenPlayerStore, + useFullScreenPlayerStoreActions, + useWindowSettings, } from '/@/renderer/store'; import { useFastAverageColor } from '../../../hooks/use-fast-average-color'; import { FullScreenPlayerImage } from '/@/renderer/features/player/components/full-screen-player-image'; @@ -19,197 +19,197 @@ import { TableConfigDropdown } from '/@/renderer/components/virtual-table'; import { Platform } from '/@/renderer/types'; const Container = styled(motion.div)` - position: absolute; - top: 0; - left: 0; - z-index: 200; - display: flex; - justify-content: center; - padding: 2rem; + position: absolute; + top: 0; + left: 0; + z-index: 200; + display: flex; + justify-content: center; + padding: 2rem; - @media screen and (max-width: 768px) { - padding: 2rem 2rem 1rem; - } + @media screen and (max-width: 768px) { + padding: 2rem 2rem 1rem; + } `; const ResponsiveContainer = styled.div` - display: grid; - grid-template-rows: minmax(0, 1fr); - grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); - gap: 2rem 2rem; - width: 100%; - max-width: 2560px; - margin-top: 5rem; + display: grid; + grid-template-rows: minmax(0, 1fr); + grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); + gap: 2rem 2rem; + width: 100%; + max-width: 2560px; + margin-top: 5rem; - @media screen and (max-width: 768px) { - grid-template-rows: minmax(0, 1fr) minmax(0, 1fr); - grid-template-columns: minmax(0, 1fr); - margin-top: 0; - } + @media screen and (max-width: 768px) { + grid-template-rows: minmax(0, 1fr) minmax(0, 1fr); + grid-template-columns: minmax(0, 1fr); + margin-top: 0; + } `; const BackgroundImageOverlay = styled.div` - position: absolute; - top: 0; - left: 0; - z-index: -1; - width: 100%; - height: 100%; - background: linear-gradient(180deg, rgba(20, 21, 23, 40%), var(--main-bg)); + position: absolute; + top: 0; + left: 0; + z-index: -1; + width: 100%; + height: 100%; + background: linear-gradient(180deg, rgba(20, 21, 23, 40%), var(--main-bg)); `; const Controls = () => { - const { dynamicBackground, expanded, useImageAspectRatio } = useFullScreenPlayerStore(); - const { setStore } = useFullScreenPlayerStoreActions(); + const { dynamicBackground, expanded, useImageAspectRatio } = useFullScreenPlayerStore(); + const { setStore } = useFullScreenPlayerStoreActions(); - const handleToggleFullScreenPlayer = () => { - setStore({ expanded: !expanded }); - }; + const handleToggleFullScreenPlayer = () => { + setStore({ expanded: !expanded }); + }; - useHotkeys([['Escape', handleToggleFullScreenPlayer]]); + useHotkeys([['Escape', handleToggleFullScreenPlayer]]); - return ( - <Group - p="1rem" - pos="absolute" - spacing="sm" - sx={{ - left: 0, - top: 10, - }} - > - <Button - compact - size="sm" - tooltip={{ label: 'Minimize' }} - variant="subtle" - onClick={handleToggleFullScreenPlayer} - > - <RiArrowDownSLine size="2rem" /> - </Button> - <Popover position="bottom-start"> - <Popover.Target> - <Button - compact - size="sm" - tooltip={{ label: 'Configure' }} - variant="subtle" - > - <RiSettings3Line size="1.5rem" /> - </Button> - </Popover.Target> - <Popover.Dropdown> - <Option> - <Option.Label>Dynamic Background</Option.Label> - <Option.Control> - <Switch - defaultChecked={dynamicBackground} - onChange={(e) => - setStore({ - dynamicBackground: e.target.checked, - }) - } - /> - </Option.Control> - </Option> - <Option> - <Option.Label>Use image aspect ratio</Option.Label> - <Option.Control> - <Switch - defaultChecked={useImageAspectRatio} - onChange={(e) => - setStore({ - useImageAspectRatio: e.target.checked, - }) - } - /> - </Option.Control> - </Option> - <TableConfigDropdown type="fullScreen" /> - </Popover.Dropdown> - </Popover> - </Group> - ); + return ( + <Group + p="1rem" + pos="absolute" + spacing="sm" + sx={{ + left: 0, + top: 10, + }} + > + <Button + compact + size="sm" + tooltip={{ label: 'Minimize' }} + variant="subtle" + onClick={handleToggleFullScreenPlayer} + > + <RiArrowDownSLine size="2rem" /> + </Button> + <Popover position="bottom-start"> + <Popover.Target> + <Button + compact + size="sm" + tooltip={{ label: 'Configure' }} + variant="subtle" + > + <RiSettings3Line size="1.5rem" /> + </Button> + </Popover.Target> + <Popover.Dropdown> + <Option> + <Option.Label>Dynamic Background</Option.Label> + <Option.Control> + <Switch + defaultChecked={dynamicBackground} + onChange={(e) => + setStore({ + dynamicBackground: e.target.checked, + }) + } + /> + </Option.Control> + </Option> + <Option> + <Option.Label>Use image aspect ratio</Option.Label> + <Option.Control> + <Switch + defaultChecked={useImageAspectRatio} + onChange={(e) => + setStore({ + useImageAspectRatio: e.target.checked, + }) + } + /> + </Option.Control> + </Option> + <TableConfigDropdown type="fullScreen" /> + </Popover.Dropdown> + </Popover> + </Group> + ); }; const containerVariants: Variants = { - closed: (custom) => { - const { windowBarStyle } = custom; - return { - height: - windowBarStyle === Platform.WINDOWS || windowBarStyle === Platform.MACOS - ? 'calc(100vh - 120px)' - : 'calc(100vh - 90px)', - position: 'absolute', - top: '100vh', - transition: { - duration: 0.5, - ease: 'easeInOut', - }, - width: '100vw', - y: -100, - }; - }, - open: (custom) => { - const { dynamicBackground, background, windowBarStyle } = custom; - return { - background: dynamicBackground ? background : 'var(--main-bg)', - height: - windowBarStyle === Platform.WINDOWS || windowBarStyle === Platform.MACOS - ? 'calc(100vh - 120px)' - : 'calc(100vh - 90px)', - left: 0, - position: 'absolute', - top: 0, - transition: { - background: { - duration: 0.5, - ease: 'easeInOut', - }, - delay: 0.1, - duration: 0.5, - ease: 'easeInOut', - }, - width: '100vw', - y: 0, - }; - }, + closed: (custom) => { + const { windowBarStyle } = custom; + return { + height: + windowBarStyle === Platform.WINDOWS || windowBarStyle === Platform.MACOS + ? 'calc(100vh - 120px)' + : 'calc(100vh - 90px)', + position: 'absolute', + top: '100vh', + transition: { + duration: 0.5, + ease: 'easeInOut', + }, + width: '100vw', + y: -100, + }; + }, + open: (custom) => { + const { dynamicBackground, background, windowBarStyle } = custom; + return { + background: dynamicBackground ? background : 'var(--main-bg)', + height: + windowBarStyle === Platform.WINDOWS || windowBarStyle === Platform.MACOS + ? 'calc(100vh - 120px)' + : 'calc(100vh - 90px)', + left: 0, + position: 'absolute', + top: 0, + transition: { + background: { + duration: 0.5, + ease: 'easeInOut', + }, + delay: 0.1, + duration: 0.5, + ease: 'easeInOut', + }, + width: '100vw', + y: 0, + }; + }, }; export const FullScreenPlayer = () => { - const { dynamicBackground } = useFullScreenPlayerStore(); - const { setStore } = useFullScreenPlayerStoreActions(); - const { windowBarStyle } = useWindowSettings(); + const { dynamicBackground } = useFullScreenPlayerStore(); + const { setStore } = useFullScreenPlayerStoreActions(); + const { windowBarStyle } = useWindowSettings(); - const location = useLocation(); - const isOpenedRef = useRef<boolean | null>(null); + const location = useLocation(); + const isOpenedRef = useRef<boolean | null>(null); - useLayoutEffect(() => { - if (isOpenedRef.current !== null) { - setStore({ expanded: false }); - } + useLayoutEffect(() => { + if (isOpenedRef.current !== null) { + setStore({ expanded: false }); + } - isOpenedRef.current = true; - }, [location, setStore]); + isOpenedRef.current = true; + }, [location, setStore]); - const currentSong = useCurrentSong(); - const background = useFastAverageColor(currentSong?.imageUrl, true, 'dominant'); + const currentSong = useCurrentSong(); + const background = useFastAverageColor(currentSong?.imageUrl, true, 'dominant'); - return ( - <Container - animate="open" - custom={{ background, dynamicBackground, windowBarStyle }} - exit="closed" - initial="closed" - transition={{ duration: 2 }} - variants={containerVariants} - > - <Controls /> - {dynamicBackground && <BackgroundImageOverlay />} - <ResponsiveContainer> - <FullScreenPlayerImage /> - <FullScreenPlayerQueue /> - </ResponsiveContainer> - </Container> - ); + return ( + <Container + animate="open" + custom={{ background, dynamicBackground, windowBarStyle }} + exit="closed" + initial="closed" + transition={{ duration: 2 }} + variants={containerVariants} + > + <Controls /> + {dynamicBackground && <BackgroundImageOverlay />} + <ResponsiveContainer> + <FullScreenPlayerImage /> + <FullScreenPlayerQueue /> + </ResponsiveContainer> + </Container> + ); }; diff --git a/src/renderer/features/player/components/left-controls.tsx b/src/renderer/features/player/components/left-controls.tsx index d3278c03..15000743 100644 --- a/src/renderer/features/player/components/left-controls.tsx +++ b/src/renderer/features/player/components/left-controls.tsx @@ -8,12 +8,12 @@ import styled from 'styled-components'; import { Button, Text, Tooltip } from '/@/renderer/components'; import { AppRoute } from '/@/renderer/router/routes'; import { - useAppStoreActions, - useCurrentSong, - useSetFullScreenPlayerStore, - useFullScreenPlayerStore, - useSidebarStore, - useHotkeySettings, + useAppStoreActions, + useCurrentSong, + useSetFullScreenPlayerStore, + useFullScreenPlayerStore, + useSidebarStore, + useHotkeySettings, } from '/@/renderer/store'; import { fadeIn } from '/@/renderer/styles'; import { LibraryItem } from '/@/renderer/api/types'; @@ -21,254 +21,261 @@ import { SONG_CONTEXT_MENU_ITEMS } from '/@/renderer/features/context-menu/conte import { useHandleGeneralContextMenu } from '/@/renderer/features/context-menu/hooks/use-handle-context-menu'; const ImageWrapper = styled.div` - position: relative; - display: flex; - align-items: center; - justify-content: center; - padding: 1rem 1rem 1rem 0; + position: relative; + display: flex; + align-items: center; + justify-content: center; + padding: 1rem 1rem 1rem 0; `; const MetadataStack = styled(motion.div)` - display: flex; - flex-direction: column; - gap: 0; - justify-content: center; - width: 100%; - overflow: hidden; + display: flex; + flex-direction: column; + gap: 0; + justify-content: center; + width: 100%; + overflow: hidden; `; const Image = styled(motion.div)` - position: relative; - width: 60px; - height: 60px; - background-color: var(--placeholder-bg); - cursor: pointer; - filter: drop-shadow(0 5px 6px rgb(0, 0, 0, 50%)); + position: relative; + width: 60px; + height: 60px; + background-color: var(--placeholder-bg); + cursor: pointer; + filter: drop-shadow(0 5px 6px rgb(0, 0, 0, 50%)); - ${fadeIn}; - animation: fadein 0.2s ease-in-out; + ${fadeIn}; + animation: fadein 0.2s ease-in-out; - button { - display: none; - } + button { + display: none; + } - &:hover button { - display: block; - } + &:hover button { + display: block; + } `; const PlayerbarImage = styled.img` - width: 100%; - height: 100%; - object-fit: cover; + width: 100%; + height: 100%; + object-fit: cover; `; const LineItem = styled.div<{ $secondary?: boolean }>` - display: inline-block; - width: 95%; - max-width: 20vw; - overflow: hidden; - color: ${(props) => props.$secondary && 'var(--main-fg-secondary)'}; - line-height: 1.3; - white-space: nowrap; - text-overflow: ellipsis; + display: inline-block; + width: 95%; + max-width: 20vw; + overflow: hidden; + color: ${(props) => props.$secondary && 'var(--main-fg-secondary)'}; + line-height: 1.3; + white-space: nowrap; + text-overflow: ellipsis; - a { - color: ${(props) => props.$secondary && 'var(--text-secondary)'}; - } + a { + color: ${(props) => props.$secondary && 'var(--text-secondary)'}; + } `; const LeftControlsContainer = styled.div` - display: flex; - width: 100%; - height: 100%; - padding-left: 1rem; + display: flex; + width: 100%; + height: 100%; + padding-left: 1rem; - @media (max-width: 640px) { - ${ImageWrapper} { - display: none; + @media (max-width: 640px) { + ${ImageWrapper} { + display: none; + } } - } `; export const LeftControls = () => { - const { setSideBar } = useAppStoreActions(); - const { expanded: isFullScreenPlayerExpanded } = useFullScreenPlayerStore(); - const setFullScreenPlayerStore = useSetFullScreenPlayerStore(); - const { image, collapsed } = useSidebarStore(); - const hideImage = image && !collapsed; - const currentSong = useCurrentSong(); - const title = currentSong?.name; - const artists = currentSong?.artists; - const { bindings } = useHotkeySettings(); + const { setSideBar } = useAppStoreActions(); + const { expanded: isFullScreenPlayerExpanded } = useFullScreenPlayerStore(); + const setFullScreenPlayerStore = useSetFullScreenPlayerStore(); + const { image, collapsed } = useSidebarStore(); + const hideImage = image && !collapsed; + const currentSong = useCurrentSong(); + const title = currentSong?.name; + const artists = currentSong?.artists; + const { bindings } = useHotkeySettings(); - const isSongDefined = Boolean(currentSong?.id); + const isSongDefined = Boolean(currentSong?.id); - const handleGeneralContextMenu = useHandleGeneralContextMenu( - LibraryItem.SONG, - SONG_CONTEXT_MENU_ITEMS, - ); + const handleGeneralContextMenu = useHandleGeneralContextMenu( + LibraryItem.SONG, + SONG_CONTEXT_MENU_ITEMS, + ); - const handleToggleFullScreenPlayer = (e?: MouseEvent<HTMLDivElement> | KeyboardEvent) => { - e?.stopPropagation(); - setFullScreenPlayerStore({ expanded: !isFullScreenPlayerExpanded }); - }; + const handleToggleFullScreenPlayer = (e?: MouseEvent<HTMLDivElement> | KeyboardEvent) => { + e?.stopPropagation(); + setFullScreenPlayerStore({ expanded: !isFullScreenPlayerExpanded }); + }; - const handleToggleSidebarImage = (e?: MouseEvent<HTMLButtonElement>) => { - e?.stopPropagation(); - setSideBar({ image: true }); - }; + const handleToggleSidebarImage = (e?: MouseEvent<HTMLButtonElement>) => { + e?.stopPropagation(); + setSideBar({ image: true }); + }; - useHotkeys([ - [ - bindings.toggleFullscreenPlayer.allowGlobal ? '' : bindings.toggleFullscreenPlayer.hotkey, - handleToggleFullScreenPlayer, - ], - ]); + useHotkeys([ + [ + bindings.toggleFullscreenPlayer.allowGlobal + ? '' + : bindings.toggleFullscreenPlayer.hotkey, + handleToggleFullScreenPlayer, + ], + ]); - return ( - <LeftControlsContainer> - <LayoutGroup> - <AnimatePresence - initial={false} - mode="wait" - > - {!hideImage && ( - <ImageWrapper> - <Image - key="playerbar-image" - animate={{ opacity: 1, scale: 1, x: 0 }} - exit={{ opacity: 0, x: -50 }} - initial={{ opacity: 0, x: -50 }} - role="button" - transition={{ duration: 0.3, ease: 'easeInOut' }} - onClick={handleToggleFullScreenPlayer} - > - <Tooltip - label="Toggle fullscreen player" - openDelay={500} + return ( + <LeftControlsContainer> + <LayoutGroup> + <AnimatePresence + initial={false} + mode="wait" > - {currentSong?.imageUrl ? ( - <PlayerbarImage - loading="eager" - src={currentSong?.imageUrl} - /> - ) : ( - <Center - sx={{ - background: 'var(--placeholder-bg)', - height: '100%', - }} - > - <RiDiscLine - color="var(--placeholder-fg)" - size={50} - /> - </Center> - )} - </Tooltip> + {!hideImage && ( + <ImageWrapper> + <Image + key="playerbar-image" + animate={{ opacity: 1, scale: 1, x: 0 }} + exit={{ opacity: 0, x: -50 }} + initial={{ opacity: 0, x: -50 }} + role="button" + transition={{ duration: 0.3, ease: 'easeInOut' }} + onClick={handleToggleFullScreenPlayer} + > + <Tooltip + label="Toggle fullscreen player" + openDelay={500} + > + {currentSong?.imageUrl ? ( + <PlayerbarImage + loading="eager" + src={currentSong?.imageUrl} + /> + ) : ( + <Center + sx={{ + background: 'var(--placeholder-bg)', + height: '100%', + }} + > + <RiDiscLine + color="var(--placeholder-fg)" + size={50} + /> + </Center> + )} + </Tooltip> - {!collapsed && ( - <Button - compact - opacity={0.8} - radius={50} - size="md" - sx={{ cursor: 'default', position: 'absolute', right: 2, top: 2 }} - tooltip={{ label: 'Expand', openDelay: 500 }} - variant="default" - onClick={handleToggleSidebarImage} - > - <RiArrowUpSLine - color="white" - size={20} - /> - </Button> - )} - </Image> - </ImageWrapper> - )} - </AnimatePresence> - <MetadataStack layout="position"> - <LineItem> - <Group - noWrap - align="flex-start" - spacing="xs" - > - <Text - $link - component={Link} - overflow="hidden" - size="md" - to={AppRoute.NOW_PLAYING} - weight={500} - > - {title || '—'} - </Text> - {isSongDefined && ( - <Button - compact - variant="subtle" - onClick={(e) => handleGeneralContextMenu(e, [currentSong!])} - > - <RiMore2Fill size="1.2rem" /> - </Button> - )} - </Group> - </LineItem> - <LineItem $secondary> - {artists?.map((artist, index) => ( - <React.Fragment key={`bar-${artist.id}`}> - {index > 0 && ( - <Text - $link - $secondary - size="md" - style={{ display: 'inline-block' }} - > - , - </Text> - )}{' '} - <Text - $link - component={Link} - overflow="hidden" - size="md" - to={ - artist.id - ? generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, { - albumArtistId: artist.id, - }) - : '' - } - weight={500} - > - {artist.name || '—'} - </Text> - </React.Fragment> - ))} - </LineItem> - <LineItem $secondary> - <Text - $link - component={Link} - overflow="hidden" - size="md" - to={ - currentSong?.albumId - ? generatePath(AppRoute.LIBRARY_ALBUMS_DETAIL, { - albumId: currentSong.albumId, - }) - : '' - } - weight={500} - > - {currentSong?.album || '—'} - </Text> - </LineItem> - </MetadataStack> - </LayoutGroup> - </LeftControlsContainer> - ); + {!collapsed && ( + <Button + compact + opacity={0.8} + radius={50} + size="md" + sx={{ + cursor: 'default', + position: 'absolute', + right: 2, + top: 2, + }} + tooltip={{ label: 'Expand', openDelay: 500 }} + variant="default" + onClick={handleToggleSidebarImage} + > + <RiArrowUpSLine + color="white" + size={20} + /> + </Button> + )} + </Image> + </ImageWrapper> + )} + </AnimatePresence> + <MetadataStack layout="position"> + <LineItem> + <Group + noWrap + align="flex-start" + spacing="xs" + > + <Text + $link + component={Link} + overflow="hidden" + size="md" + to={AppRoute.NOW_PLAYING} + weight={500} + > + {title || '—'} + </Text> + {isSongDefined && ( + <Button + compact + variant="subtle" + onClick={(e) => handleGeneralContextMenu(e, [currentSong!])} + > + <RiMore2Fill size="1.2rem" /> + </Button> + )} + </Group> + </LineItem> + <LineItem $secondary> + {artists?.map((artist, index) => ( + <React.Fragment key={`bar-${artist.id}`}> + {index > 0 && ( + <Text + $link + $secondary + size="md" + style={{ display: 'inline-block' }} + > + , + </Text> + )}{' '} + <Text + $link + component={Link} + overflow="hidden" + size="md" + to={ + artist.id + ? generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, { + albumArtistId: artist.id, + }) + : '' + } + weight={500} + > + {artist.name || '—'} + </Text> + </React.Fragment> + ))} + </LineItem> + <LineItem $secondary> + <Text + $link + component={Link} + overflow="hidden" + size="md" + to={ + currentSong?.albumId + ? generatePath(AppRoute.LIBRARY_ALBUMS_DETAIL, { + albumId: currentSong.albumId, + }) + : '' + } + weight={500} + > + {currentSong?.album || '—'} + </Text> + </LineItem> + </MetadataStack> + </LayoutGroup> + </LeftControlsContainer> + ); }; diff --git a/src/renderer/features/player/components/player-button.tsx b/src/renderer/features/player/components/player-button.tsx index 60768d7e..51314508 100644 --- a/src/renderer/features/player/components/player-button.tsx +++ b/src/renderer/features/player/components/player-button.tsx @@ -8,153 +8,154 @@ import { Tooltip } from '/@/renderer/components'; type MantineButtonProps = UnstyledButtonProps & ComponentPropsWithoutRef<'button'>; interface PlayerButtonProps extends MantineButtonProps { - $isActive?: boolean; - icon: ReactNode; - tooltip?: Omit<TooltipProps, 'children'>; - variant: 'main' | 'secondary' | 'tertiary'; + $isActive?: boolean; + icon: ReactNode; + tooltip?: Omit<TooltipProps, 'children'>; + variant: 'main' | 'secondary' | 'tertiary'; } const WrapperMainVariant = css` - margin: 0 0.5rem; + margin: 0 0.5rem; `; type MotionWrapperProps = { variant: PlayerButtonProps['variant'] }; const MotionWrapper = styled(motion.div)<MotionWrapperProps>` - display: flex; - align-items: center; - justify-content: center; + display: flex; + align-items: center; + justify-content: center; - ${({ variant }) => variant === 'main' && WrapperMainVariant}; + ${({ variant }) => variant === 'main' && WrapperMainVariant}; `; const ButtonMainVariant = css` - padding: 0.5rem; - background: var(--playerbar-btn-main-bg); - border-radius: 50%; - - svg { - display: flex; - fill: var(--playerbar-btn-main-fg); - } - - &:focus-visible { - background: var(--playerbar-btn-main-bg-hover); - } - - &:hover { - background: var(--playerbar-btn-main-bg-hover); + padding: 0.5rem; + background: var(--playerbar-btn-main-bg); + border-radius: 50%; svg { - fill: var(--playerbar-btn-main-fg-hover); + display: flex; + fill: var(--playerbar-btn-main-fg); + } + + &:focus-visible { + background: var(--playerbar-btn-main-bg-hover); + } + + &:hover { + background: var(--playerbar-btn-main-bg-hover); + + svg { + fill: var(--playerbar-btn-main-fg-hover); + } } - } `; const ButtonSecondaryVariant = css` - padding: 0.5rem; + padding: 0.5rem; `; const ButtonTertiaryVariant = css` - padding: 0.5rem; + padding: 0.5rem; - svg { - display: flex; - } - - &:focus-visible { svg { - fill: var(--playerbar-btn-fg-hover); - stroke: var(--playerbar-btn-fg-hover); + display: flex; + } + + &:focus-visible { + svg { + fill: var(--playerbar-btn-fg-hover); + stroke: var(--playerbar-btn-fg-hover); + } } - } `; type StyledPlayerButtonProps = Omit<PlayerButtonProps, 'icon'>; const StyledPlayerButton = styled(UnstyledButton)<StyledPlayerButtonProps>` - display: flex; - align-items: center; - width: 100%; - padding: 0.5rem; - overflow: visible; - background: var(--playerbar-btn-bg-hover); - all: unset; - cursor: default; - - button { display: flex; - } - - &:focus-visible { + align-items: center; + width: 100%; + padding: 0.5rem; + overflow: visible; background: var(--playerbar-btn-bg-hover); - outline: 1px var(--primary-color) solid; - } + all: unset; + cursor: default; - &:disabled { - opacity: 0.5; - } + button { + display: flex; + } - svg { - display: flex; - fill: ${({ $isActive }) => ($isActive ? 'var(--primary-color)' : 'var(--playerbar-btn-fg)')}; - stroke: var(--playerbar-btn-fg); - } + &:focus-visible { + background: var(--playerbar-btn-bg-hover); + outline: 1px var(--primary-color) solid; + } - &:hover { - background: var(--playerbar-btn-bg-hover); + &:disabled { + opacity: 0.5; + } svg { - fill: ${({ $isActive }) => - $isActive ? 'var(--primary-color)' : 'var(--playerbar-btn-fg-hover)'}; + display: flex; + fill: ${({ $isActive }) => + $isActive ? 'var(--primary-color)' : 'var(--playerbar-btn-fg)'}; + stroke: var(--playerbar-btn-fg); } - } - ${({ variant }) => - variant === 'main' - ? ButtonMainVariant - : variant === 'secondary' - ? ButtonSecondaryVariant - : ButtonTertiaryVariant}; + &:hover { + background: var(--playerbar-btn-bg-hover); + + svg { + fill: ${({ $isActive }) => + $isActive ? 'var(--primary-color)' : 'var(--playerbar-btn-fg-hover)'}; + } + } + + ${({ variant }) => + variant === 'main' + ? ButtonMainVariant + : variant === 'secondary' + ? ButtonSecondaryVariant + : ButtonTertiaryVariant}; `; export const PlayerButton = forwardRef<HTMLDivElement, PlayerButtonProps>( - ({ tooltip, variant, icon, ...rest }: PlayerButtonProps, ref) => { - if (tooltip) { - return ( - <Tooltip {...tooltip}> - <MotionWrapper - ref={ref} - variant={variant} - > - <StyledPlayerButton - variant={variant} - {...rest} - > - {icon} - </StyledPlayerButton> - </MotionWrapper> - </Tooltip> - ); - } + ({ tooltip, variant, icon, ...rest }: PlayerButtonProps, ref) => { + if (tooltip) { + return ( + <Tooltip {...tooltip}> + <MotionWrapper + ref={ref} + variant={variant} + > + <StyledPlayerButton + variant={variant} + {...rest} + > + {icon} + </StyledPlayerButton> + </MotionWrapper> + </Tooltip> + ); + } - return ( - <MotionWrapper - ref={ref} - variant={variant} - > - <StyledPlayerButton - variant={variant} - {...rest} - > - {icon} - </StyledPlayerButton> - </MotionWrapper> - ); - }, + return ( + <MotionWrapper + ref={ref} + variant={variant} + > + <StyledPlayerButton + variant={variant} + {...rest} + > + {icon} + </StyledPlayerButton> + </MotionWrapper> + ); + }, ); PlayerButton.defaultProps = { - $isActive: false, - tooltip: undefined, + $isActive: false, + tooltip: undefined, }; diff --git a/src/renderer/features/player/components/playerbar-slider.tsx b/src/renderer/features/player/components/playerbar-slider.tsx index af401907..6313cf89 100644 --- a/src/renderer/features/player/components/playerbar-slider.tsx +++ b/src/renderer/features/player/components/playerbar-slider.tsx @@ -1,46 +1,46 @@ import { rem, Slider, SliderProps } from '@mantine/core'; export const PlayerbarSlider = ({ ...props }: SliderProps) => { - return ( - <Slider - styles={{ - bar: { - backgroundColor: 'var(--playerbar-slider-track-progress-bg)', - transition: 'background-color 0.2s ease', - }, - label: { - backgroundColor: 'var(--tooltip-bg)', - color: 'var(--tooltip-fg)', - fontSize: '1.1rem', - fontWeight: 600, - padding: '0 1rem', - }, - root: { - '&:hover': { - '& .mantine-Slider-bar': { - backgroundColor: 'var(--primary-color)', - }, - '& .mantine-Slider-thumb': { - opacity: 1, - }, - }, - }, - thumb: { - backgroundColor: 'var(--slider-thumb-bg)', - borderColor: 'var(--primary-color)', - borderWidth: rem(1), - height: '1rem', - opacity: 0, - width: '1rem', - }, - track: { - '&::before': { - backgroundColor: 'var(--playerbar-slider-track-bg)', - right: 'calc(0.1rem * -1)', - }, - }, - }} - {...props} - /> - ); + return ( + <Slider + styles={{ + bar: { + backgroundColor: 'var(--playerbar-slider-track-progress-bg)', + transition: 'background-color 0.2s ease', + }, + label: { + backgroundColor: 'var(--tooltip-bg)', + color: 'var(--tooltip-fg)', + fontSize: '1.1rem', + fontWeight: 600, + padding: '0 1rem', + }, + root: { + '&:hover': { + '& .mantine-Slider-bar': { + backgroundColor: 'var(--primary-color)', + }, + '& .mantine-Slider-thumb': { + opacity: 1, + }, + }, + }, + thumb: { + backgroundColor: 'var(--slider-thumb-bg)', + borderColor: 'var(--primary-color)', + borderWidth: rem(1), + height: '1rem', + opacity: 0, + width: '1rem', + }, + track: { + '&::before': { + backgroundColor: 'var(--playerbar-slider-track-bg)', + right: 'calc(0.1rem * -1)', + }, + }, + }} + {...props} + /> + ); }; diff --git a/src/renderer/features/player/components/playerbar.tsx b/src/renderer/features/player/components/playerbar.tsx index 67a0a155..54cb8f86 100644 --- a/src/renderer/features/player/components/playerbar.tsx +++ b/src/renderer/features/player/components/playerbar.tsx @@ -5,13 +5,13 @@ import { useSettingsStore } from '/@/renderer/store/settings.store'; import { PlaybackType } from '/@/renderer/types'; import { AudioPlayer } from '/@/renderer/components'; import { - useCurrentPlayer, - useCurrentStatus, - useMuted, - usePlayer1Data, - usePlayer2Data, - usePlayerControls, - useVolume, + useCurrentPlayer, + useCurrentStatus, + useMuted, + usePlayer1Data, + usePlayer2Data, + usePlayerControls, + useVolume, } from '/@/renderer/store'; import { CenterControls } from './center-controls'; import { LeftControls } from './left-controls'; @@ -19,97 +19,97 @@ import { RightControls } from './right-controls'; import { PlayersRef } from '/@/renderer/features/player/ref/players-ref'; const PlayerbarContainer = styled.div` - width: 100vw; - height: 100%; - border-top: var(--playerbar-border-top); + width: 100vw; + height: 100%; + border-top: var(--playerbar-border-top); `; const PlayerbarControlsGrid = styled.div` - display: grid; - grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr); - gap: 1rem; - height: 100%; + display: grid; + grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr); + gap: 1rem; + height: 100%; - @media (max-width: 768px) { - grid-template-columns: minmax(0, 0.5fr) minmax(0, 1fr) minmax(0, 0.5fr); - } + @media (max-width: 768px) { + grid-template-columns: minmax(0, 0.5fr) minmax(0, 1fr) minmax(0, 0.5fr); + } `; const RightGridItem = styled.div` - align-self: center; - width: 100%; - height: 100%; - overflow: hidden; + align-self: center; + width: 100%; + height: 100%; + overflow: hidden; `; const LeftGridItem = styled.div` - width: 100%; - height: 100%; - overflow: hidden; + width: 100%; + height: 100%; + overflow: hidden; `; const CenterGridItem = styled.div` - display: flex; - flex-direction: column; - gap: 0.5rem; - align-items: center; - justify-content: center; - width: 100%; - height: 100%; - overflow: hidden; + display: flex; + flex-direction: column; + gap: 0.5rem; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + overflow: hidden; `; const utils = isElectron() ? window.electron.utils : null; const mpris = isElectron() && utils?.isLinux() ? window.electron.mpris : null; export const Playerbar = () => { - const playersRef = PlayersRef; - const settings = useSettingsStore((state) => state.playback); - const volume = useVolume(); - const player1 = usePlayer1Data(); - const player2 = usePlayer2Data(); - const status = useCurrentStatus(); - const player = useCurrentPlayer(); - const muted = useMuted(); - const { autoNext } = usePlayerControls(); + const playersRef = PlayersRef; + const settings = useSettingsStore((state) => state.playback); + const volume = useVolume(); + const player1 = usePlayer1Data(); + const player2 = usePlayer2Data(); + const status = useCurrentStatus(); + const player = useCurrentPlayer(); + const muted = useMuted(); + const { autoNext } = usePlayerControls(); - const autoNextFn = useCallback(() => { - const playerData = autoNext(); - mpris?.updateSong({ - currentTime: 0, - song: playerData.current.song, - }); - }, [autoNext]); + const autoNextFn = useCallback(() => { + const playerData = autoNext(); + mpris?.updateSong({ + currentTime: 0, + song: playerData.current.song, + }); + }, [autoNext]); - return ( - <PlayerbarContainer> - <PlayerbarControlsGrid> - <LeftGridItem> - <LeftControls /> - </LeftGridItem> - <CenterGridItem> - <CenterControls playersRef={playersRef} /> - </CenterGridItem> - <RightGridItem> - <RightControls /> - </RightGridItem> - </PlayerbarControlsGrid> - {settings.type === PlaybackType.WEB && ( - <AudioPlayer - ref={playersRef} - autoNext={autoNextFn} - crossfadeDuration={settings.crossfadeDuration} - crossfadeStyle={settings.crossfadeStyle} - currentPlayer={player} - muted={muted} - playbackStyle={settings.style} - player1={player1} - player2={player2} - status={status} - style={settings.style} - volume={(volume / 100) ** 2} - /> - )} - </PlayerbarContainer> - ); + return ( + <PlayerbarContainer> + <PlayerbarControlsGrid> + <LeftGridItem> + <LeftControls /> + </LeftGridItem> + <CenterGridItem> + <CenterControls playersRef={playersRef} /> + </CenterGridItem> + <RightGridItem> + <RightControls /> + </RightGridItem> + </PlayerbarControlsGrid> + {settings.type === PlaybackType.WEB && ( + <AudioPlayer + ref={playersRef} + autoNext={autoNextFn} + crossfadeDuration={settings.crossfadeDuration} + crossfadeStyle={settings.crossfadeStyle} + currentPlayer={player} + muted={muted} + playbackStyle={settings.style} + player1={player1} + player2={player2} + status={status} + style={settings.style} + volume={(volume / 100) ** 2} + /> + )} + </PlayerbarContainer> + ); }; diff --git a/src/renderer/features/player/components/right-controls.tsx b/src/renderer/features/player/components/right-controls.tsx index d87f20fd..2d3ac95b 100644 --- a/src/renderer/features/player/components/right-controls.tsx +++ b/src/renderer/features/player/components/right-controls.tsx @@ -3,20 +3,20 @@ import { Flex, Group } from '@mantine/core'; import { useHotkeys, useMediaQuery } from '@mantine/hooks'; import { HiOutlineQueueList } from 'react-icons/hi2'; import { - RiVolumeUpFill, - RiVolumeDownFill, - RiVolumeMuteFill, - RiHeartLine, - RiHeartFill, + RiVolumeUpFill, + RiVolumeDownFill, + RiVolumeMuteFill, + RiHeartLine, + RiHeartFill, } from 'react-icons/ri'; import { - useAppStoreActions, - useCurrentServer, - useCurrentSong, - useHotkeySettings, - useMuted, - useSidebarStore, - useVolume, + useAppStoreActions, + useCurrentServer, + useCurrentSong, + useHotkeySettings, + useMuted, + useSidebarStore, + useVolume, } from '/@/renderer/store'; import { useRightControls } from '../hooks/use-right-controls'; import { PlayerButton } from './player-button'; @@ -26,178 +26,180 @@ import { Rating } from '/@/renderer/components'; import { PlayerbarSlider } from '/@/renderer/features/player/components/playerbar-slider'; export const RightControls = () => { - const isMinWidth = useMediaQuery('(max-width: 480px)'); - const volume = useVolume(); - const muted = useMuted(); - const server = useCurrentServer(); - const currentSong = useCurrentSong(); - const { setSideBar } = useAppStoreActions(); - const { rightExpanded: isQueueExpanded } = useSidebarStore(); - const { bindings } = useHotkeySettings(); - const { handleVolumeSlider, handleVolumeWheel, handleMute, handleVolumeDown, handleVolumeUp } = - useRightControls(); + const isMinWidth = useMediaQuery('(max-width: 480px)'); + const volume = useVolume(); + const muted = useMuted(); + const server = useCurrentServer(); + const currentSong = useCurrentSong(); + const { setSideBar } = useAppStoreActions(); + const { rightExpanded: isQueueExpanded } = useSidebarStore(); + const { bindings } = useHotkeySettings(); + const { handleVolumeSlider, handleVolumeWheel, handleMute, handleVolumeDown, handleVolumeUp } = + useRightControls(); - const updateRatingMutation = useSetRating({}); - const addToFavoritesMutation = useCreateFavorite({}); - const removeFromFavoritesMutation = useDeleteFavorite({}); + const updateRatingMutation = useSetRating({}); + const addToFavoritesMutation = useCreateFavorite({}); + const removeFromFavoritesMutation = useDeleteFavorite({}); - const handleAddToFavorites = () => { - if (!currentSong) return; + const handleAddToFavorites = () => { + if (!currentSong) return; - addToFavoritesMutation.mutate({ - query: { - id: [currentSong.id], - type: LibraryItem.SONG, - }, - serverId: currentSong?.serverId, - }); - }; - - const handleUpdateRating = (rating: number) => { - if (!currentSong) return; - - updateRatingMutation.mutate({ - query: { - item: [currentSong], - rating, - }, - serverId: currentSong?.serverId, - }); - }; - - const handleClearRating = (_e: MouseEvent<HTMLDivElement>, rating?: number) => { - if (!currentSong || !rating) return; - - updateRatingMutation.mutate({ - query: { - item: [currentSong], - rating: 0, - }, - serverId: currentSong?.serverId, - }); - }; - - const handleRemoveFromFavorites = () => { - if (!currentSong) return; - - removeFromFavoritesMutation.mutate({ - query: { - id: [currentSong.id], - type: LibraryItem.SONG, - }, - serverId: currentSong?.serverId, - }); - }; - - const handleToggleFavorite = () => { - if (!currentSong) return; - - if (currentSong.userFavorite) { - handleRemoveFromFavorites(); - } else { - handleAddToFavorites(); - } - }; - - const handleToggleQueue = () => { - setSideBar({ rightExpanded: !isQueueExpanded }); - }; - - const isSongDefined = Boolean(currentSong?.id); - const showRating = isSongDefined && server?.type === ServerType.NAVIDROME; - - useHotkeys([ - [bindings.volumeDown.isGlobal ? '' : bindings.volumeDown.hotkey, handleVolumeDown], - [bindings.volumeUp.isGlobal ? '' : bindings.volumeUp.hotkey, handleVolumeUp], - [bindings.volumeMute.isGlobal ? '' : bindings.volumeMute.hotkey, handleMute], - [bindings.toggleQueue.isGlobal ? '' : bindings.toggleQueue.hotkey, handleToggleQueue], - ]); - - return ( - <Flex - align="flex-end" - direction="column" - h="100%" - px="1rem" - py="0.5rem" - > - <Group h="calc(100% / 3)"> - {showRating && ( - <Rating - size="sm" - value={currentSong?.userRating || 0} - onChange={handleUpdateRating} - onClick={handleClearRating} - /> - )} - </Group> - <Group - noWrap - align="center" - spacing="xs" - > - <PlayerButton - icon={ - currentSong?.userFavorite ? ( - <RiHeartFill - color="var(--primary-color)" - size="1.1rem" - /> - ) : ( - <RiHeartLine size="1.1rem" /> - ) - } - sx={{ - svg: { - fill: !currentSong?.userFavorite ? undefined : 'var(--primary-color) !important', + addToFavoritesMutation.mutate({ + query: { + id: [currentSong.id], + type: LibraryItem.SONG, }, - }} - tooltip={{ - label: currentSong?.userFavorite ? 'Unfavorite' : 'Favorite', - openDelay: 500, - }} - variant="secondary" - onClick={handleToggleFavorite} - /> - <PlayerButton - icon={<HiOutlineQueueList size="1.1rem" />} - tooltip={{ label: 'View queue', openDelay: 500 }} - variant="secondary" - onClick={handleToggleQueue} - /> - <Group - noWrap - spacing="xs" + serverId: currentSong?.serverId, + }); + }; + + const handleUpdateRating = (rating: number) => { + if (!currentSong) return; + + updateRatingMutation.mutate({ + query: { + item: [currentSong], + rating, + }, + serverId: currentSong?.serverId, + }); + }; + + const handleClearRating = (_e: MouseEvent<HTMLDivElement>, rating?: number) => { + if (!currentSong || !rating) return; + + updateRatingMutation.mutate({ + query: { + item: [currentSong], + rating: 0, + }, + serverId: currentSong?.serverId, + }); + }; + + const handleRemoveFromFavorites = () => { + if (!currentSong) return; + + removeFromFavoritesMutation.mutate({ + query: { + id: [currentSong.id], + type: LibraryItem.SONG, + }, + serverId: currentSong?.serverId, + }); + }; + + const handleToggleFavorite = () => { + if (!currentSong) return; + + if (currentSong.userFavorite) { + handleRemoveFromFavorites(); + } else { + handleAddToFavorites(); + } + }; + + const handleToggleQueue = () => { + setSideBar({ rightExpanded: !isQueueExpanded }); + }; + + const isSongDefined = Boolean(currentSong?.id); + const showRating = isSongDefined && server?.type === ServerType.NAVIDROME; + + useHotkeys([ + [bindings.volumeDown.isGlobal ? '' : bindings.volumeDown.hotkey, handleVolumeDown], + [bindings.volumeUp.isGlobal ? '' : bindings.volumeUp.hotkey, handleVolumeUp], + [bindings.volumeMute.isGlobal ? '' : bindings.volumeMute.hotkey, handleMute], + [bindings.toggleQueue.isGlobal ? '' : bindings.toggleQueue.hotkey, handleToggleQueue], + ]); + + return ( + <Flex + align="flex-end" + direction="column" + h="100%" + px="1rem" + py="0.5rem" > - <PlayerButton - icon={ - muted ? ( - <RiVolumeMuteFill size="1.2rem" /> - ) : volume > 50 ? ( - <RiVolumeUpFill size="1.2rem" /> - ) : ( - <RiVolumeDownFill size="1.2rem" /> - ) - } - tooltip={{ label: muted ? 'Muted' : volume, openDelay: 500 }} - variant="secondary" - onClick={handleMute} - onWheel={handleVolumeWheel} - /> - {!isMinWidth ? ( - <PlayerbarSlider - max={100} - min={0} - size={6} - value={volume} - w="60px" - onChange={handleVolumeSlider} - onWheel={handleVolumeWheel} - /> - ) : null} - </Group> - </Group> - <Group h="calc(100% / 3)" /> - </Flex> - ); + <Group h="calc(100% / 3)"> + {showRating && ( + <Rating + size="sm" + value={currentSong?.userRating || 0} + onChange={handleUpdateRating} + onClick={handleClearRating} + /> + )} + </Group> + <Group + noWrap + align="center" + spacing="xs" + > + <PlayerButton + icon={ + currentSong?.userFavorite ? ( + <RiHeartFill + color="var(--primary-color)" + size="1.1rem" + /> + ) : ( + <RiHeartLine size="1.1rem" /> + ) + } + sx={{ + svg: { + fill: !currentSong?.userFavorite + ? undefined + : 'var(--primary-color) !important', + }, + }} + tooltip={{ + label: currentSong?.userFavorite ? 'Unfavorite' : 'Favorite', + openDelay: 500, + }} + variant="secondary" + onClick={handleToggleFavorite} + /> + <PlayerButton + icon={<HiOutlineQueueList size="1.1rem" />} + tooltip={{ label: 'View queue', openDelay: 500 }} + variant="secondary" + onClick={handleToggleQueue} + /> + <Group + noWrap + spacing="xs" + > + <PlayerButton + icon={ + muted ? ( + <RiVolumeMuteFill size="1.2rem" /> + ) : volume > 50 ? ( + <RiVolumeUpFill size="1.2rem" /> + ) : ( + <RiVolumeDownFill size="1.2rem" /> + ) + } + tooltip={{ label: muted ? 'Muted' : volume, openDelay: 500 }} + variant="secondary" + onClick={handleMute} + onWheel={handleVolumeWheel} + /> + {!isMinWidth ? ( + <PlayerbarSlider + max={100} + min={0} + size={6} + value={volume} + w="60px" + onChange={handleVolumeSlider} + onWheel={handleVolumeWheel} + /> + ) : null} + </Group> + </Group> + <Group h="calc(100% / 3)" /> + </Flex> + ); }; diff --git a/src/renderer/features/player/components/shuffle-all-modal.tsx b/src/renderer/features/player/components/shuffle-all-modal.tsx index 7ec1c725..694ecc90 100644 --- a/src/renderer/features/player/components/shuffle-all-modal.tsx +++ b/src/renderer/features/player/components/shuffle-all-modal.tsx @@ -9,10 +9,10 @@ import { create } from 'zustand'; import { persist } from 'zustand/middleware'; import { immer } from 'zustand/middleware/immer'; import { - GenreListResponse, - RandomSongListQuery, - MusicFolderListResponse, - ServerType, + GenreListResponse, + RandomSongListQuery, + MusicFolderListResponse, + ServerType, } from '/@/renderer/api/types'; import { api } from '/@/renderer/api'; import { useAuthStore } from '/@/renderer/store'; @@ -20,240 +20,240 @@ import { queryKeys } from '/@/renderer/api/query-keys'; import { Play, PlayQueueAddOptions, ServerListItem } from '/@/renderer/types'; interface ShuffleAllSlice extends RandomSongListQuery { - actions: { - setStore: (data: Partial<ShuffleAllSlice>) => void; - }; - enableMaxYear: boolean; - enableMinYear: boolean; + actions: { + setStore: (data: Partial<ShuffleAllSlice>) => void; + }; + enableMaxYear: boolean; + enableMinYear: boolean; } const useShuffleAllStore = create<ShuffleAllSlice>()( - persist( - immer((set, get) => ({ - actions: { - setStore: (data) => { - set({ ...get(), ...data }); + persist( + immer((set, get) => ({ + actions: { + setStore: (data) => { + set({ ...get(), ...data }); + }, + }, + enableMaxYear: false, + enableMinYear: false, + genre: '', + maxYear: 2020, + minYear: 2000, + musicFolder: '', + songCount: 100, + })), + { + merge: (persistedState, currentState) => merge(currentState, persistedState), + name: 'store_shuffle_all', + version: 1, }, - }, - enableMaxYear: false, - enableMinYear: false, - genre: '', - maxYear: 2020, - minYear: 2000, - musicFolder: '', - songCount: 100, - })), - { - merge: (persistedState, currentState) => merge(currentState, persistedState), - name: 'store_shuffle_all', - version: 1, - }, - ), + ), ); export const useShuffleAllStoreActions = () => useShuffleAllStore((state) => state.actions); interface ShuffleAllModalProps { - genres: GenreListResponse | undefined; - handlePlayQueueAdd: ((options: PlayQueueAddOptions) => void) | undefined; - musicFolders: MusicFolderListResponse | undefined; - queryClient: QueryClient; - server: ServerListItem | null; + genres: GenreListResponse | undefined; + handlePlayQueueAdd: ((options: PlayQueueAddOptions) => void) | undefined; + musicFolders: MusicFolderListResponse | undefined; + queryClient: QueryClient; + server: ServerListItem | null; } export const ShuffleAllModal = ({ - handlePlayQueueAdd, - queryClient, - server, - genres, - musicFolders, + handlePlayQueueAdd, + queryClient, + server, + genres, + musicFolders, }: ShuffleAllModalProps) => { - const { genre, limit, maxYear, minYear, enableMaxYear, enableMinYear, musicFolderId } = - useShuffleAllStore(); - const { setStore } = useShuffleAllStoreActions(); + const { genre, limit, maxYear, minYear, enableMaxYear, enableMinYear, musicFolderId } = + useShuffleAllStore(); + const { setStore } = useShuffleAllStoreActions(); - const handlePlay = async (playType: Play) => { - const res = await queryClient.fetchQuery({ - cacheTime: 0, - queryFn: ({ signal }) => - api.controller.getRandomSongList({ - apiClientProps: { - server, - signal, - }, - query: { - genre: genre || undefined, - limit, - maxYear: enableMaxYear ? maxYear || undefined : undefined, - minYear: enableMinYear ? minYear || undefined : undefined, - musicFolderId: musicFolderId || undefined, - }, - }), - queryKey: queryKeys.songs.randomSongList(server?.id), - staleTime: 0, - }); + const handlePlay = async (playType: Play) => { + const res = await queryClient.fetchQuery({ + cacheTime: 0, + queryFn: ({ signal }) => + api.controller.getRandomSongList({ + apiClientProps: { + server, + signal, + }, + query: { + genre: genre || undefined, + limit, + maxYear: enableMaxYear ? maxYear || undefined : undefined, + minYear: enableMinYear ? minYear || undefined : undefined, + musicFolderId: musicFolderId || undefined, + }, + }), + queryKey: queryKeys.songs.randomSongList(server?.id), + staleTime: 0, + }); - handlePlayQueueAdd?.({ - byData: res?.items || [], - playType, - }); + handlePlayQueueAdd?.({ + byData: res?.items || [], + playType, + }); - closeAllModals(); - }; + closeAllModals(); + }; - const genreData = useMemo(() => { - if (!genres) return []; + const genreData = useMemo(() => { + if (!genres) return []; - return genres.items.map((genre) => { - const value = - server?.type === ServerType.NAVIDROME || server?.type === ServerType.SUBSONIC - ? genre.name - : genre.id; - return { - label: genre.name, - value, - }; - }); - }, [genres, server?.type]); + return genres.items.map((genre) => { + const value = + server?.type === ServerType.NAVIDROME || server?.type === ServerType.SUBSONIC + ? genre.name + : genre.id; + return { + label: genre.name, + value, + }; + }); + }, [genres, server?.type]); - const musicFolderData = useMemo(() => { - if (!musicFolders) return []; - return musicFolders.items.map((musicFolder) => ({ - label: musicFolder.name, - value: String(musicFolder.id), - })); - }, [musicFolders]); + const musicFolderData = useMemo(() => { + if (!musicFolders) return []; + return musicFolders.items.map((musicFolder) => ({ + label: musicFolder.name, + value: String(musicFolder.id), + })); + }, [musicFolders]); - return ( - <Stack spacing="md"> - <NumberInput - required - label="How many tracks?" - max={500} - min={1} - value={limit} - onChange={(e) => setStore({ limit: e ? Number(e) : 0 })} - /> - <Group grow> - <NumberInput - label="From year" - max={2050} - min={1850} - rightSection={ - <Checkbox - checked={enableMinYear} - mr="0.5rem" - onChange={(e) => setStore({ enableMinYear: e.currentTarget.checked })} + return ( + <Stack spacing="md"> + <NumberInput + required + label="How many tracks?" + max={500} + min={1} + value={limit} + onChange={(e) => setStore({ limit: e ? Number(e) : 0 })} /> - } - value={minYear} - onChange={(e) => setStore({ minYear: e ? Number(e) : 0 })} - /> + <Group grow> + <NumberInput + label="From year" + max={2050} + min={1850} + rightSection={ + <Checkbox + checked={enableMinYear} + mr="0.5rem" + onChange={(e) => setStore({ enableMinYear: e.currentTarget.checked })} + /> + } + value={minYear} + onChange={(e) => setStore({ minYear: e ? Number(e) : 0 })} + /> - <NumberInput - label="To year" - max={2050} - min={1850} - rightSection={ - <Checkbox - checked={enableMaxYear} - mr="0.5rem" - onChange={(e) => setStore({ enableMaxYear: e.currentTarget.checked })} + <NumberInput + label="To year" + max={2050} + min={1850} + rightSection={ + <Checkbox + checked={enableMaxYear} + mr="0.5rem" + onChange={(e) => setStore({ enableMaxYear: e.currentTarget.checked })} + /> + } + value={maxYear} + onChange={(e) => setStore({ maxYear: e ? Number(e) : 0 })} + /> + </Group> + <Select + clearable + data={genreData} + label="Genre" + value={genre} + onChange={(e) => setStore({ genre: e || '' })} /> - } - value={maxYear} - onChange={(e) => setStore({ maxYear: e ? Number(e) : 0 })} - /> - </Group> - <Select - clearable - data={genreData} - label="Genre" - value={genre} - onChange={(e) => setStore({ genre: e || '' })} - /> - <Select - clearable - data={musicFolderData} - label="Music folder" - value={musicFolderId} - onChange={(e) => { - setStore({ musicFolderId: e ? String(e) : '' }); - }} - /> - <Divider /> - <Group grow> - <Button - leftIcon={<RiAddBoxFill size="1rem" />} - type="submit" - variant="default" - onClick={() => handlePlay(Play.LAST)} - > - Add - </Button> - <Button - leftIcon={<RiAddCircleFill size="1rem" />} - type="submit" - variant="default" - onClick={() => handlePlay(Play.NEXT)} - > - Add next - </Button> - </Group> - <Button - leftIcon={<RiPlayFill size="1rem" />} - type="submit" - variant="filled" - onClick={() => handlePlay(Play.NOW)} - > - Play - </Button> - </Stack> - ); + <Select + clearable + data={musicFolderData} + label="Music folder" + value={musicFolderId} + onChange={(e) => { + setStore({ musicFolderId: e ? String(e) : '' }); + }} + /> + <Divider /> + <Group grow> + <Button + leftIcon={<RiAddBoxFill size="1rem" />} + type="submit" + variant="default" + onClick={() => handlePlay(Play.LAST)} + > + Add + </Button> + <Button + leftIcon={<RiAddCircleFill size="1rem" />} + type="submit" + variant="default" + onClick={() => handlePlay(Play.NEXT)} + > + Add next + </Button> + </Group> + <Button + leftIcon={<RiPlayFill size="1rem" />} + type="submit" + variant="filled" + onClick={() => handlePlay(Play.NOW)} + > + Play + </Button> + </Stack> + ); }; export const openShuffleAllModal = async ( - props: Pick<ShuffleAllModalProps, 'handlePlayQueueAdd' | 'queryClient'>, + props: Pick<ShuffleAllModalProps, 'handlePlayQueueAdd' | 'queryClient'>, ) => { - const server = useAuthStore.getState().currentServer; + const server = useAuthStore.getState().currentServer; - const genres = await props.queryClient.fetchQuery({ - cacheTime: 1000 * 60 * 60 * 4, - queryFn: ({ signal }) => - api.controller.getGenreList({ - apiClientProps: { - server, - signal, - }, - query: null, - }), - queryKey: queryKeys.genres.list(server?.id), - staleTime: 1000 * 60 * 5, - }); + const genres = await props.queryClient.fetchQuery({ + cacheTime: 1000 * 60 * 60 * 4, + queryFn: ({ signal }) => + api.controller.getGenreList({ + apiClientProps: { + server, + signal, + }, + query: null, + }), + queryKey: queryKeys.genres.list(server?.id), + staleTime: 1000 * 60 * 5, + }); - const musicFolders = await props.queryClient.fetchQuery({ - cacheTime: 1000 * 60 * 60 * 4, - queryFn: ({ signal }) => - api.controller.getMusicFolderList({ - apiClientProps: { - server, - signal, - }, - }), - queryKey: queryKeys.musicFolders.list(server?.id), - staleTime: 1000 * 60 * 5, - }); + const musicFolders = await props.queryClient.fetchQuery({ + cacheTime: 1000 * 60 * 60 * 4, + queryFn: ({ signal }) => + api.controller.getMusicFolderList({ + apiClientProps: { + server, + signal, + }, + }), + queryKey: queryKeys.musicFolders.list(server?.id), + staleTime: 1000 * 60 * 5, + }); - openModal({ - children: ( - <ShuffleAllModal - genres={genres} - musicFolders={musicFolders} - server={server} - {...props} - /> - ), - size: 'sm', - title: 'Shuffle all', - }); + openModal({ + children: ( + <ShuffleAllModal + genres={genres} + musicFolders={musicFolders} + server={server} + {...props} + /> + ), + size: 'sm', + title: 'Shuffle all', + }); }; diff --git a/src/renderer/features/player/context/play-queue-handler-context.ts b/src/renderer/features/player/context/play-queue-handler-context.ts index f322c070..ae1d0265 100644 --- a/src/renderer/features/player/context/play-queue-handler-context.ts +++ b/src/renderer/features/player/context/play-queue-handler-context.ts @@ -2,7 +2,7 @@ import { createContext } from 'react'; import { PlayQueueAddOptions } from '/@/renderer/types'; export const PlayQueueHandlerContext = createContext<{ - handlePlayQueueAdd: ((options: PlayQueueAddOptions) => void) | undefined; + handlePlayQueueAdd: ((options: PlayQueueAddOptions) => void) | undefined; }>({ - handlePlayQueueAdd: undefined, + handlePlayQueueAdd: undefined, }); diff --git a/src/renderer/features/player/hooks/use-center-controls.ts b/src/renderer/features/player/hooks/use-center-controls.ts index 80876230..2bb08c16 100644 --- a/src/renderer/features/player/hooks/use-center-controls.ts +++ b/src/renderer/features/player/hooks/use-center-controls.ts @@ -4,14 +4,14 @@ import { useCallback, useEffect } from 'react'; import isElectron from 'is-electron'; import { PlaybackType, PlayerRepeat, PlayerShuffle, PlayerStatus } from '/@/renderer/types'; import { - useCurrentPlayer, - useCurrentStatus, - useDefaultQueue, - usePlayerControls, - usePlayerStore, - useRepeatStatus, - useSetCurrentTime, - useShuffleStatus, + useCurrentPlayer, + useCurrentStatus, + useDefaultQueue, + usePlayerControls, + usePlayerStore, + useRepeatStatus, + useSetCurrentTime, + useShuffleStatus, } from '/@/renderer/store'; import { usePlayerType, useSettingsStore } from '/@/renderer/store/settings.store'; import { useScrobble } from '/@/renderer/features/player/hooks/use-scrobble'; @@ -27,787 +27,826 @@ const mpris = isElectron() && utils?.isLinux() ? window.electron.mpris : null; const mediaSession = !isElectron() || !utils?.isLinux() ? navigator.mediaSession : null; export const useCenterControls = (args: { playersRef: any }) => { - const { playersRef } = args; + const { playersRef } = args; - const settings = useSettingsStore((state) => state.playback); - const currentPlayer = useCurrentPlayer(); - const { setShuffle, setRepeat, play, pause, previous, next, setCurrentIndex, autoNext } = - usePlayerControls(); - const setCurrentTime = useSetCurrentTime(); - const queue = useDefaultQueue(); - const playerStatus = useCurrentStatus(); - const repeatStatus = useRepeatStatus(); - const shuffleStatus = useShuffleStatus(); - const playerType = usePlayerType(); - const player1Ref = playersRef?.current?.player1; - const player2Ref = playersRef?.current?.player2; - const currentPlayerRef = currentPlayer === 1 ? player1Ref : player2Ref; - const nextPlayerRef = currentPlayer === 1 ? player2Ref : player1Ref; + const settings = useSettingsStore((state) => state.playback); + const currentPlayer = useCurrentPlayer(); + const { setShuffle, setRepeat, play, pause, previous, next, setCurrentIndex, autoNext } = + usePlayerControls(); + const setCurrentTime = useSetCurrentTime(); + const queue = useDefaultQueue(); + const playerStatus = useCurrentStatus(); + const repeatStatus = useRepeatStatus(); + const shuffleStatus = useShuffleStatus(); + const playerType = usePlayerType(); + const player1Ref = playersRef?.current?.player1; + const player2Ref = playersRef?.current?.player2; + const currentPlayerRef = currentPlayer === 1 ? player1Ref : player2Ref; + const nextPlayerRef = currentPlayer === 1 ? player2Ref : player1Ref; - const { handleScrobbleFromSongRestart, handleScrobbleFromSeek } = useScrobble(); + const { handleScrobbleFromSongRestart, handleScrobbleFromSeek } = useScrobble(); - const resetPlayers = useCallback(() => { - if (player1Ref.getInternalPlayer()) { - player1Ref.getInternalPlayer().currentTime = 0; - player1Ref.getInternalPlayer().pause(); - } - - if (player2Ref.getInternalPlayer()) { - player2Ref.getInternalPlayer().currentTime = 0; - player2Ref.getInternalPlayer().pause(); - } - }, [player1Ref, player2Ref]); - - const resetNextPlayer = useCallback(() => { - currentPlayerRef.getInternalPlayer().volume = 0.1; - - const nextPlayer = nextPlayerRef.getInternalPlayer(); - if (nextPlayer) { - nextPlayer.currentTime = 0; - nextPlayer.pause(); - } - }, [currentPlayerRef, nextPlayerRef]); - - const stopPlayback = useCallback(() => { - player1Ref.getInternalPlayer().pause(); - player2Ref.getInternalPlayer().pause(); - resetPlayers(); - }, [player1Ref, player2Ref, resetPlayers]); - - const isMpvPlayer = isElectron() && settings.type === PlaybackType.LOCAL; - - const mprisUpdateSong = (args?: { - currentTime?: number; - song?: QueueSong; - status?: PlayerStatus; - }) => { - const { song, currentTime, status } = args || {}; - - const time = currentTime || usePlayerStore.getState().current.time; - const playStatus = status || usePlayerStore.getState().current.status; - const track = song || usePlayerStore.getState().current.song; - - mpris?.updateSong({ - currentTime: time, - repeat: usePlayerStore.getState().repeat, - shuffle: usePlayerStore.getState().shuffle, - song: track, - status: playStatus === PlayerStatus.PLAYING ? 'Playing' : 'Paused', - }); - - if (mediaSession) { - mediaSession.playbackState = playStatus === PlayerStatus.PLAYING ? 'playing' : 'paused'; - - let metadata: MediaMetadata; - - if (track) { - let artwork: MediaImage[]; - - if (track.imageUrl) { - const image300 = track.imageUrl - ?.replace(/&size=\d+/, '&size=300') - .replace(/\?width=\d+/, '?width=300') - .replace(/&height=\d+/, '&height=300'); - - artwork = [{ sizes: '300x300', src: image300, type: 'image/png' }]; - } else { - artwork = []; + const resetPlayers = useCallback(() => { + if (player1Ref.getInternalPlayer()) { + player1Ref.getInternalPlayer().currentTime = 0; + player1Ref.getInternalPlayer().pause(); } - metadata = new MediaMetadata({ - album: track.album ?? '', - artist: track.artistName, - artwork, - title: track.name, - }); - } else { - metadata = new MediaMetadata(); - } - - mediaSession.metadata = metadata; - } - }; - - const handlePlay = useCallback(() => { - mprisUpdateSong({ status: PlayerStatus.PLAYING }); - - if (isMpvPlayer) { - mpvPlayer?.volume(usePlayerStore.getState().volume); - mpvPlayer.play(); - } else { - currentPlayerRef.getInternalPlayer().play(); - } - - play(); - }, [currentPlayerRef, isMpvPlayer, play]); - - const handlePause = useCallback(() => { - mprisUpdateSong({ status: PlayerStatus.PAUSED }); - - if (isMpvPlayer) { - mpvPlayer.pause(); - } - - pause(); - }, [isMpvPlayer, pause]); - - const handleStop = useCallback(() => { - mprisUpdateSong({ status: PlayerStatus.PAUSED }); - - if (isMpvPlayer) { - mpvPlayer.pause(); - mpvPlayer.seekTo(0); - } else { - stopPlayback(); - } - - setCurrentTime(0); - pause(); - }, [isMpvPlayer, pause, setCurrentTime, stopPlayback]); - - const handleToggleShuffle = useCallback(() => { - if (shuffleStatus === PlayerShuffle.NONE) { - const playerData = setShuffle(PlayerShuffle.TRACK); - mpris?.updateShuffle(true); - return mpvPlayer.setQueueNext(playerData); - } - - const playerData = setShuffle(PlayerShuffle.NONE); - mpris?.updateShuffle(false); - return mpvPlayer.setQueueNext(playerData); - }, [setShuffle, shuffleStatus]); - - const handleToggleRepeat = useCallback(() => { - if (repeatStatus === PlayerRepeat.NONE) { - const playerData = setRepeat(PlayerRepeat.ALL); - mpris?.updateRepeat('Playlist'); - return mpvPlayer.setQueueNext(playerData); - } - - if (repeatStatus === PlayerRepeat.ALL) { - const playerData = setRepeat(PlayerRepeat.ONE); - mpris?.updateRepeat('Track'); - return mpvPlayer.setQueueNext(playerData); - } - - mpris?.updateRepeat('None'); - return setRepeat(PlayerRepeat.NONE); - }, [repeatStatus, setRepeat]); - - const checkIsLastTrack = useCallback(() => { - return usePlayerStore.getState().actions.checkIsLastTrack(); - }, []); - - const checkIsFirstTrack = useCallback(() => { - return usePlayerStore.getState().actions.checkIsFirstTrack(); - }, []); - - const handleAutoNext = useCallback(() => { - const isLastTrack = checkIsLastTrack(); - - const handleRepeatAll = { - local: () => { - const playerData = autoNext(); - mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); - mpvPlayer.autoNext(playerData); - play(); - }, - web: () => { - const playerData = autoNext(); - mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); - }, - }; - - const handleRepeatNone = { - local: () => { - if (isLastTrack) { - const playerData = setCurrentIndex(0); - mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PAUSED }); - mpvPlayer.setQueue(playerData, true); - pause(); - } else { - const playerData = autoNext(); - mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); - mpvPlayer.autoNext(playerData); - play(); + if (player2Ref.getInternalPlayer()) { + player2Ref.getInternalPlayer().currentTime = 0; + player2Ref.getInternalPlayer().pause(); } - }, - web: () => { - if (isLastTrack) { - resetPlayers(); - mprisUpdateSong({ status: PlayerStatus.PAUSED }); - pause(); - } else { - const playerData = autoNext(); - mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); - resetPlayers(); + }, [player1Ref, player2Ref]); + + const resetNextPlayer = useCallback(() => { + currentPlayerRef.getInternalPlayer().volume = 0.1; + + const nextPlayer = nextPlayerRef.getInternalPlayer(); + if (nextPlayer) { + nextPlayer.currentTime = 0; + nextPlayer.pause(); } - }, - }; + }, [currentPlayerRef, nextPlayerRef]); - const handleRepeatOne = { - local: () => { - const playerData = autoNext(); - mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); - mpvPlayer.autoNext(playerData); - play(); - }, - web: () => { - if (isLastTrack) { - mprisUpdateSong({ status: PlayerStatus.PAUSED }); - resetPlayers(); - } else { - const playerData = autoNext(); - mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); - resetPlayers(); - } - }, - }; - - switch (repeatStatus) { - case PlayerRepeat.NONE: - handleRepeatNone[playerType](); - break; - case PlayerRepeat.ALL: - handleRepeatAll[playerType](); - break; - case PlayerRepeat.ONE: - handleRepeatOne[playerType](); - break; - - default: - break; - } - }, [ - autoNext, - checkIsLastTrack, - pause, - play, - playerType, - repeatStatus, - resetPlayers, - setCurrentIndex, - ]); - - const handleNextTrack = useCallback(() => { - const isLastTrack = checkIsLastTrack(); - setCurrentTime(0); - - const handleRepeatAll = { - local: () => { - const playerData = next(); - mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); - mpvPlayer.setQueue(playerData); - mpvPlayer.next(); - }, - web: () => { - const playerData = next(); - mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); - }, - }; - - const handleRepeatNone = { - local: () => { - if (isLastTrack) { - const playerData = setCurrentIndex(0); - mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PAUSED }); - mpvPlayer.setQueue(playerData); - mpvPlayer.pause(); - pause(); - } else { - const playerData = next(); - mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); - mpvPlayer.setQueue(playerData); - mpvPlayer.next(); - } - }, - web: () => { - if (isLastTrack) { - const playerData = setCurrentIndex(0); - mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); - resetPlayers(); - pause(); - } else { - const playerData = next(); - mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); - resetPlayers(); - } - }, - }; - - const handleRepeatOne = { - local: () => { - const playerData = next(); - mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); - mpvPlayer.setQueue(playerData); - mpvPlayer.next(); - }, - web: () => { - if (!isLastTrack) { - const playerData = next(); - mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); - } - }, - }; - - switch (repeatStatus) { - case PlayerRepeat.NONE: - handleRepeatNone[playerType](); - break; - case PlayerRepeat.ALL: - handleRepeatAll[playerType](); - break; - case PlayerRepeat.ONE: - handleRepeatOne[playerType](); - break; - - default: - break; - } - - setCurrentTime(0); - }, [ - checkIsLastTrack, - next, - pause, - playerType, - repeatStatus, - resetPlayers, - setCurrentIndex, - setCurrentTime, - ]); - - const handlePrevTrack = useCallback(() => { - const currentTime = isMpvPlayer - ? usePlayerStore.getState().current.time - : currentPlayerRef.getCurrentTime(); - - // Reset the current track more than 10 seconds have elapsed - if (currentTime >= 10) { - setCurrentTime(0, true); - handleScrobbleFromSongRestart(currentTime); - mpris?.updateSeek(0); - if (isMpvPlayer) { - return mpvPlayer.seekTo(0); - } - return currentPlayerRef.seekTo(0); - } - - const isFirstTrack = checkIsFirstTrack(); - - const handleRepeatAll = { - local: () => { - if (!isFirstTrack) { - const playerData = previous(); - mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); - mpvPlayer.setQueue(playerData); - mpvPlayer.previous(); - } else { - const playerData = setCurrentIndex(queue.length - 1); - mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); - mpvPlayer.setQueue(playerData); - mpvPlayer.previous(); - } - }, - web: () => { - if (isFirstTrack) { - const playerData = setCurrentIndex(queue.length - 1); - mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); - resetPlayers(); - } else { - const playerData = previous(); - mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); - resetPlayers(); - } - }, - }; - - const handleRepeatNone = { - local: () => { - const playerData = previous(); - mpris?.updateSong({ - currentTime: usePlayerStore.getState().current.time, - song: playerData.current.song, - }); - mpvPlayer.setQueue(playerData); - mpvPlayer.previous(); - }, - web: () => { - if (isFirstTrack) { - resetPlayers(); - mprisUpdateSong({ status: PlayerStatus.PAUSED }); - pause(); - } else { - const playerData = previous(); - mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); - resetPlayers(); - } - }, - }; - - const handleRepeatOne = { - local: () => { - if (!isFirstTrack) { - const playerData = previous(); - mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); - mpvPlayer.setQueue(playerData); - mpvPlayer.previous(); - } else { - mpvPlayer.stop(); - } - }, - web: () => { - const playerData = previous(); - mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); + const stopPlayback = useCallback(() => { + player1Ref.getInternalPlayer().pause(); + player2Ref.getInternalPlayer().pause(); resetPlayers(); - }, + }, [player1Ref, player2Ref, resetPlayers]); + + const isMpvPlayer = isElectron() && settings.type === PlaybackType.LOCAL; + + const mprisUpdateSong = (args?: { + currentTime?: number; + song?: QueueSong; + status?: PlayerStatus; + }) => { + const { song, currentTime, status } = args || {}; + + const time = currentTime || usePlayerStore.getState().current.time; + const playStatus = status || usePlayerStore.getState().current.status; + const track = song || usePlayerStore.getState().current.song; + + mpris?.updateSong({ + currentTime: time, + repeat: usePlayerStore.getState().repeat, + shuffle: usePlayerStore.getState().shuffle, + song: track, + status: playStatus === PlayerStatus.PLAYING ? 'Playing' : 'Paused', + }); + + if (mediaSession) { + mediaSession.playbackState = playStatus === PlayerStatus.PLAYING ? 'playing' : 'paused'; + + let metadata: MediaMetadata; + + if (track) { + let artwork: MediaImage[]; + + if (track.imageUrl) { + const image300 = track.imageUrl + ?.replace(/&size=\d+/, '&size=300') + .replace(/\?width=\d+/, '?width=300') + .replace(/&height=\d+/, '&height=300'); + + artwork = [{ sizes: '300x300', src: image300, type: 'image/png' }]; + } else { + artwork = []; + } + + metadata = new MediaMetadata({ + album: track.album ?? '', + artist: track.artistName, + artwork, + title: track.name, + }); + } else { + metadata = new MediaMetadata(); + } + + mediaSession.metadata = metadata; + } }; - switch (repeatStatus) { - case PlayerRepeat.NONE: - handleRepeatNone[playerType](); - break; - case PlayerRepeat.ALL: - handleRepeatAll[playerType](); - break; - case PlayerRepeat.ONE: - handleRepeatOne[playerType](); - break; - - default: - break; - } - - return setCurrentTime(0); - }, [ - checkIsFirstTrack, - currentPlayerRef, - handleScrobbleFromSongRestart, - isMpvPlayer, - pause, - playerType, - previous, - queue.length, - repeatStatus, - resetPlayers, - setCurrentIndex, - setCurrentTime, - ]); - - const handlePlayPause = useCallback(() => { - if (queue) { - if (playerStatus === PlayerStatus.PAUSED) { - return handlePlay(); - } - - return handlePause(); - } - - return null; - }, [handlePause, handlePlay, playerStatus, queue]); - - const handleSkipBackward = (seconds: number) => { - const currentTime = isMpvPlayer - ? usePlayerStore.getState().current.time - : currentPlayerRef.getCurrentTime(); - - const evaluatedTime = currentTime - seconds; - const newTime = evaluatedTime < 0 ? 0 : evaluatedTime; - setCurrentTime(newTime, true); - mpris?.updateSeek(newTime); - - if (isMpvPlayer) { - mpvPlayer.seek(-seconds); - } else { - resetNextPlayer(); - currentPlayerRef.seekTo(newTime); - } - }; - - const handleSkipForward = (seconds: number) => { - const currentTime = isMpvPlayer - ? usePlayerStore.getState().current.time - : currentPlayerRef.getCurrentTime(); - - if (isMpvPlayer) { - const newTime = currentTime + seconds; - mpvPlayer.seek(seconds); - mpris?.updateSeek(newTime); - setCurrentTime(newTime, true); - } else { - const checkNewTime = currentTime + seconds; - const songDuration = currentPlayerRef.player.player.duration; - - const newTime = checkNewTime >= songDuration ? songDuration - 1 : checkNewTime; - mpris?.updateSeek(newTime); - - resetNextPlayer(); - setCurrentTime(newTime, true); - currentPlayerRef.seekTo(newTime); - } - }; - - const debouncedSeek = debounce((e: number) => { - if (isMpvPlayer) { - mpvPlayer.seekTo(e); - } else { - currentPlayerRef.seekTo(e); - } - }, 100); - - const handleSeekSlider = useCallback( - (e: number | any) => { - setCurrentTime(e, true); - handleScrobbleFromSeek(e); - debouncedSeek(e); - - mpris?.updateSeek(e); - }, - [debouncedSeek, handleScrobbleFromSeek, setCurrentTime], - ); - - const handleQuit = useCallback(() => { - mpvPlayer.quit(); - }, []); - - const handleError = useCallback( - (message: string) => { - toast.error({ id: 'mpv-error', message, title: 'An error occurred during playback' }); - pause(); - mpvPlayer.pause(); - }, - [pause], - ); - - useEffect(() => { - if (isElectron()) { - mpvPlayerListener.rendererPlayPause(() => { - handlePlayPause(); - }); - - mpvPlayerListener.rendererNext(() => { - handleNextTrack(); - }); - - mpvPlayerListener.rendererPrevious(() => { - handlePrevTrack(); - }); - - mpvPlayerListener.rendererPlay(() => { - handlePlay(); - }); - - mpvPlayerListener.rendererPause(() => { - handlePause(); - }); - - mpvPlayerListener.rendererStop(() => { - handleStop(); - }); - - mpvPlayerListener.rendererCurrentTime((_event: any, time: number) => { - setCurrentTime(time); - }); - - mpvPlayerListener.rendererAutoNext(() => { - handleAutoNext(); - }); - - mpvPlayerListener.rendererToggleShuffle(() => { - handleToggleShuffle(); - }); - - mpvPlayerListener.rendererToggleRepeat(() => { - handleToggleRepeat(); - }); - - mpvPlayerListener.rendererError((_event: any, message: string) => { - handleError(message); - }); - } - - return () => { - ipc?.removeAllListeners('renderer-player-play-pause'); - ipc?.removeAllListeners('renderer-player-next'); - ipc?.removeAllListeners('renderer-player-previous'); - ipc?.removeAllListeners('renderer-player-play'); - ipc?.removeAllListeners('renderer-player-pause'); - ipc?.removeAllListeners('renderer-player-stop'); - ipc?.removeAllListeners('renderer-player-current-time'); - ipc?.removeAllListeners('renderer-player-auto-next'); - ipc?.removeAllListeners('renderer-player-toggle-shuffle'); - ipc?.removeAllListeners('renderer-player-toggle-repeat'); - ipc?.removeAllListeners('renderer-player-error'); - }; - }, [ - autoNext, - handleAutoNext, - handleError, - handleNextTrack, - handlePause, - handlePlay, - handlePlayPause, - handlePrevTrack, - handleQuit, - handleStop, - handleToggleRepeat, - handleToggleShuffle, - isMpvPlayer, - next, - pause, - play, - previous, - setCurrentTime, - ]); - - useEffect(() => { - if (!isElectron() && mediaSession) { - mediaSession.setActionHandler('nexttrack', () => { - handleNextTrack(); - }); - - mediaSession.setActionHandler('pause', () => { - handlePause(); - }); - - mediaSession.setActionHandler('play', () => { - handlePlay(); - }); - - mediaSession.setActionHandler('previoustrack', () => { - handlePrevTrack(); - }); - - mediaSession.setActionHandler('seekto', (evt) => { - const time = evt.seekTime; - - if (time !== undefined) { - handleSeekSlider(time); - } - }); - - mediaSession.setActionHandler('stop', () => { - handleStop(); - }); - - return () => { - mediaSession.setActionHandler('nexttrack', null); - mediaSession.setActionHandler('pause', null); - mediaSession.setActionHandler('play', null); - mediaSession.setActionHandler('previoustrack', null); - mediaSession.setActionHandler('seekto', null); - mediaSession.setActionHandler('stop', null); - }; - } - - return () => {}; - }, [ - handleNextTrack, - handlePause, - handlePlay, - handlePrevTrack, - handleSeekSlider, - handleStop, - setCurrentTime, - ]); - - useEffect(() => { - if (utils?.isLinux()) { - const unsubCurrentTime = usePlayerStore.subscribe( - (state) => state.current.time, - (time) => { - mpris?.updatePosition(time); - }, - ); - - return () => { - unsubCurrentTime(); - }; - } - - return () => {}; - }, []); - - useEffect(() => { - if (utils?.isLinux()) { - mpris.requestPosition((_e: any, data: { position: number }) => { - const newTime = data.position; - handleSeekSlider(newTime); - }); - - mpris.requestSeek((_e: any, data: { offset: number }) => { - const currentTime = usePlayerStore.getState().current.time; - const currentSongDuration = usePlayerStore.getState().current.song?.duration || 0; - const resultingTime = currentTime + data.offset; - - let newTime = resultingTime; - if (resultingTime > currentSongDuration) { - newTime = currentSongDuration - 1; - } - - if (resultingTime < 0) { - newTime = 0; - } - - handleSeekSlider(newTime); - }); - - mpris.requestVolume((_e: any, data: { volume: number }) => { - let newVolume = Math.round(data.volume * 100); - - if (newVolume > 100) { - newVolume = 100; - } else if (newVolume < 0) { - newVolume = 0; - } - - usePlayerStore.getState().actions.setVolume(newVolume); - mpris.updateVolume(data.volume); + const handlePlay = useCallback(() => { + mprisUpdateSong({ status: PlayerStatus.PLAYING }); if (isMpvPlayer) { - mpvPlayer.volume(newVolume); - } - }); - - mpris.requestToggleRepeat((_e: any, data: { repeat: string }) => { - if (data.repeat === 'Playlist') { - usePlayerStore.getState().actions.setRepeat(PlayerRepeat.ALL); - } else if (data.repeat === 'Track') { - usePlayerStore.getState().actions.setRepeat(PlayerRepeat.ONE); + mpvPlayer?.volume(usePlayerStore.getState().volume); + mpvPlayer.play(); } else { - usePlayerStore.getState().actions.setRepeat(PlayerRepeat.NONE); + currentPlayerRef.getInternalPlayer().play(); } - }); - mpris.requestToggleShuffle((_e: any, data: { shuffle: boolean }) => { - usePlayerStore - .getState() - .actions.setShuffle(data.shuffle ? PlayerShuffle.TRACK : PlayerShuffle.NONE); - }); + play(); + }, [currentPlayerRef, isMpvPlayer, play]); - return () => { - ipc?.removeAllListeners('mpris-request-position'); - ipc?.removeAllListeners('mpris-request-seek'); - ipc?.removeAllListeners('mpris-request-volume'); - ipc?.removeAllListeners('mpris-request-toggle-repeat'); - ipc?.removeAllListeners('mpris-request-toggle-shuffle'); - }; - } + const handlePause = useCallback(() => { + mprisUpdateSong({ status: PlayerStatus.PAUSED }); - return () => {}; - }, [handleSeekSlider, isMpvPlayer]); + if (isMpvPlayer) { + mpvPlayer.pause(); + } - return { - handleNextTrack, - handlePause, - handlePlay, - handlePlayPause, - handlePrevTrack, - handleSeekSlider, - handleSkipBackward, - handleSkipForward, - handleStop, - handleToggleRepeat, - handleToggleShuffle, - }; + pause(); + }, [isMpvPlayer, pause]); + + const handleStop = useCallback(() => { + mprisUpdateSong({ status: PlayerStatus.PAUSED }); + + if (isMpvPlayer) { + mpvPlayer.pause(); + mpvPlayer.seekTo(0); + } else { + stopPlayback(); + } + + setCurrentTime(0); + pause(); + }, [isMpvPlayer, pause, setCurrentTime, stopPlayback]); + + const handleToggleShuffle = useCallback(() => { + if (shuffleStatus === PlayerShuffle.NONE) { + const playerData = setShuffle(PlayerShuffle.TRACK); + mpris?.updateShuffle(true); + return mpvPlayer.setQueueNext(playerData); + } + + const playerData = setShuffle(PlayerShuffle.NONE); + mpris?.updateShuffle(false); + return mpvPlayer.setQueueNext(playerData); + }, [setShuffle, shuffleStatus]); + + const handleToggleRepeat = useCallback(() => { + if (repeatStatus === PlayerRepeat.NONE) { + const playerData = setRepeat(PlayerRepeat.ALL); + mpris?.updateRepeat('Playlist'); + return mpvPlayer.setQueueNext(playerData); + } + + if (repeatStatus === PlayerRepeat.ALL) { + const playerData = setRepeat(PlayerRepeat.ONE); + mpris?.updateRepeat('Track'); + return mpvPlayer.setQueueNext(playerData); + } + + mpris?.updateRepeat('None'); + return setRepeat(PlayerRepeat.NONE); + }, [repeatStatus, setRepeat]); + + const checkIsLastTrack = useCallback(() => { + return usePlayerStore.getState().actions.checkIsLastTrack(); + }, []); + + const checkIsFirstTrack = useCallback(() => { + return usePlayerStore.getState().actions.checkIsFirstTrack(); + }, []); + + const handleAutoNext = useCallback(() => { + const isLastTrack = checkIsLastTrack(); + + const handleRepeatAll = { + local: () => { + const playerData = autoNext(); + mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); + mpvPlayer.autoNext(playerData); + play(); + }, + web: () => { + const playerData = autoNext(); + mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); + }, + }; + + const handleRepeatNone = { + local: () => { + if (isLastTrack) { + const playerData = setCurrentIndex(0); + mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PAUSED }); + mpvPlayer.setQueue(playerData, true); + pause(); + } else { + const playerData = autoNext(); + mprisUpdateSong({ + song: playerData.current.song, + status: PlayerStatus.PLAYING, + }); + mpvPlayer.autoNext(playerData); + play(); + } + }, + web: () => { + if (isLastTrack) { + resetPlayers(); + mprisUpdateSong({ status: PlayerStatus.PAUSED }); + pause(); + } else { + const playerData = autoNext(); + mprisUpdateSong({ + song: playerData.current.song, + status: PlayerStatus.PLAYING, + }); + resetPlayers(); + } + }, + }; + + const handleRepeatOne = { + local: () => { + const playerData = autoNext(); + mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); + mpvPlayer.autoNext(playerData); + play(); + }, + web: () => { + if (isLastTrack) { + mprisUpdateSong({ status: PlayerStatus.PAUSED }); + resetPlayers(); + } else { + const playerData = autoNext(); + mprisUpdateSong({ + song: playerData.current.song, + status: PlayerStatus.PLAYING, + }); + resetPlayers(); + } + }, + }; + + switch (repeatStatus) { + case PlayerRepeat.NONE: + handleRepeatNone[playerType](); + break; + case PlayerRepeat.ALL: + handleRepeatAll[playerType](); + break; + case PlayerRepeat.ONE: + handleRepeatOne[playerType](); + break; + + default: + break; + } + }, [ + autoNext, + checkIsLastTrack, + pause, + play, + playerType, + repeatStatus, + resetPlayers, + setCurrentIndex, + ]); + + const handleNextTrack = useCallback(() => { + const isLastTrack = checkIsLastTrack(); + setCurrentTime(0); + + const handleRepeatAll = { + local: () => { + const playerData = next(); + mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); + mpvPlayer.setQueue(playerData); + mpvPlayer.next(); + }, + web: () => { + const playerData = next(); + mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); + }, + }; + + const handleRepeatNone = { + local: () => { + if (isLastTrack) { + const playerData = setCurrentIndex(0); + mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PAUSED }); + mpvPlayer.setQueue(playerData); + mpvPlayer.pause(); + pause(); + } else { + const playerData = next(); + mprisUpdateSong({ + song: playerData.current.song, + status: PlayerStatus.PLAYING, + }); + mpvPlayer.setQueue(playerData); + mpvPlayer.next(); + } + }, + web: () => { + if (isLastTrack) { + const playerData = setCurrentIndex(0); + mprisUpdateSong({ + song: playerData.current.song, + status: PlayerStatus.PLAYING, + }); + resetPlayers(); + pause(); + } else { + const playerData = next(); + mprisUpdateSong({ + song: playerData.current.song, + status: PlayerStatus.PLAYING, + }); + resetPlayers(); + } + }, + }; + + const handleRepeatOne = { + local: () => { + const playerData = next(); + mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); + mpvPlayer.setQueue(playerData); + mpvPlayer.next(); + }, + web: () => { + if (!isLastTrack) { + const playerData = next(); + mprisUpdateSong({ + song: playerData.current.song, + status: PlayerStatus.PLAYING, + }); + } + }, + }; + + switch (repeatStatus) { + case PlayerRepeat.NONE: + handleRepeatNone[playerType](); + break; + case PlayerRepeat.ALL: + handleRepeatAll[playerType](); + break; + case PlayerRepeat.ONE: + handleRepeatOne[playerType](); + break; + + default: + break; + } + + setCurrentTime(0); + }, [ + checkIsLastTrack, + next, + pause, + playerType, + repeatStatus, + resetPlayers, + setCurrentIndex, + setCurrentTime, + ]); + + const handlePrevTrack = useCallback(() => { + const currentTime = isMpvPlayer + ? usePlayerStore.getState().current.time + : currentPlayerRef.getCurrentTime(); + + // Reset the current track more than 10 seconds have elapsed + if (currentTime >= 10) { + setCurrentTime(0, true); + handleScrobbleFromSongRestart(currentTime); + mpris?.updateSeek(0); + if (isMpvPlayer) { + return mpvPlayer.seekTo(0); + } + return currentPlayerRef.seekTo(0); + } + + const isFirstTrack = checkIsFirstTrack(); + + const handleRepeatAll = { + local: () => { + if (!isFirstTrack) { + const playerData = previous(); + mprisUpdateSong({ + song: playerData.current.song, + status: PlayerStatus.PLAYING, + }); + mpvPlayer.setQueue(playerData); + mpvPlayer.previous(); + } else { + const playerData = setCurrentIndex(queue.length - 1); + mprisUpdateSong({ + song: playerData.current.song, + status: PlayerStatus.PLAYING, + }); + mpvPlayer.setQueue(playerData); + mpvPlayer.previous(); + } + }, + web: () => { + if (isFirstTrack) { + const playerData = setCurrentIndex(queue.length - 1); + mprisUpdateSong({ + song: playerData.current.song, + status: PlayerStatus.PLAYING, + }); + resetPlayers(); + } else { + const playerData = previous(); + mprisUpdateSong({ + song: playerData.current.song, + status: PlayerStatus.PLAYING, + }); + resetPlayers(); + } + }, + }; + + const handleRepeatNone = { + local: () => { + const playerData = previous(); + mpris?.updateSong({ + currentTime: usePlayerStore.getState().current.time, + song: playerData.current.song, + }); + mpvPlayer.setQueue(playerData); + mpvPlayer.previous(); + }, + web: () => { + if (isFirstTrack) { + resetPlayers(); + mprisUpdateSong({ status: PlayerStatus.PAUSED }); + pause(); + } else { + const playerData = previous(); + mprisUpdateSong({ + song: playerData.current.song, + status: PlayerStatus.PLAYING, + }); + resetPlayers(); + } + }, + }; + + const handleRepeatOne = { + local: () => { + if (!isFirstTrack) { + const playerData = previous(); + mprisUpdateSong({ + song: playerData.current.song, + status: PlayerStatus.PLAYING, + }); + mpvPlayer.setQueue(playerData); + mpvPlayer.previous(); + } else { + mpvPlayer.stop(); + } + }, + web: () => { + const playerData = previous(); + mprisUpdateSong({ song: playerData.current.song, status: PlayerStatus.PLAYING }); + resetPlayers(); + }, + }; + + switch (repeatStatus) { + case PlayerRepeat.NONE: + handleRepeatNone[playerType](); + break; + case PlayerRepeat.ALL: + handleRepeatAll[playerType](); + break; + case PlayerRepeat.ONE: + handleRepeatOne[playerType](); + break; + + default: + break; + } + + return setCurrentTime(0); + }, [ + checkIsFirstTrack, + currentPlayerRef, + handleScrobbleFromSongRestart, + isMpvPlayer, + pause, + playerType, + previous, + queue.length, + repeatStatus, + resetPlayers, + setCurrentIndex, + setCurrentTime, + ]); + + const handlePlayPause = useCallback(() => { + if (queue) { + if (playerStatus === PlayerStatus.PAUSED) { + return handlePlay(); + } + + return handlePause(); + } + + return null; + }, [handlePause, handlePlay, playerStatus, queue]); + + const handleSkipBackward = (seconds: number) => { + const currentTime = isMpvPlayer + ? usePlayerStore.getState().current.time + : currentPlayerRef.getCurrentTime(); + + const evaluatedTime = currentTime - seconds; + const newTime = evaluatedTime < 0 ? 0 : evaluatedTime; + setCurrentTime(newTime, true); + mpris?.updateSeek(newTime); + + if (isMpvPlayer) { + mpvPlayer.seek(-seconds); + } else { + resetNextPlayer(); + currentPlayerRef.seekTo(newTime); + } + }; + + const handleSkipForward = (seconds: number) => { + const currentTime = isMpvPlayer + ? usePlayerStore.getState().current.time + : currentPlayerRef.getCurrentTime(); + + if (isMpvPlayer) { + const newTime = currentTime + seconds; + mpvPlayer.seek(seconds); + mpris?.updateSeek(newTime); + setCurrentTime(newTime, true); + } else { + const checkNewTime = currentTime + seconds; + const songDuration = currentPlayerRef.player.player.duration; + + const newTime = checkNewTime >= songDuration ? songDuration - 1 : checkNewTime; + mpris?.updateSeek(newTime); + + resetNextPlayer(); + setCurrentTime(newTime, true); + currentPlayerRef.seekTo(newTime); + } + }; + + const debouncedSeek = debounce((e: number) => { + if (isMpvPlayer) { + mpvPlayer.seekTo(e); + } else { + currentPlayerRef.seekTo(e); + } + }, 100); + + const handleSeekSlider = useCallback( + (e: number | any) => { + setCurrentTime(e, true); + handleScrobbleFromSeek(e); + debouncedSeek(e); + + mpris?.updateSeek(e); + }, + [debouncedSeek, handleScrobbleFromSeek, setCurrentTime], + ); + + const handleQuit = useCallback(() => { + mpvPlayer.quit(); + }, []); + + const handleError = useCallback( + (message: string) => { + toast.error({ id: 'mpv-error', message, title: 'An error occurred during playback' }); + pause(); + mpvPlayer.pause(); + }, + [pause], + ); + + useEffect(() => { + if (isElectron()) { + mpvPlayerListener.rendererPlayPause(() => { + handlePlayPause(); + }); + + mpvPlayerListener.rendererNext(() => { + handleNextTrack(); + }); + + mpvPlayerListener.rendererPrevious(() => { + handlePrevTrack(); + }); + + mpvPlayerListener.rendererPlay(() => { + handlePlay(); + }); + + mpvPlayerListener.rendererPause(() => { + handlePause(); + }); + + mpvPlayerListener.rendererStop(() => { + handleStop(); + }); + + mpvPlayerListener.rendererCurrentTime((_event: any, time: number) => { + setCurrentTime(time); + }); + + mpvPlayerListener.rendererAutoNext(() => { + handleAutoNext(); + }); + + mpvPlayerListener.rendererToggleShuffle(() => { + handleToggleShuffle(); + }); + + mpvPlayerListener.rendererToggleRepeat(() => { + handleToggleRepeat(); + }); + + mpvPlayerListener.rendererError((_event: any, message: string) => { + handleError(message); + }); + } + + return () => { + ipc?.removeAllListeners('renderer-player-play-pause'); + ipc?.removeAllListeners('renderer-player-next'); + ipc?.removeAllListeners('renderer-player-previous'); + ipc?.removeAllListeners('renderer-player-play'); + ipc?.removeAllListeners('renderer-player-pause'); + ipc?.removeAllListeners('renderer-player-stop'); + ipc?.removeAllListeners('renderer-player-current-time'); + ipc?.removeAllListeners('renderer-player-auto-next'); + ipc?.removeAllListeners('renderer-player-toggle-shuffle'); + ipc?.removeAllListeners('renderer-player-toggle-repeat'); + ipc?.removeAllListeners('renderer-player-error'); + }; + }, [ + autoNext, + handleAutoNext, + handleError, + handleNextTrack, + handlePause, + handlePlay, + handlePlayPause, + handlePrevTrack, + handleQuit, + handleStop, + handleToggleRepeat, + handleToggleShuffle, + isMpvPlayer, + next, + pause, + play, + previous, + setCurrentTime, + ]); + + useEffect(() => { + if (!isElectron() && mediaSession) { + mediaSession.setActionHandler('nexttrack', () => { + handleNextTrack(); + }); + + mediaSession.setActionHandler('pause', () => { + handlePause(); + }); + + mediaSession.setActionHandler('play', () => { + handlePlay(); + }); + + mediaSession.setActionHandler('previoustrack', () => { + handlePrevTrack(); + }); + + mediaSession.setActionHandler('seekto', (evt) => { + const time = evt.seekTime; + + if (time !== undefined) { + handleSeekSlider(time); + } + }); + + mediaSession.setActionHandler('stop', () => { + handleStop(); + }); + + return () => { + mediaSession.setActionHandler('nexttrack', null); + mediaSession.setActionHandler('pause', null); + mediaSession.setActionHandler('play', null); + mediaSession.setActionHandler('previoustrack', null); + mediaSession.setActionHandler('seekto', null); + mediaSession.setActionHandler('stop', null); + }; + } + + return () => {}; + }, [ + handleNextTrack, + handlePause, + handlePlay, + handlePrevTrack, + handleSeekSlider, + handleStop, + setCurrentTime, + ]); + + useEffect(() => { + if (utils?.isLinux()) { + const unsubCurrentTime = usePlayerStore.subscribe( + (state) => state.current.time, + (time) => { + mpris?.updatePosition(time); + }, + ); + + return () => { + unsubCurrentTime(); + }; + } + + return () => {}; + }, []); + + useEffect(() => { + if (utils?.isLinux()) { + mpris.requestPosition((_e: any, data: { position: number }) => { + const newTime = data.position; + handleSeekSlider(newTime); + }); + + mpris.requestSeek((_e: any, data: { offset: number }) => { + const currentTime = usePlayerStore.getState().current.time; + const currentSongDuration = usePlayerStore.getState().current.song?.duration || 0; + const resultingTime = currentTime + data.offset; + + let newTime = resultingTime; + if (resultingTime > currentSongDuration) { + newTime = currentSongDuration - 1; + } + + if (resultingTime < 0) { + newTime = 0; + } + + handleSeekSlider(newTime); + }); + + mpris.requestVolume((_e: any, data: { volume: number }) => { + let newVolume = Math.round(data.volume * 100); + + if (newVolume > 100) { + newVolume = 100; + } else if (newVolume < 0) { + newVolume = 0; + } + + usePlayerStore.getState().actions.setVolume(newVolume); + mpris.updateVolume(data.volume); + + if (isMpvPlayer) { + mpvPlayer.volume(newVolume); + } + }); + + mpris.requestToggleRepeat((_e: any, data: { repeat: string }) => { + if (data.repeat === 'Playlist') { + usePlayerStore.getState().actions.setRepeat(PlayerRepeat.ALL); + } else if (data.repeat === 'Track') { + usePlayerStore.getState().actions.setRepeat(PlayerRepeat.ONE); + } else { + usePlayerStore.getState().actions.setRepeat(PlayerRepeat.NONE); + } + }); + + mpris.requestToggleShuffle((_e: any, data: { shuffle: boolean }) => { + usePlayerStore + .getState() + .actions.setShuffle(data.shuffle ? PlayerShuffle.TRACK : PlayerShuffle.NONE); + }); + + return () => { + ipc?.removeAllListeners('mpris-request-position'); + ipc?.removeAllListeners('mpris-request-seek'); + ipc?.removeAllListeners('mpris-request-volume'); + ipc?.removeAllListeners('mpris-request-toggle-repeat'); + ipc?.removeAllListeners('mpris-request-toggle-shuffle'); + }; + } + + return () => {}; + }, [handleSeekSlider, isMpvPlayer]); + + return { + handleNextTrack, + handlePause, + handlePlay, + handlePlayPause, + handlePrevTrack, + handleSeekSlider, + handleSkipBackward, + handleSkipForward, + handleStop, + handleToggleRepeat, + handleToggleShuffle, + }; }; diff --git a/src/renderer/features/player/hooks/use-handle-playqueue-add.ts b/src/renderer/features/player/hooks/use-handle-playqueue-add.ts index bf1dcdee..1adfe66e 100644 --- a/src/renderer/features/player/hooks/use-handle-playqueue-add.ts +++ b/src/renderer/features/player/hooks/use-handle-playqueue-add.ts @@ -7,43 +7,43 @@ import { toast } from '/@/renderer/components/toast/index'; import isElectron from 'is-electron'; import { nanoid } from 'nanoid/non-secure'; import { - LibraryItem, - QueueSong, - Song, - SongListResponse, - instanceOfCancellationError, + LibraryItem, + QueueSong, + Song, + SongListResponse, + instanceOfCancellationError, } from '/@/renderer/api/types'; import { - getPlaylistSongsById, - getSongById, - getAlbumSongsById, - getAlbumArtistSongsById, - getSongsByQuery, + getPlaylistSongsById, + getSongById, + getAlbumSongsById, + getAlbumArtistSongsById, + getSongsByQuery, } from '/@/renderer/features/player/utils'; import { queryKeys } from '/@/renderer/api/query-keys'; const getRootQueryKey = (itemType: LibraryItem, serverId: string) => { - let queryKey; + let queryKey; - switch (itemType) { - case LibraryItem.ALBUM: - queryKey = queryKeys.songs.list(serverId); - break; - case LibraryItem.ALBUM_ARTIST: - queryKey = queryKeys.songs.list(serverId); - break; - case LibraryItem.PLAYLIST: - queryKey = queryKeys.playlists.songList(serverId); - break; - case LibraryItem.SONG: - queryKey = queryKeys.songs.list(serverId); - break; - default: - queryKey = queryKeys.songs.list(serverId); - break; - } + switch (itemType) { + case LibraryItem.ALBUM: + queryKey = queryKeys.songs.list(serverId); + break; + case LibraryItem.ALBUM_ARTIST: + queryKey = queryKeys.songs.list(serverId); + break; + case LibraryItem.PLAYLIST: + queryKey = queryKeys.playlists.songList(serverId); + break; + case LibraryItem.SONG: + queryKey = queryKeys.songs.list(serverId); + break; + default: + queryKey = queryKeys.songs.list(serverId); + break; + } - return queryKey; + return queryKey; }; const mpvPlayer = isElectron() ? window.electron.mpvPlayer : null; @@ -53,118 +53,133 @@ const mpris = isElectron() && utils?.isLinux() ? window.electron.mpris : null; const addToQueue = usePlayerStore.getState().actions.addToQueue; export const useHandlePlayQueueAdd = () => { - const queryClient = useQueryClient(); - const playerType = usePlayerType(); - const server = useCurrentServer(); - const { play } = usePlayerControls(); - const timeoutIds = useRef<Record<string, ReturnType<typeof setTimeout>> | null>({}); + const queryClient = useQueryClient(); + const playerType = usePlayerType(); + const server = useCurrentServer(); + const { play } = usePlayerControls(); + const timeoutIds = useRef<Record<string, ReturnType<typeof setTimeout>> | null>({}); - const handlePlayQueueAdd = useCallback( - async (options: PlayQueueAddOptions) => { - if (!server) return toast.error({ message: 'No server selected', type: 'error' }); - const { initialIndex, initialSongId, playType, byData, byItemType, query } = options; - let songs: QueueSong[] | null = null; - let initialSongIndex = 0; + const handlePlayQueueAdd = useCallback( + async (options: PlayQueueAddOptions) => { + if (!server) return toast.error({ message: 'No server selected', type: 'error' }); + const { initialIndex, initialSongId, playType, byData, byItemType, query } = options; + let songs: QueueSong[] | null = null; + let initialSongIndex = 0; - if (byItemType) { - let songList: SongListResponse | undefined; - const { type: itemType, id } = byItemType; + if (byItemType) { + let songList: SongListResponse | undefined; + const { type: itemType, id } = byItemType; - const fetchId = nanoid(); - timeoutIds.current = { - ...timeoutIds.current, - [fetchId]: setTimeout(() => { - toast.info({ - autoClose: false, - id: fetchId, - message: 'This is taking a while... close the notification to cancel the request', - onClose: () => { - queryClient.cancelQueries({ - exact: false, - queryKey: getRootQueryKey(itemType, server?.id), - }); - }, - title: 'Adding to queue', - }); - }, 2000), - }; + const fetchId = nanoid(); + timeoutIds.current = { + ...timeoutIds.current, + [fetchId]: setTimeout(() => { + toast.info({ + autoClose: false, + id: fetchId, + message: + 'This is taking a while... close the notification to cancel the request', + onClose: () => { + queryClient.cancelQueries({ + exact: false, + queryKey: getRootQueryKey(itemType, server?.id), + }); + }, + title: 'Adding to queue', + }); + }, 2000), + }; - try { - if (itemType === LibraryItem.PLAYLIST) { - songList = await getPlaylistSongsById({ id: id?.[0], query, queryClient, server }); - } else if (itemType === LibraryItem.ALBUM) { - songList = await getAlbumSongsById({ id, query, queryClient, server }); - } else if (itemType === LibraryItem.ALBUM_ARTIST) { - songList = await getAlbumArtistSongsById({ id, query, queryClient, server }); - } else if (itemType === LibraryItem.SONG) { - if (id?.length === 1) { - songList = await getSongById({ id: id?.[0], queryClient, server }); - } else { - songList = await getSongsByQuery({ query, queryClient, server }); + try { + if (itemType === LibraryItem.PLAYLIST) { + songList = await getPlaylistSongsById({ + id: id?.[0], + query, + queryClient, + server, + }); + } else if (itemType === LibraryItem.ALBUM) { + songList = await getAlbumSongsById({ id, query, queryClient, server }); + } else if (itemType === LibraryItem.ALBUM_ARTIST) { + songList = await getAlbumArtistSongsById({ + id, + query, + queryClient, + server, + }); + } else if (itemType === LibraryItem.SONG) { + if (id?.length === 1) { + songList = await getSongById({ id: id?.[0], queryClient, server }); + } else { + songList = await getSongsByQuery({ query, queryClient, server }); + } + } + + clearTimeout(timeoutIds.current[fetchId] as ReturnType<typeof setTimeout>); + delete timeoutIds.current[fetchId]; + toast.hide(fetchId); + } catch (err: any) { + if (instanceOfCancellationError(err)) { + return null; + } + + clearTimeout(timeoutIds.current[fetchId] as ReturnType<typeof setTimeout>); + delete timeoutIds.current[fetchId]; + toast.hide(fetchId); + + return toast.error({ + message: err.message, + title: 'Play queue add failed', + }); + } + + songs = + songList?.items?.map((song: Song) => ({ ...song, uniqueId: nanoid() })) || null; + } else if (byData) { + songs = byData.map((song) => ({ ...song, uniqueId: nanoid() })) || null; } - } - clearTimeout(timeoutIds.current[fetchId] as ReturnType<typeof setTimeout>); - delete timeoutIds.current[fetchId]; - toast.hide(fetchId); - } catch (err: any) { - if (instanceOfCancellationError(err)) { + if (!songs || songs?.length === 0) + return toast.warn({ + message: 'The query returned no results', + title: 'No tracks added', + }); + + if (initialIndex) { + initialSongIndex = initialIndex; + } else if (initialSongId) { + initialSongIndex = songs.findIndex((song) => song.id === initialSongId); + } + + const playerData = addToQueue({ initialIndex: initialSongIndex, playType, songs }); + + if (playerType === PlaybackType.LOCAL) { + mpvPlayer?.volume(usePlayerStore.getState().volume); + + if (playType === Play.NEXT || playType === Play.LAST) { + mpvPlayer?.setQueueNext(playerData); + } + + if (playType === Play.NOW) { + mpvPlayer?.setQueue(playerData); + mpvPlayer?.play(); + } + } + + play(); + + mpris?.updateSong({ + currentTime: usePlayerStore.getState().current.time, + repeat: usePlayerStore.getState().repeat, + shuffle: usePlayerStore.getState().shuffle, + song: playerData.current.song, + status: 'Playing', + }); + return null; - } + }, + [play, playerType, queryClient, server], + ); - clearTimeout(timeoutIds.current[fetchId] as ReturnType<typeof setTimeout>); - delete timeoutIds.current[fetchId]; - toast.hide(fetchId); - - return toast.error({ - message: err.message, - title: 'Play queue add failed', - }); - } - - songs = songList?.items?.map((song: Song) => ({ ...song, uniqueId: nanoid() })) || null; - } else if (byData) { - songs = byData.map((song) => ({ ...song, uniqueId: nanoid() })) || null; - } - - if (!songs || songs?.length === 0) - return toast.warn({ message: 'The query returned no results', title: 'No tracks added' }); - - if (initialIndex) { - initialSongIndex = initialIndex; - } else if (initialSongId) { - initialSongIndex = songs.findIndex((song) => song.id === initialSongId); - } - - const playerData = addToQueue({ initialIndex: initialSongIndex, playType, songs }); - - if (playerType === PlaybackType.LOCAL) { - mpvPlayer?.volume(usePlayerStore.getState().volume); - - if (playType === Play.NEXT || playType === Play.LAST) { - mpvPlayer?.setQueueNext(playerData); - } - - if (playType === Play.NOW) { - mpvPlayer?.setQueue(playerData); - mpvPlayer?.play(); - } - } - - play(); - - mpris?.updateSong({ - currentTime: usePlayerStore.getState().current.time, - repeat: usePlayerStore.getState().repeat, - shuffle: usePlayerStore.getState().shuffle, - song: playerData.current.song, - status: 'Playing', - }); - - return null; - }, - [play, playerType, queryClient, server], - ); - - return handlePlayQueueAdd; + return handlePlayQueueAdd; }; diff --git a/src/renderer/features/player/hooks/use-playqueue-add.ts b/src/renderer/features/player/hooks/use-playqueue-add.ts index 0fb87611..4703cb61 100644 --- a/src/renderer/features/player/hooks/use-playqueue-add.ts +++ b/src/renderer/features/player/hooks/use-playqueue-add.ts @@ -2,6 +2,6 @@ import { useContext } from 'react'; import { PlayQueueHandlerContext } from '/@/renderer/features/player/context/play-queue-handler-context'; export const usePlayQueueAdd = () => { - const { handlePlayQueueAdd } = useContext(PlayQueueHandlerContext); - return handlePlayQueueAdd; + const { handlePlayQueueAdd } = useContext(PlayQueueHandlerContext); + return handlePlayQueueAdd; }; diff --git a/src/renderer/features/player/hooks/use-right-controls.ts b/src/renderer/features/player/hooks/use-right-controls.ts index ee6c44ee..4b4e944f 100644 --- a/src/renderer/features/player/hooks/use-right-controls.ts +++ b/src/renderer/features/player/hooks/use-right-controls.ts @@ -10,123 +10,123 @@ const utils = isElectron() ? window.electron.utils : null; const mpris = isElectron() && utils?.isLinux() ? window.electron.mpris : null; const calculateVolumeUp = (volume: number, volumeWheelStep: number) => { - let volumeToSet; - const newVolumeGreaterThanHundred = volume + volumeWheelStep > 100; - if (newVolumeGreaterThanHundred) { - volumeToSet = 100; - } else { - volumeToSet = volume + volumeWheelStep; - } + let volumeToSet; + const newVolumeGreaterThanHundred = volume + volumeWheelStep > 100; + if (newVolumeGreaterThanHundred) { + volumeToSet = 100; + } else { + volumeToSet = volume + volumeWheelStep; + } - return volumeToSet; + return volumeToSet; }; const calculateVolumeDown = (volume: number, volumeWheelStep: number) => { - let volumeToSet; - const newVolumeLessThanZero = volume - volumeWheelStep < 0; - if (newVolumeLessThanZero) { - volumeToSet = 0; - } else { - volumeToSet = volume - volumeWheelStep; - } + let volumeToSet; + const newVolumeLessThanZero = volume - volumeWheelStep < 0; + if (newVolumeLessThanZero) { + volumeToSet = 0; + } else { + volumeToSet = volume - volumeWheelStep; + } - return volumeToSet; + return volumeToSet; }; export const useRightControls = () => { - const { setVolume, setMuted } = usePlayerControls(); - const volume = useVolume(); - const muted = useMuted(); - const { volumeWheelStep } = useGeneralSettings(); + const { setVolume, setMuted } = usePlayerControls(); + const volume = useVolume(); + const muted = useMuted(); + const { volumeWheelStep } = useGeneralSettings(); - // Ensure that the mpv player volume is set on startup - useEffect(() => { - if (isElectron()) { - mpvPlayer.volume(volume); - mpris?.updateVolume(volume / 100); + // Ensure that the mpv player volume is set on startup + useEffect(() => { + if (isElectron()) { + mpvPlayer.volume(volume); + mpris?.updateVolume(volume / 100); - if (muted) { - mpvPlayer.mute(); - } - } + if (muted) { + mpvPlayer.mute(); + } + } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); - const handleVolumeSlider = (e: number) => { - mpvPlayer?.volume(e); - mpris?.updateVolume(e / 100); - setVolume(e); - }; - - const handleVolumeSliderState = (e: number) => { - mpris?.updateVolume(e / 100); - setVolume(e); - }; - - const handleVolumeDown = useCallback(() => { - const volumeToSet = calculateVolumeDown(volume, volumeWheelStep); - mpvPlayer?.volume(volumeToSet); - mpris?.updateVolume(volumeToSet / 100); - setVolume(volumeToSet); - }, [setVolume, volume, volumeWheelStep]); - - const handleVolumeUp = useCallback(() => { - const volumeToSet = calculateVolumeUp(volume, volumeWheelStep); - mpvPlayer?.volume(volumeToSet); - mpris?.updateVolume(volumeToSet / 100); - setVolume(volumeToSet); - }, [setVolume, volume, volumeWheelStep]); - - const handleVolumeWheel = useCallback( - (e: WheelEvent<HTMLDivElement | HTMLButtonElement>) => { - let volumeToSet; - if (e.deltaY > 0) { - volumeToSet = calculateVolumeDown(volume, volumeWheelStep); - } else { - volumeToSet = calculateVolumeUp(volume, volumeWheelStep); - } - - mpvPlayer?.volume(volumeToSet); - mpris?.updateVolume(volumeToSet / 100); - setVolume(volumeToSet); - }, - [setVolume, volume, volumeWheelStep], - ); - - const handleMute = useCallback(() => { - setMuted(!muted); - mpvPlayer?.mute(); - }, [muted, setMuted]); - - useEffect(() => { - if (isElectron()) { - mpvPlayerListener?.rendererVolumeMute(() => { - handleMute(); - }); - - mpvPlayerListener?.rendererVolumeUp(() => { - handleVolumeUp(); - }); - - mpvPlayerListener?.rendererVolumeDown(() => { - handleVolumeDown(); - }); - } - - return () => { - ipc?.removeAllListeners('renderer-player-volume-mute'); - ipc?.removeAllListeners('renderer-player-volume-up'); - ipc?.removeAllListeners('renderer-player-volume-down'); + const handleVolumeSlider = (e: number) => { + mpvPlayer?.volume(e); + mpris?.updateVolume(e / 100); + setVolume(e); }; - }, [handleMute, handleVolumeDown, handleVolumeUp]); - return { - handleMute, - handleVolumeDown, - handleVolumeSlider, - handleVolumeSliderState, - handleVolumeUp, - handleVolumeWheel, - }; + const handleVolumeSliderState = (e: number) => { + mpris?.updateVolume(e / 100); + setVolume(e); + }; + + const handleVolumeDown = useCallback(() => { + const volumeToSet = calculateVolumeDown(volume, volumeWheelStep); + mpvPlayer?.volume(volumeToSet); + mpris?.updateVolume(volumeToSet / 100); + setVolume(volumeToSet); + }, [setVolume, volume, volumeWheelStep]); + + const handleVolumeUp = useCallback(() => { + const volumeToSet = calculateVolumeUp(volume, volumeWheelStep); + mpvPlayer?.volume(volumeToSet); + mpris?.updateVolume(volumeToSet / 100); + setVolume(volumeToSet); + }, [setVolume, volume, volumeWheelStep]); + + const handleVolumeWheel = useCallback( + (e: WheelEvent<HTMLDivElement | HTMLButtonElement>) => { + let volumeToSet; + if (e.deltaY > 0) { + volumeToSet = calculateVolumeDown(volume, volumeWheelStep); + } else { + volumeToSet = calculateVolumeUp(volume, volumeWheelStep); + } + + mpvPlayer?.volume(volumeToSet); + mpris?.updateVolume(volumeToSet / 100); + setVolume(volumeToSet); + }, + [setVolume, volume, volumeWheelStep], + ); + + const handleMute = useCallback(() => { + setMuted(!muted); + mpvPlayer?.mute(); + }, [muted, setMuted]); + + useEffect(() => { + if (isElectron()) { + mpvPlayerListener?.rendererVolumeMute(() => { + handleMute(); + }); + + mpvPlayerListener?.rendererVolumeUp(() => { + handleVolumeUp(); + }); + + mpvPlayerListener?.rendererVolumeDown(() => { + handleVolumeDown(); + }); + } + + return () => { + ipc?.removeAllListeners('renderer-player-volume-mute'); + ipc?.removeAllListeners('renderer-player-volume-up'); + ipc?.removeAllListeners('renderer-player-volume-down'); + }; + }, [handleMute, handleVolumeDown, handleVolumeUp]); + + return { + handleMute, + handleVolumeDown, + handleVolumeSlider, + handleVolumeSliderState, + handleVolumeUp, + handleVolumeWheel, + }; }; diff --git a/src/renderer/features/player/hooks/use-scrobble.ts b/src/renderer/features/player/hooks/use-scrobble.ts index 5d11475f..bc88a084 100644 --- a/src/renderer/features/player/hooks/use-scrobble.ts +++ b/src/renderer/features/player/hooks/use-scrobble.ts @@ -34,286 +34,294 @@ Progress Events (Jellyfin only): */ const checkScrobbleConditions = (args: { - scrobbleAtDuration: number; - scrobbleAtPercentage: number; - songCompletedDuration: number; - songDuration: number; + scrobbleAtDuration: number; + scrobbleAtPercentage: number; + songCompletedDuration: number; + songDuration: number; }) => { - const { scrobbleAtDuration, scrobbleAtPercentage, songCompletedDuration, songDuration } = args; - const percentageOfSongCompleted = songDuration ? (songCompletedDuration / songDuration) * 100 : 0; + const { scrobbleAtDuration, scrobbleAtPercentage, songCompletedDuration, songDuration } = args; + const percentageOfSongCompleted = songDuration + ? (songCompletedDuration / songDuration) * 100 + : 0; - return ( - percentageOfSongCompleted >= scrobbleAtPercentage || songCompletedDuration >= scrobbleAtDuration - ); + return ( + percentageOfSongCompleted >= scrobbleAtPercentage || + songCompletedDuration >= scrobbleAtDuration + ); }; export const useScrobble = () => { - const status = useCurrentStatus(); - const scrobbleSettings = usePlaybackSettings().scrobble; - const isScrobbleEnabled = scrobbleSettings?.enabled; - const sendScrobble = useSendScrobble(); + const status = useCurrentStatus(); + const scrobbleSettings = usePlaybackSettings().scrobble; + const isScrobbleEnabled = scrobbleSettings?.enabled; + const sendScrobble = useSendScrobble(); - const [isCurrentSongScrobbled, setIsCurrentSongScrobbled] = useState(false); + const [isCurrentSongScrobbled, setIsCurrentSongScrobbled] = useState(false); - const handleScrobbleFromSeek = useCallback( - (currentTime: number) => { - if (!isScrobbleEnabled) return; + const handleScrobbleFromSeek = useCallback( + (currentTime: number) => { + if (!isScrobbleEnabled) return; - const currentSong = usePlayerStore.getState().current.song; + const currentSong = usePlayerStore.getState().current.song; - if (!currentSong?.id || currentSong?.serverType !== ServerType.JELLYFIN) return; + if (!currentSong?.id || currentSong?.serverType !== ServerType.JELLYFIN) return; - const position = - currentSong?.serverType === ServerType.JELLYFIN ? currentTime * 1e7 : undefined; + const position = + currentSong?.serverType === ServerType.JELLYFIN ? currentTime * 1e7 : undefined; - sendScrobble.mutate({ - query: { - event: 'timeupdate', - id: currentSong.id, - position, - submission: false, + sendScrobble.mutate({ + query: { + event: 'timeupdate', + id: currentSong.id, + position, + submission: false, + }, + serverId: currentSong?.serverId, + }); }, - serverId: currentSong?.serverId, - }); - }, - [isScrobbleEnabled, sendScrobble], - ); - - const progressIntervalId = useRef<ReturnType<typeof setInterval> | null>(null); - const songChangeTimeoutId = useRef<ReturnType<typeof setTimeout> | null>(null); - const handleScrobbleFromSongChange = useCallback( - (current: (QueueSong | number | undefined)[], previous: (QueueSong | number | undefined)[]) => { - if (!isScrobbleEnabled) return; - - if (progressIntervalId.current) { - clearInterval(progressIntervalId.current); - } - - // const currentSong = current[0] as QueueSong | undefined; - const previousSong = previous[0] as QueueSong; - const previousSongTime = previous[1] as number; - - // Send completion scrobble when song changes and a previous song exists - if (previousSong?.id) { - const shouldSubmitScrobble = checkScrobbleConditions({ - scrobbleAtDuration: scrobbleSettings?.scrobbleAtDuration, - scrobbleAtPercentage: scrobbleSettings?.scrobbleAtPercentage, - songCompletedDuration: previousSongTime, - songDuration: previousSong.duration, - }); - - if ( - (!isCurrentSongScrobbled && shouldSubmitScrobble) || - previousSong?.serverType === ServerType.JELLYFIN - ) { - const position = - previousSong?.serverType === ServerType.JELLYFIN ? previousSongTime * 1e7 : undefined; - - sendScrobble.mutate({ - query: { - id: previousSong.id, - position, - submission: true, - }, - serverId: previousSong?.serverId, - }); - } - } - - setIsCurrentSongScrobbled(false); - - // Use a timeout to prevent spamming the server with scrobble events when switching through songs quickly - clearTimeout(songChangeTimeoutId.current as ReturnType<typeof setTimeout>); - songChangeTimeoutId.current = setTimeout(() => { - const currentSong = current[0] as QueueSong | undefined; - - // Send start scrobble when song changes and the new song is playing - if (status === PlayerStatus.PLAYING && currentSong?.id) { - sendScrobble.mutate({ - query: { - event: 'start', - id: currentSong.id, - position: 0, - submission: false, - }, - serverId: currentSong?.serverId, - }); - - if (currentSong?.serverType === ServerType.JELLYFIN) { - progressIntervalId.current = setInterval(() => { - const currentTime = usePlayerStore.getState().current.time; - handleScrobbleFromSeek(currentTime); - }, 10000); - } - } - }, 2000); - }, - [ - isScrobbleEnabled, - scrobbleSettings?.scrobbleAtDuration, - scrobbleSettings?.scrobbleAtPercentage, - isCurrentSongScrobbled, - sendScrobble, - status, - handleScrobbleFromSeek, - ], - ); - - const handleScrobbleFromStatusChange = useCallback( - (status: PlayerStatus | undefined) => { - if (!isScrobbleEnabled) return; - - const currentSong = usePlayerStore.getState().current.song; - - if (!currentSong?.id) return; - - const position = - currentSong?.serverType === ServerType.JELLYFIN - ? usePlayerStore.getState().current.time * 1e7 - : undefined; - - // Whenever the player is restarted, send a 'start' scrobble - if (status === PlayerStatus.PLAYING) { - sendScrobble.mutate({ - query: { - event: 'unpause', - id: currentSong.id, - position, - submission: false, - }, - serverId: currentSong?.serverId, - }); - - if (currentSong?.serverType === ServerType.JELLYFIN) { - progressIntervalId.current = setInterval(() => { - const currentTime = usePlayerStore.getState().current.time; - handleScrobbleFromSeek(currentTime); - }, 10000); - } - - // Jellyfin is the only one that needs to send a 'pause' event to the server - } else if (currentSong?.serverType === ServerType.JELLYFIN) { - sendScrobble.mutate({ - query: { - event: 'pause', - id: currentSong.id, - position, - submission: false, - }, - serverId: currentSong?.serverId, - }); - - if (progressIntervalId.current) { - clearInterval(progressIntervalId.current as ReturnType<typeof setInterval>); - } - } else { - // If not already scrobbled, send a 'submission' scrobble if conditions are met - const shouldSubmitScrobble = checkScrobbleConditions({ - scrobbleAtDuration: scrobbleSettings?.scrobbleAtDuration, - scrobbleAtPercentage: scrobbleSettings?.scrobbleAtPercentage, - songCompletedDuration: usePlayerStore.getState().current.time, - songDuration: currentSong.duration, - }); - - if (!isCurrentSongScrobbled && shouldSubmitScrobble) { - sendScrobble.mutate({ - query: { - id: currentSong.id, - submission: true, - }, - serverId: currentSong?.serverId, - }); - - setIsCurrentSongScrobbled(true); - } - } - }, - [ - isScrobbleEnabled, - sendScrobble, - handleScrobbleFromSeek, - scrobbleSettings?.scrobbleAtDuration, - scrobbleSettings?.scrobbleAtPercentage, - isCurrentSongScrobbled, - ], - ); - - // When pressing the "Previous Track" button, the player will restart the current song if the - // currentTime is >= 10 seconds. Since the song / status change events are not triggered, we will - // need to perform another check to see if the scrobble conditions are met - const handleScrobbleFromSongRestart = useCallback( - (currentTime: number) => { - if (!isScrobbleEnabled) return; - - const currentSong = usePlayerStore.getState().current.song; - - if (!currentSong?.id) return; - - const position = - currentSong?.serverType === ServerType.JELLYFIN ? currentTime * 1e7 : undefined; - - const shouldSubmitScrobble = checkScrobbleConditions({ - scrobbleAtDuration: scrobbleSettings?.scrobbleAtDuration, - scrobbleAtPercentage: scrobbleSettings?.scrobbleAtPercentage, - songCompletedDuration: currentTime, - songDuration: currentSong.duration, - }); - - if (!isCurrentSongScrobbled && shouldSubmitScrobble) { - sendScrobble.mutate({ - query: { - id: currentSong.id, - position, - submission: true, - }, - serverId: currentSong?.serverId, - }); - } - - if (currentSong?.serverType === ServerType.JELLYFIN) { - sendScrobble.mutate({ - query: { - event: 'start', - id: currentSong.id, - position: 0, - submission: false, - }, - serverId: currentSong?.serverId, - }); - } - - setIsCurrentSongScrobbled(false); - }, - [ - isScrobbleEnabled, - scrobbleSettings?.scrobbleAtDuration, - scrobbleSettings?.scrobbleAtPercentage, - isCurrentSongScrobbled, - sendScrobble, - ], - ); - - useEffect(() => { - const unsubSongChange = usePlayerStore.subscribe( - (state) => [state.current.song, state.current.time], - handleScrobbleFromSongChange, - { - // We need the current time to check the scrobble condition, but we only want to - // trigger the callback when the song changes - equalityFn: (a, b) => (a[0] as QueueSong)?.id === (b[0] as QueueSong)?.id, - }, + [isScrobbleEnabled, sendScrobble], ); - const unsubStatusChange = usePlayerStore.subscribe( - (state) => state.current.status, - handleScrobbleFromStatusChange, + const progressIntervalId = useRef<ReturnType<typeof setInterval> | null>(null); + const songChangeTimeoutId = useRef<ReturnType<typeof setTimeout> | null>(null); + const handleScrobbleFromSongChange = useCallback( + ( + current: (QueueSong | number | undefined)[], + previous: (QueueSong | number | undefined)[], + ) => { + if (!isScrobbleEnabled) return; + + if (progressIntervalId.current) { + clearInterval(progressIntervalId.current); + } + + // const currentSong = current[0] as QueueSong | undefined; + const previousSong = previous[0] as QueueSong; + const previousSongTime = previous[1] as number; + + // Send completion scrobble when song changes and a previous song exists + if (previousSong?.id) { + const shouldSubmitScrobble = checkScrobbleConditions({ + scrobbleAtDuration: scrobbleSettings?.scrobbleAtDuration, + scrobbleAtPercentage: scrobbleSettings?.scrobbleAtPercentage, + songCompletedDuration: previousSongTime, + songDuration: previousSong.duration, + }); + + if ( + (!isCurrentSongScrobbled && shouldSubmitScrobble) || + previousSong?.serverType === ServerType.JELLYFIN + ) { + const position = + previousSong?.serverType === ServerType.JELLYFIN + ? previousSongTime * 1e7 + : undefined; + + sendScrobble.mutate({ + query: { + id: previousSong.id, + position, + submission: true, + }, + serverId: previousSong?.serverId, + }); + } + } + + setIsCurrentSongScrobbled(false); + + // Use a timeout to prevent spamming the server with scrobble events when switching through songs quickly + clearTimeout(songChangeTimeoutId.current as ReturnType<typeof setTimeout>); + songChangeTimeoutId.current = setTimeout(() => { + const currentSong = current[0] as QueueSong | undefined; + + // Send start scrobble when song changes and the new song is playing + if (status === PlayerStatus.PLAYING && currentSong?.id) { + sendScrobble.mutate({ + query: { + event: 'start', + id: currentSong.id, + position: 0, + submission: false, + }, + serverId: currentSong?.serverId, + }); + + if (currentSong?.serverType === ServerType.JELLYFIN) { + progressIntervalId.current = setInterval(() => { + const currentTime = usePlayerStore.getState().current.time; + handleScrobbleFromSeek(currentTime); + }, 10000); + } + } + }, 2000); + }, + [ + isScrobbleEnabled, + scrobbleSettings?.scrobbleAtDuration, + scrobbleSettings?.scrobbleAtPercentage, + isCurrentSongScrobbled, + sendScrobble, + status, + handleScrobbleFromSeek, + ], ); - return () => { - unsubSongChange(); - unsubStatusChange(); - }; - }, [handleScrobbleFromSongChange, handleScrobbleFromStatusChange]); + const handleScrobbleFromStatusChange = useCallback( + (status: PlayerStatus | undefined) => { + if (!isScrobbleEnabled) return; - return { handleScrobbleFromSeek, handleScrobbleFromSongRestart }; + const currentSong = usePlayerStore.getState().current.song; + + if (!currentSong?.id) return; + + const position = + currentSong?.serverType === ServerType.JELLYFIN + ? usePlayerStore.getState().current.time * 1e7 + : undefined; + + // Whenever the player is restarted, send a 'start' scrobble + if (status === PlayerStatus.PLAYING) { + sendScrobble.mutate({ + query: { + event: 'unpause', + id: currentSong.id, + position, + submission: false, + }, + serverId: currentSong?.serverId, + }); + + if (currentSong?.serverType === ServerType.JELLYFIN) { + progressIntervalId.current = setInterval(() => { + const currentTime = usePlayerStore.getState().current.time; + handleScrobbleFromSeek(currentTime); + }, 10000); + } + + // Jellyfin is the only one that needs to send a 'pause' event to the server + } else if (currentSong?.serverType === ServerType.JELLYFIN) { + sendScrobble.mutate({ + query: { + event: 'pause', + id: currentSong.id, + position, + submission: false, + }, + serverId: currentSong?.serverId, + }); + + if (progressIntervalId.current) { + clearInterval(progressIntervalId.current as ReturnType<typeof setInterval>); + } + } else { + // If not already scrobbled, send a 'submission' scrobble if conditions are met + const shouldSubmitScrobble = checkScrobbleConditions({ + scrobbleAtDuration: scrobbleSettings?.scrobbleAtDuration, + scrobbleAtPercentage: scrobbleSettings?.scrobbleAtPercentage, + songCompletedDuration: usePlayerStore.getState().current.time, + songDuration: currentSong.duration, + }); + + if (!isCurrentSongScrobbled && shouldSubmitScrobble) { + sendScrobble.mutate({ + query: { + id: currentSong.id, + submission: true, + }, + serverId: currentSong?.serverId, + }); + + setIsCurrentSongScrobbled(true); + } + } + }, + [ + isScrobbleEnabled, + sendScrobble, + handleScrobbleFromSeek, + scrobbleSettings?.scrobbleAtDuration, + scrobbleSettings?.scrobbleAtPercentage, + isCurrentSongScrobbled, + ], + ); + + // When pressing the "Previous Track" button, the player will restart the current song if the + // currentTime is >= 10 seconds. Since the song / status change events are not triggered, we will + // need to perform another check to see if the scrobble conditions are met + const handleScrobbleFromSongRestart = useCallback( + (currentTime: number) => { + if (!isScrobbleEnabled) return; + + const currentSong = usePlayerStore.getState().current.song; + + if (!currentSong?.id) return; + + const position = + currentSong?.serverType === ServerType.JELLYFIN ? currentTime * 1e7 : undefined; + + const shouldSubmitScrobble = checkScrobbleConditions({ + scrobbleAtDuration: scrobbleSettings?.scrobbleAtDuration, + scrobbleAtPercentage: scrobbleSettings?.scrobbleAtPercentage, + songCompletedDuration: currentTime, + songDuration: currentSong.duration, + }); + + if (!isCurrentSongScrobbled && shouldSubmitScrobble) { + sendScrobble.mutate({ + query: { + id: currentSong.id, + position, + submission: true, + }, + serverId: currentSong?.serverId, + }); + } + + if (currentSong?.serverType === ServerType.JELLYFIN) { + sendScrobble.mutate({ + query: { + event: 'start', + id: currentSong.id, + position: 0, + submission: false, + }, + serverId: currentSong?.serverId, + }); + } + + setIsCurrentSongScrobbled(false); + }, + [ + isScrobbleEnabled, + scrobbleSettings?.scrobbleAtDuration, + scrobbleSettings?.scrobbleAtPercentage, + isCurrentSongScrobbled, + sendScrobble, + ], + ); + + useEffect(() => { + const unsubSongChange = usePlayerStore.subscribe( + (state) => [state.current.song, state.current.time], + handleScrobbleFromSongChange, + { + // We need the current time to check the scrobble condition, but we only want to + // trigger the callback when the song changes + equalityFn: (a, b) => (a[0] as QueueSong)?.id === (b[0] as QueueSong)?.id, + }, + ); + + const unsubStatusChange = usePlayerStore.subscribe( + (state) => state.current.status, + handleScrobbleFromStatusChange, + ); + + return () => { + unsubSongChange(); + unsubStatusChange(); + }; + }, [handleScrobbleFromSongChange, handleScrobbleFromStatusChange]); + + return { handleScrobbleFromSeek, handleScrobbleFromSongRestart }; }; diff --git a/src/renderer/features/player/mutations/scrobble-mutation.ts b/src/renderer/features/player/mutations/scrobble-mutation.ts index 33871af3..77dc7251 100644 --- a/src/renderer/features/player/mutations/scrobble-mutation.ts +++ b/src/renderer/features/player/mutations/scrobble-mutation.ts @@ -6,25 +6,25 @@ import { MutationOptions } from '/@/renderer/lib/react-query'; import { getServerById, useIncrementQueuePlayCount } from '/@/renderer/store'; export const useSendScrobble = (options?: MutationOptions) => { - const incrementPlayCount = useIncrementQueuePlayCount(); + const incrementPlayCount = useIncrementQueuePlayCount(); - return useMutation< - ScrobbleResponse, - AxiosError, - Omit<ScrobbleArgs, 'server' | 'apiClientProps'>, - null - >({ - mutationFn: (args) => { - const server = getServerById(args.serverId); - if (!server) throw new Error('Server not found'); - return api.controller.scrobble({ ...args, apiClientProps: { server } }); - }, - onSuccess: (_data, variables) => { - // Manually increment the play count for the song in the queue if scrobble was submitted - if (variables.query.submission) { - incrementPlayCount([variables.query.id]); - } - }, - ...options, - }); + return useMutation< + ScrobbleResponse, + AxiosError, + Omit<ScrobbleArgs, 'server' | 'apiClientProps'>, + null + >({ + mutationFn: (args) => { + const server = getServerById(args.serverId); + if (!server) throw new Error('Server not found'); + return api.controller.scrobble({ ...args, apiClientProps: { server } }); + }, + onSuccess: (_data, variables) => { + // Manually increment the play count for the song in the queue if scrobble was submitted + if (variables.query.submission) { + incrementPlayCount([variables.query.id]); + } + }, + ...options, + }); }; diff --git a/src/renderer/features/player/utils.ts b/src/renderer/features/player/utils.ts index 36c94d6b..3be679fc 100644 --- a/src/renderer/features/player/utils.ts +++ b/src/renderer/features/player/utils.ts @@ -2,195 +2,195 @@ import { QueryClient } from '@tanstack/react-query'; import { api } from '/@/renderer/api'; import { queryKeys } from '/@/renderer/api/query-keys'; import { - PlaylistSongListQuery, - SongDetailQuery, - SongListQuery, - SongListResponse, - SongListSort, - SortOrder, + PlaylistSongListQuery, + SongDetailQuery, + SongListQuery, + SongListResponse, + SongListSort, + SortOrder, } from '/@/renderer/api/types'; import { ServerListItem } from '/@/renderer/types'; export const getPlaylistSongsById = async (args: { - id: string; - query?: Partial<PlaylistSongListQuery>; - queryClient: QueryClient; - server: ServerListItem; + id: string; + query?: Partial<PlaylistSongListQuery>; + queryClient: QueryClient; + server: ServerListItem; }) => { - const { id, queryClient, server, query } = args; + const { id, queryClient, server, query } = args; - const queryFilter: PlaylistSongListQuery = { - id, - sortBy: SongListSort.ID, - sortOrder: SortOrder.ASC, - startIndex: 0, - ...query, - }; + const queryFilter: PlaylistSongListQuery = { + id, + sortBy: SongListSort.ID, + sortOrder: SortOrder.ASC, + startIndex: 0, + ...query, + }; - const queryKey = queryKeys.playlists.songList(server?.id, id, queryFilter); + const queryKey = queryKeys.playlists.songList(server?.id, id, queryFilter); - const res = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.getPlaylistSongList({ - apiClientProps: { - server, - signal, + const res = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.getPlaylistSongList({ + apiClientProps: { + server, + signal, + }, + query: queryFilter, + }), + { + cacheTime: 1000 * 60, + staleTime: 1000 * 60, }, - query: queryFilter, - }), - { - cacheTime: 1000 * 60, - staleTime: 1000 * 60, - }, - ); + ); - return res; + return res; }; export const getAlbumSongsById = async (args: { - id: string[]; - orderByIds?: boolean; - query?: Partial<SongListQuery>; - queryClient: QueryClient; - server: ServerListItem; + id: string[]; + orderByIds?: boolean; + query?: Partial<SongListQuery>; + queryClient: QueryClient; + server: ServerListItem; }) => { - const { id, queryClient, server, query } = args; + const { id, queryClient, server, query } = args; - const queryFilter: SongListQuery = { - albumIds: id, - sortBy: SongListSort.ALBUM, - sortOrder: SortOrder.ASC, - startIndex: 0, - ...query, - }; + const queryFilter: SongListQuery = { + albumIds: id, + sortBy: SongListSort.ALBUM, + sortOrder: SortOrder.ASC, + startIndex: 0, + ...query, + }; - const queryKey = queryKeys.songs.list(server?.id, queryFilter); + const queryKey = queryKeys.songs.list(server?.id, queryFilter); - const res = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.getSongList({ - apiClientProps: { - server, - signal, + const res = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.getSongList({ + apiClientProps: { + server, + signal, + }, + query: queryFilter, + }), + { + cacheTime: 1000 * 60, + staleTime: 1000 * 60, }, - query: queryFilter, - }), - { - cacheTime: 1000 * 60, - staleTime: 1000 * 60, - }, - ); + ); - return res; + return res; }; export const getAlbumArtistSongsById = async (args: { - id: string[]; - orderByIds?: boolean; - query?: Partial<SongListQuery>; - queryClient: QueryClient; - server: ServerListItem; + id: string[]; + orderByIds?: boolean; + query?: Partial<SongListQuery>; + queryClient: QueryClient; + server: ServerListItem; }) => { - const { id, queryClient, server, query } = args; + const { id, queryClient, server, query } = args; - const queryFilter: SongListQuery = { - artistIds: id || [], - sortBy: SongListSort.ALBUM_ARTIST, - sortOrder: SortOrder.ASC, - startIndex: 0, - ...query, - }; + const queryFilter: SongListQuery = { + artistIds: id || [], + sortBy: SongListSort.ALBUM_ARTIST, + sortOrder: SortOrder.ASC, + startIndex: 0, + ...query, + }; - const queryKey = queryKeys.songs.list(server?.id, queryFilter); + const queryKey = queryKeys.songs.list(server?.id, queryFilter); - const res = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.getSongList({ - apiClientProps: { - server, - signal, + const res = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.getSongList({ + apiClientProps: { + server, + signal, + }, + query: queryFilter, + }), + { + cacheTime: 1000 * 60, + staleTime: 1000 * 60, }, - query: queryFilter, - }), - { - cacheTime: 1000 * 60, - staleTime: 1000 * 60, - }, - ); + ); - return res; + return res; }; export const getSongsByQuery = async (args: { - query?: Partial<SongListQuery>; - queryClient: QueryClient; - server: ServerListItem; + query?: Partial<SongListQuery>; + queryClient: QueryClient; + server: ServerListItem; }) => { - const { queryClient, server, query } = args; + const { queryClient, server, query } = args; - const queryFilter: SongListQuery = { - sortBy: SongListSort.ALBUM, - sortOrder: SortOrder.ASC, - startIndex: 0, - ...query, - }; + const queryFilter: SongListQuery = { + sortBy: SongListSort.ALBUM, + sortOrder: SortOrder.ASC, + startIndex: 0, + ...query, + }; - const queryKey = queryKeys.songs.list(server?.id, queryFilter); + const queryKey = queryKeys.songs.list(server?.id, queryFilter); - const res = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.getSongList({ - apiClientProps: { - server, - signal, + const res = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.getSongList({ + apiClientProps: { + server, + signal, + }, + query: queryFilter, + }), + { + cacheTime: 1000 * 60, + staleTime: 1000 * 60, }, - query: queryFilter, - }), - { - cacheTime: 1000 * 60, - staleTime: 1000 * 60, - }, - ); + ); - return res; + return res; }; export const getSongById = async (args: { - id: string; - queryClient: QueryClient; - server: ServerListItem; + id: string; + queryClient: QueryClient; + server: ServerListItem; }): Promise<SongListResponse> => { - const { id, queryClient, server } = args; + const { id, queryClient, server } = args; - const queryFilter: SongDetailQuery = { id }; + const queryFilter: SongDetailQuery = { id }; - const queryKey = queryKeys.songs.detail(server?.id, queryFilter); + const queryKey = queryKeys.songs.detail(server?.id, queryFilter); - const res = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.getSongDetail({ - apiClientProps: { - server, - signal, + const res = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.getSongDetail({ + apiClientProps: { + server, + signal, + }, + query: queryFilter, + }), + { + cacheTime: 1000 * 60, + staleTime: 1000 * 60, }, - query: queryFilter, - }), - { - cacheTime: 1000 * 60, - staleTime: 1000 * 60, - }, - ); + ); - if (!res) throw new Error('Song not found'); + if (!res) throw new Error('Song not found'); - return { - items: [res], - startIndex: 0, - totalRecordCount: 1, - }; + return { + items: [res], + startIndex: 0, + totalRecordCount: 1, + }; }; diff --git a/src/renderer/features/playlists/components/add-to-playlist-context-modal.tsx b/src/renderer/features/playlists/components/add-to-playlist-context-modal.tsx index 69774827..f3fa383c 100644 --- a/src/renderer/features/playlists/components/add-to-playlist-context-modal.tsx +++ b/src/renderer/features/playlists/components/add-to-playlist-context-modal.tsx @@ -12,211 +12,212 @@ import { queryClient } from '/@/renderer/lib/react-query'; import { useCurrentServer } from '/@/renderer/store'; export const AddToPlaylistContextModal = ({ - id, - innerProps, + id, + innerProps, }: ContextModalProps<{ - albumId?: string[]; - artistId?: string[]; - songId?: string[]; + albumId?: string[]; + artistId?: string[]; + songId?: string[]; }>) => { - const { albumId, artistId, songId } = innerProps; - const server = useCurrentServer(); - const [isLoading, setIsLoading] = useState(false); + const { albumId, artistId, songId } = innerProps; + const server = useCurrentServer(); + const [isLoading, setIsLoading] = useState(false); - const addToPlaylistMutation = useAddToPlaylist({}); + const addToPlaylistMutation = useAddToPlaylist({}); - const playlistList = usePlaylistList({ - query: { - _custom: { - navidrome: { - smart: false, + const playlistList = usePlaylistList({ + query: { + _custom: { + navidrome: { + smart: false, + }, + }, + sortBy: PlaylistListSort.NAME, + sortOrder: SortOrder.ASC, + startIndex: 0, }, - }, - sortBy: PlaylistListSort.NAME, - sortOrder: SortOrder.ASC, - startIndex: 0, - }, - serverId: server?.id, - }); - - const playlistSelect = useMemo(() => { - return ( - playlistList.data?.items?.map((playlist) => ({ - label: playlist.name, - value: playlist.id, - })) || [] - ); - }, [playlistList.data]); - - const form = useForm({ - initialValues: { - playlistId: [], - skipDuplicates: true, - }, - }); - - const getSongsByAlbum = async (albumId: string) => { - const query: SongListQuery = { - albumIds: [albumId], - sortBy: SongListSort.ALBUM, - sortOrder: SortOrder.ASC, - startIndex: 0, - }; - - const queryKey = queryKeys.songs.list(server?.id || '', query); - - const songsRes = await queryClient.fetchQuery(queryKey, ({ signal }) => { - if (!server) throw new Error('No server'); - return api.controller.getSongList({ apiClientProps: { server, signal }, query }); + serverId: server?.id, }); - return songsRes; - }; + const playlistSelect = useMemo(() => { + return ( + playlistList.data?.items?.map((playlist) => ({ + label: playlist.name, + value: playlist.id, + })) || [] + ); + }, [playlistList.data]); - const getSongsByArtist = async (artistId: string) => { - const query: SongListQuery = { - artistIds: [artistId], - sortBy: SongListSort.ARTIST, - sortOrder: SortOrder.ASC, - startIndex: 0, - }; - - const queryKey = queryKeys.songs.list(server?.id || '', query); - - const songsRes = await queryClient.fetchQuery(queryKey, ({ signal }) => { - if (!server) throw new Error('No server'); - return api.controller.getSongList({ apiClientProps: { server, signal }, query }); + const form = useForm({ + initialValues: { + playlistId: [], + skipDuplicates: true, + }, }); - return songsRes; - }; - - const isSubmitDisabled = form.values.playlistId.length === 0 || addToPlaylistMutation.isLoading; - - const handleSubmit = form.onSubmit(async (values) => { - setIsLoading(true); - const allSongIds: string[] = []; - const uniqueSongIds: string[] = []; - - if (albumId && albumId.length > 0) { - for (const id of albumId) { - const songs = await getSongsByAlbum(id); - allSongIds.push(...(songs?.items?.map((song) => song.id) || [])); - } - } - - if (artistId && artistId.length > 0) { - for (const id of artistId) { - const songs = await getSongsByArtist(id); - allSongIds.push(...(songs?.items?.map((song) => song.id) || [])); - } - } - - if (songId && songId.length > 0) { - allSongIds.push(...songId); - } - - for (const playlistId of values.playlistId) { - if (values.skipDuplicates) { - const query = { - id: playlistId, - startIndex: 0, + const getSongsByAlbum = async (albumId: string) => { + const query: SongListQuery = { + albumIds: [albumId], + sortBy: SongListSort.ALBUM, + sortOrder: SortOrder.ASC, + startIndex: 0, }; - const queryKey = queryKeys.playlists.songList(server?.id || '', playlistId, query); + const queryKey = queryKeys.songs.list(server?.id || '', query); - const playlistSongsRes = await queryClient.fetchQuery(queryKey, ({ signal }) => { - if (!server) throw new Error('No server'); - return api.controller.getPlaylistSongList({ - apiClientProps: { - server, - signal, - }, - query: { id: playlistId, startIndex: 0 }, - }); + const songsRes = await queryClient.fetchQuery(queryKey, ({ signal }) => { + if (!server) throw new Error('No server'); + return api.controller.getSongList({ apiClientProps: { server, signal }, query }); }); - const playlistSongIds = playlistSongsRes?.items?.map((song) => song.id); + return songsRes; + }; - for (const songId of allSongIds) { - if (!playlistSongIds?.includes(songId)) { - uniqueSongIds.push(songId); - } + const getSongsByArtist = async (artistId: string) => { + const query: SongListQuery = { + artistIds: [artistId], + sortBy: SongListSort.ARTIST, + sortOrder: SortOrder.ASC, + startIndex: 0, + }; + + const queryKey = queryKeys.songs.list(server?.id || '', query); + + const songsRes = await queryClient.fetchQuery(queryKey, ({ signal }) => { + if (!server) throw new Error('No server'); + return api.controller.getSongList({ apiClientProps: { server, signal }, query }); + }); + + return songsRes; + }; + + const isSubmitDisabled = form.values.playlistId.length === 0 || addToPlaylistMutation.isLoading; + + const handleSubmit = form.onSubmit(async (values) => { + setIsLoading(true); + const allSongIds: string[] = []; + const uniqueSongIds: string[] = []; + + if (albumId && albumId.length > 0) { + for (const id of albumId) { + const songs = await getSongsByAlbum(id); + allSongIds.push(...(songs?.items?.map((song) => song.id) || [])); + } } - } - if (values.skipDuplicates ? uniqueSongIds.length > 0 : allSongIds.length > 0) { - if (!server) return null; - addToPlaylistMutation.mutate( - { - body: { songId: values.skipDuplicates ? uniqueSongIds : allSongIds }, - query: { id: playlistId }, - serverId: server?.id, - }, - { - onError: (err) => { - toast.error({ - message: `[${ - playlistSelect.find((playlist) => playlist.value === playlistId)?.label - }] ${err.message}`, - title: 'Failed to add songs to playlist', - }); - }, - }, - ); - } - } + if (artistId && artistId.length > 0) { + for (const id of artistId) { + const songs = await getSongsByArtist(id); + allSongIds.push(...(songs?.items?.map((song) => song.id) || [])); + } + } - setIsLoading(false); - toast.success({ - message: `Added ${ - values.skipDuplicates ? uniqueSongIds.length : allSongIds.length - } songs to ${values.playlistId.length} playlist(s)`, + if (songId && songId.length > 0) { + allSongIds.push(...songId); + } + + for (const playlistId of values.playlistId) { + if (values.skipDuplicates) { + const query = { + id: playlistId, + startIndex: 0, + }; + + const queryKey = queryKeys.playlists.songList(server?.id || '', playlistId, query); + + const playlistSongsRes = await queryClient.fetchQuery(queryKey, ({ signal }) => { + if (!server) throw new Error('No server'); + return api.controller.getPlaylistSongList({ + apiClientProps: { + server, + signal, + }, + query: { id: playlistId, startIndex: 0 }, + }); + }); + + const playlistSongIds = playlistSongsRes?.items?.map((song) => song.id); + + for (const songId of allSongIds) { + if (!playlistSongIds?.includes(songId)) { + uniqueSongIds.push(songId); + } + } + } + + if (values.skipDuplicates ? uniqueSongIds.length > 0 : allSongIds.length > 0) { + if (!server) return null; + addToPlaylistMutation.mutate( + { + body: { songId: values.skipDuplicates ? uniqueSongIds : allSongIds }, + query: { id: playlistId }, + serverId: server?.id, + }, + { + onError: (err) => { + toast.error({ + message: `[${ + playlistSelect.find((playlist) => playlist.value === playlistId) + ?.label + }] ${err.message}`, + title: 'Failed to add songs to playlist', + }); + }, + }, + ); + } + } + + setIsLoading(false); + toast.success({ + message: `Added ${ + values.skipDuplicates ? uniqueSongIds.length : allSongIds.length + } songs to ${values.playlistId.length} playlist(s)`, + }); + closeModal(id); + return null; }); - closeModal(id); - return null; - }); - return ( - <Box p="1rem"> - <form onSubmit={handleSubmit}> - <Stack> - <MultiSelect - clearable - searchable - data={playlistSelect} - disabled={playlistList.isLoading} - label="Playlists" - size="md" - {...form.getInputProps('playlistId')} - /> - <Switch - label="Skip duplicates" - {...form.getInputProps('skipDuplicates', { type: 'checkbox' })} - /> - <Group position="right"> - <Group> - <Button - disabled={addToPlaylistMutation.isLoading} - size="md" - variant="subtle" - onClick={() => closeModal(id)} - > - Cancel - </Button> - <Button - disabled={isSubmitDisabled} - loading={isLoading} - size="md" - type="submit" - variant="filled" - > - Add - </Button> - </Group> - </Group> - </Stack> - </form> - </Box> - ); + return ( + <Box p="1rem"> + <form onSubmit={handleSubmit}> + <Stack> + <MultiSelect + clearable + searchable + data={playlistSelect} + disabled={playlistList.isLoading} + label="Playlists" + size="md" + {...form.getInputProps('playlistId')} + /> + <Switch + label="Skip duplicates" + {...form.getInputProps('skipDuplicates', { type: 'checkbox' })} + /> + <Group position="right"> + <Group> + <Button + disabled={addToPlaylistMutation.isLoading} + size="md" + variant="subtle" + onClick={() => closeModal(id)} + > + Cancel + </Button> + <Button + disabled={isSubmitDisabled} + loading={isLoading} + size="md" + type="submit" + variant="filled" + > + Add + </Button> + </Group> + </Group> + </Stack> + </form> + </Box> + ); }; diff --git a/src/renderer/features/playlists/components/create-playlist-form.tsx b/src/renderer/features/playlists/components/create-playlist-form.tsx index 1fd4f99c..608141cd 100644 --- a/src/renderer/features/playlists/components/create-playlist-form.tsx +++ b/src/renderer/features/playlists/components/create-playlist-form.tsx @@ -4,140 +4,142 @@ import { useRef, useState } from 'react'; import { CreatePlaylistBody, ServerType, SongListSort } from '/@/renderer/api/types'; import { Button, Switch, Text, TextInput, toast } from '/@/renderer/components'; import { - PlaylistQueryBuilder, - PlaylistQueryBuilderRef, + PlaylistQueryBuilder, + PlaylistQueryBuilderRef, } from '/@/renderer/features/playlists/components/playlist-query-builder'; import { useCreatePlaylist } from '/@/renderer/features/playlists/mutations/create-playlist-mutation'; import { convertQueryGroupToNDQuery } from '/@/renderer/features/playlists/utils'; import { useCurrentServer } from '/@/renderer/store'; interface CreatePlaylistFormProps { - onCancel: () => void; + onCancel: () => void; } export const CreatePlaylistForm = ({ onCancel }: CreatePlaylistFormProps) => { - const mutation = useCreatePlaylist({}); - const server = useCurrentServer(); - const queryBuilderRef = useRef<PlaylistQueryBuilderRef>(null); + const mutation = useCreatePlaylist({}); + const server = useCurrentServer(); + const queryBuilderRef = useRef<PlaylistQueryBuilderRef>(null); - const form = useForm<CreatePlaylistBody>({ - initialValues: { - _custom: { - navidrome: { - public: false, - rules: undefined, - }, - }, - comment: '', - name: '', - }, - }); - const [isSmartPlaylist, setIsSmartPlaylist] = useState(false); - - const handleSubmit = form.onSubmit((values) => { - if (isSmartPlaylist) { - values._custom!.navidrome = { - ...values._custom?.navidrome, - rules: queryBuilderRef.current?.getFilters(), - }; - } - - const smartPlaylist = queryBuilderRef.current?.getFilters(); - - if (!server) return; - - mutation.mutate( - { - body: { - ...values, - _custom: { - navidrome: { - ...values._custom?.navidrome, - rules: - isSmartPlaylist && smartPlaylist?.filters - ? { - ...convertQueryGroupToNDQuery(smartPlaylist.filters), - ...smartPlaylist.extraFilters, - } - : undefined, + const form = useForm<CreatePlaylistBody>({ + initialValues: { + _custom: { + navidrome: { + public: false, + rules: undefined, + }, }, - }, + comment: '', + name: '', }, - serverId: server.id, - }, - { - onError: (err) => { - toast.error({ message: err.message, title: 'Error creating playlist' }); - }, - onSuccess: () => { - toast.success({ message: `Playlist has been created` }); - onCancel(); - }, - }, + }); + const [isSmartPlaylist, setIsSmartPlaylist] = useState(false); + + const handleSubmit = form.onSubmit((values) => { + if (isSmartPlaylist) { + values._custom!.navidrome = { + ...values._custom?.navidrome, + rules: queryBuilderRef.current?.getFilters(), + }; + } + + const smartPlaylist = queryBuilderRef.current?.getFilters(); + + if (!server) return; + + mutation.mutate( + { + body: { + ...values, + _custom: { + navidrome: { + ...values._custom?.navidrome, + rules: + isSmartPlaylist && smartPlaylist?.filters + ? { + ...convertQueryGroupToNDQuery(smartPlaylist.filters), + ...smartPlaylist.extraFilters, + } + : undefined, + }, + }, + }, + serverId: server.id, + }, + { + onError: (err) => { + toast.error({ message: err.message, title: 'Error creating playlist' }); + }, + onSuccess: () => { + toast.success({ message: `Playlist has been created` }); + onCancel(); + }, + }, + ); + }); + + const isPublicDisplayed = server?.type === ServerType.NAVIDROME; + const isSubmitDisabled = !form.values.name || mutation.isLoading; + + return ( + <form onSubmit={handleSubmit}> + <Stack> + <TextInput + data-autofocus + required + label="Name" + {...form.getInputProps('name')} + /> + <TextInput + label="Description" + {...form.getInputProps('comment')} + /> + <Group> + {isPublicDisplayed && ( + <Switch + label="Is public?" + {...form.getInputProps('_custom.navidrome.public', { + type: 'checkbox', + })} + /> + )} + {server?.type === ServerType.NAVIDROME && ( + <Switch + label="Is smart playlist?" + onChange={(e) => setIsSmartPlaylist(e.currentTarget.checked)} + /> + )} + </Group> + {server?.type === ServerType.NAVIDROME && isSmartPlaylist && ( + <Stack pt="1rem"> + <Text>Query Editor</Text> + <PlaylistQueryBuilder + ref={queryBuilderRef} + isSaving={false} + limit={undefined} + query={undefined} + sortBy={SongListSort.ALBUM} + sortOrder="asc" + /> + </Stack> + )} + + <Group position="right"> + <Button + variant="subtle" + onClick={onCancel} + > + Cancel + </Button> + <Button + disabled={isSubmitDisabled} + loading={mutation.isLoading} + type="submit" + variant="filled" + > + Save + </Button> + </Group> + </Stack> + </form> ); - }); - - const isPublicDisplayed = server?.type === ServerType.NAVIDROME; - const isSubmitDisabled = !form.values.name || mutation.isLoading; - - return ( - <form onSubmit={handleSubmit}> - <Stack> - <TextInput - data-autofocus - required - label="Name" - {...form.getInputProps('name')} - /> - <TextInput - label="Description" - {...form.getInputProps('comment')} - /> - <Group> - {isPublicDisplayed && ( - <Switch - label="Is public?" - {...form.getInputProps('_custom.navidrome.public', { type: 'checkbox' })} - /> - )} - {server?.type === ServerType.NAVIDROME && ( - <Switch - label="Is smart playlist?" - onChange={(e) => setIsSmartPlaylist(e.currentTarget.checked)} - /> - )} - </Group> - {server?.type === ServerType.NAVIDROME && isSmartPlaylist && ( - <Stack pt="1rem"> - <Text>Query Editor</Text> - <PlaylistQueryBuilder - ref={queryBuilderRef} - isSaving={false} - limit={undefined} - query={undefined} - sortBy={SongListSort.ALBUM} - sortOrder="asc" - /> - </Stack> - )} - - <Group position="right"> - <Button - variant="subtle" - onClick={onCancel} - > - Cancel - </Button> - <Button - disabled={isSubmitDisabled} - loading={mutation.isLoading} - type="submit" - variant="filled" - > - Save - </Button> - </Group> - </Stack> - </form> - ); }; diff --git a/src/renderer/features/playlists/components/playlist-detail-content.tsx b/src/renderer/features/playlists/components/playlist-detail-content.tsx index cab88d93..9bcb73d8 100644 --- a/src/renderer/features/playlists/components/playlist-detail-content.tsx +++ b/src/renderer/features/playlists/components/playlist-detail-content.tsx @@ -10,14 +10,14 @@ import styled from 'styled-components'; import { LibraryItem, QueueSong } from '/@/renderer/api/types'; import { Button, ConfirmModal, DropdownMenu, MotionGroup, toast } from '/@/renderer/components'; import { - getColumnDefs, - useFixedTableHeader, - VirtualTable, + getColumnDefs, + useFixedTableHeader, + VirtualTable, } from '/@/renderer/components/virtual-table'; import { useHandleTableContextMenu } from '/@/renderer/features/context-menu'; import { - PLAYLIST_SONG_CONTEXT_MENU_ITEMS, - SMART_PLAYLIST_SONG_CONTEXT_MENU_ITEMS, + PLAYLIST_SONG_CONTEXT_MENU_ITEMS, + SMART_PLAYLIST_SONG_CONTEXT_MENU_ITEMS, } from '/@/renderer/features/context-menu/context-menu-items'; import { usePlayQueueAdd } from '/@/renderer/features/player'; import { openUpdatePlaylistModal } from '/@/renderer/features/playlists/components/update-playlist-form'; @@ -31,226 +31,232 @@ import { usePlayButtonBehavior } from '/@/renderer/store/settings.store'; import { Play } from '/@/renderer/types'; const ContentContainer = styled.div` - position: relative; - display: flex; - flex-direction: column; - padding: 1rem 2rem 5rem; - overflow: hidden; + position: relative; + display: flex; + flex-direction: column; + padding: 1rem 2rem 5rem; + overflow: hidden; - .ag-theme-alpine-dark { - --ag-header-background-color: rgba(0, 0, 0, 0%) !important; - } + .ag-theme-alpine-dark { + --ag-header-background-color: rgba(0, 0, 0, 0%) !important; + } - .ag-header { - margin-bottom: 0.5rem; - } + .ag-header { + margin-bottom: 0.5rem; + } `; interface PlaylistDetailContentProps { - tableRef: MutableRefObject<AgGridReactType | null>; + tableRef: MutableRefObject<AgGridReactType | null>; } export const PlaylistDetailContent = ({ tableRef }: PlaylistDetailContentProps) => { - const navigate = useNavigate(); - const { playlistId } = useParams() as { playlistId: string }; - const page = useSongListStore(); - const handlePlayQueueAdd = usePlayQueueAdd(); - const server = useCurrentServer(); - const detailQuery = usePlaylistDetail({ query: { id: playlistId }, serverId: server?.id }); - const playButtonBehavior = usePlayButtonBehavior(); + const navigate = useNavigate(); + const { playlistId } = useParams() as { playlistId: string }; + const page = useSongListStore(); + const handlePlayQueueAdd = usePlayQueueAdd(); + const server = useCurrentServer(); + const detailQuery = usePlaylistDetail({ query: { id: playlistId }, serverId: server?.id }); + const playButtonBehavior = usePlayButtonBehavior(); - const playlistSongsQueryInfinite = usePlaylistSongListInfinite({ - options: { - cacheTime: 0, - keepPreviousData: false, - }, - query: { - id: playlistId, - limit: 50, - startIndex: 0, - }, - serverId: server?.id, - }); - - const handleLoadMore = () => { - playlistSongsQueryInfinite.fetchNextPage(); - }; - - const columnDefs: ColDef[] = useMemo( - () => - getColumnDefs(page.table.columns).filter((c) => c.colId !== 'album' && c.colId !== 'artist'), - [page.table.columns], - ); - - const contextMenuItems = useMemo(() => { - if (detailQuery?.data?.rules) { - return SMART_PLAYLIST_SONG_CONTEXT_MENU_ITEMS; - } - - return PLAYLIST_SONG_CONTEXT_MENU_ITEMS; - }, [detailQuery?.data?.rules]); - - const handleContextMenu = useHandleTableContextMenu(LibraryItem.SONG, contextMenuItems, { - playlistId, - }); - - const playlistSongData = useMemo( - () => playlistSongsQueryInfinite.data?.pages.flatMap((p) => p?.items), - [playlistSongsQueryInfinite.data?.pages], - ); - - const { intersectRef, tableContainerRef } = useFixedTableHeader(); - - const deletePlaylistMutation = useDeletePlaylist({}); - - const handleDeletePlaylist = () => { - deletePlaylistMutation.mutate( - { query: { id: playlistId }, serverId: server?.id }, - { - onError: (err) => { - toast.error({ - message: err.message, - title: 'Error deleting playlist', - }); + const playlistSongsQueryInfinite = usePlaylistSongListInfinite({ + options: { + cacheTime: 0, + keepPreviousData: false, }, - onSuccess: () => { - toast.success({ - message: `Playlist has been deleted`, - }); - closeAllModals(); - navigate(AppRoute.PLAYLISTS); + query: { + id: playlistId, + limit: 50, + startIndex: 0, }, - }, + serverId: server?.id, + }); + + const handleLoadMore = () => { + playlistSongsQueryInfinite.fetchNextPage(); + }; + + const columnDefs: ColDef[] = useMemo( + () => + getColumnDefs(page.table.columns).filter( + (c) => c.colId !== 'album' && c.colId !== 'artist', + ), + [page.table.columns], ); - }; - const openDeletePlaylist = () => { - openModal({ - children: ( - <ConfirmModal - loading={deletePlaylistMutation.isLoading} - onConfirm={handleDeletePlaylist} - > - Are you sure you want to delete this playlist? - </ConfirmModal> - ), - title: 'Delete playlist', + const contextMenuItems = useMemo(() => { + if (detailQuery?.data?.rules) { + return SMART_PLAYLIST_SONG_CONTEXT_MENU_ITEMS; + } + + return PLAYLIST_SONG_CONTEXT_MENU_ITEMS; + }, [detailQuery?.data?.rules]); + + const handleContextMenu = useHandleTableContextMenu(LibraryItem.SONG, contextMenuItems, { + playlistId, }); - }; - const handlePlay = (playType?: Play) => { - handlePlayQueueAdd?.({ - byItemType: { - id: [playlistId], - type: LibraryItem.PLAYLIST, - }, - playType: playType || playButtonBehavior, - }); - }; + const playlistSongData = useMemo( + () => playlistSongsQueryInfinite.data?.pages.flatMap((p) => p?.items), + [playlistSongsQueryInfinite.data?.pages], + ); - const handleRowDoubleClick = (e: RowDoubleClickedEvent<QueueSong>) => { - if (!e.data) return; + const { intersectRef, tableContainerRef } = useFixedTableHeader(); - handlePlayQueueAdd?.({ - byItemType: { - id: [playlistId], - type: LibraryItem.PLAYLIST, - }, - initialSongId: e.data.id, - playType: playButtonBehavior, - }); - }; + const deletePlaylistMutation = useDeletePlaylist({}); - const loadMoreRef = useRef<HTMLButtonElement | null>(null); + const handleDeletePlaylist = () => { + deletePlaylistMutation.mutate( + { query: { id: playlistId }, serverId: server?.id }, + { + onError: (err) => { + toast.error({ + message: err.message, + title: 'Error deleting playlist', + }); + }, + onSuccess: () => { + toast.success({ + message: `Playlist has been deleted`, + }); + closeAllModals(); + navigate(AppRoute.PLAYLISTS); + }, + }, + ); + }; - return ( - <ContentContainer> - <Group - ref={intersectRef} - p="1rem" - position="apart" - > - <Group> - <PlayButton onClick={() => handlePlay()} /> - <DropdownMenu position="bottom-start"> - <DropdownMenu.Target> - <Button - compact - variant="subtle" - > - <RiMoreFill size={20} /> - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - {PLAY_TYPES.filter((type) => type.play !== playButtonBehavior).map((type) => ( - <DropdownMenu.Item - key={`playtype-${type.play}`} - onClick={() => handlePlay(type.play)} + const openDeletePlaylist = () => { + openModal({ + children: ( + <ConfirmModal + loading={deletePlaylistMutation.isLoading} + onConfirm={handleDeletePlaylist} > - {type.label} - </DropdownMenu.Item> - ))} - <DropdownMenu.Divider /> - <DropdownMenu.Item - onClick={() => { - if (!detailQuery.data || !server) return; - openUpdatePlaylistModal({ playlist: detailQuery.data, server }); - }} - > - Edit playlist - </DropdownMenu.Item> - <DropdownMenu.Item onClick={openDeletePlaylist}>Delete playlist</DropdownMenu.Item> - </DropdownMenu.Dropdown> - </DropdownMenu> - <Button - compact - uppercase - component={Link} - to={generatePath(AppRoute.PLAYLISTS_DETAIL_SONGS, { playlistId })} - variant="subtle" - > - View full playlist - </Button> - </Group> - </Group> - <Box ref={tableContainerRef}> - <VirtualTable - ref={tableRef} - autoFitColumns - autoHeight - deselectOnClickOutside - suppressCellFocus - suppressHorizontalScroll - suppressLoadingOverlay - suppressRowDrag - columnDefs={columnDefs} - getRowId={(data) => { - // It's possible that there are duplicate song ids in a playlist - return `${data.data.id}-${data.data.pageIndex}`; - }} - rowData={playlistSongData} - rowHeight={60} - rowSelection="multiple" - onCellContextMenu={handleContextMenu} - onRowDoubleClicked={handleRowDoubleClick} - /> - </Box> - <MotionGroup - p="2rem" - position="center" - onViewportEnter={handleLoadMore} - > - <Button - ref={loadMoreRef} - compact - disabled={!playlistSongsQueryInfinite.hasNextPage} - loading={playlistSongsQueryInfinite.isFetchingNextPage} - variant="subtle" - onClick={handleLoadMore} - > - {playlistSongsQueryInfinite.hasNextPage ? 'Load more' : 'End of playlist'} - </Button> - </MotionGroup> - </ContentContainer> - ); + Are you sure you want to delete this playlist? + </ConfirmModal> + ), + title: 'Delete playlist', + }); + }; + + const handlePlay = (playType?: Play) => { + handlePlayQueueAdd?.({ + byItemType: { + id: [playlistId], + type: LibraryItem.PLAYLIST, + }, + playType: playType || playButtonBehavior, + }); + }; + + const handleRowDoubleClick = (e: RowDoubleClickedEvent<QueueSong>) => { + if (!e.data) return; + + handlePlayQueueAdd?.({ + byItemType: { + id: [playlistId], + type: LibraryItem.PLAYLIST, + }, + initialSongId: e.data.id, + playType: playButtonBehavior, + }); + }; + + const loadMoreRef = useRef<HTMLButtonElement | null>(null); + + return ( + <ContentContainer> + <Group + ref={intersectRef} + p="1rem" + position="apart" + > + <Group> + <PlayButton onClick={() => handlePlay()} /> + <DropdownMenu position="bottom-start"> + <DropdownMenu.Target> + <Button + compact + variant="subtle" + > + <RiMoreFill size={20} /> + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + {PLAY_TYPES.filter((type) => type.play !== playButtonBehavior).map( + (type) => ( + <DropdownMenu.Item + key={`playtype-${type.play}`} + onClick={() => handlePlay(type.play)} + > + {type.label} + </DropdownMenu.Item> + ), + )} + <DropdownMenu.Divider /> + <DropdownMenu.Item + onClick={() => { + if (!detailQuery.data || !server) return; + openUpdatePlaylistModal({ playlist: detailQuery.data, server }); + }} + > + Edit playlist + </DropdownMenu.Item> + <DropdownMenu.Item onClick={openDeletePlaylist}> + Delete playlist + </DropdownMenu.Item> + </DropdownMenu.Dropdown> + </DropdownMenu> + <Button + compact + uppercase + component={Link} + to={generatePath(AppRoute.PLAYLISTS_DETAIL_SONGS, { playlistId })} + variant="subtle" + > + View full playlist + </Button> + </Group> + </Group> + <Box ref={tableContainerRef}> + <VirtualTable + ref={tableRef} + autoFitColumns + autoHeight + deselectOnClickOutside + suppressCellFocus + suppressHorizontalScroll + suppressLoadingOverlay + suppressRowDrag + columnDefs={columnDefs} + getRowId={(data) => { + // It's possible that there are duplicate song ids in a playlist + return `${data.data.id}-${data.data.pageIndex}`; + }} + rowData={playlistSongData} + rowHeight={60} + rowSelection="multiple" + onCellContextMenu={handleContextMenu} + onRowDoubleClicked={handleRowDoubleClick} + /> + </Box> + <MotionGroup + p="2rem" + position="center" + onViewportEnter={handleLoadMore} + > + <Button + ref={loadMoreRef} + compact + disabled={!playlistSongsQueryInfinite.hasNextPage} + loading={playlistSongsQueryInfinite.isFetchingNextPage} + variant="subtle" + onClick={handleLoadMore} + > + {playlistSongsQueryInfinite.hasNextPage ? 'Load more' : 'End of playlist'} + </Button> + </MotionGroup> + </ContentContainer> + ); }; diff --git a/src/renderer/features/playlists/components/playlist-detail-header.tsx b/src/renderer/features/playlists/components/playlist-detail-header.tsx index 863dab62..1235681c 100644 --- a/src/renderer/features/playlists/components/playlist-detail-header.tsx +++ b/src/renderer/features/playlists/components/playlist-detail-header.tsx @@ -10,69 +10,70 @@ import { LibraryItem } from '/@/renderer/api/types'; import { useCurrentServer } from '../../../store/auth.store'; interface PlaylistDetailHeaderProps { - background: string; - imagePlaceholderUrl?: string | null; - imageUrl?: string | null; + background: string; + imagePlaceholderUrl?: string | null; + imageUrl?: string | null; } export const PlaylistDetailHeader = forwardRef( - ( - { background, imageUrl, imagePlaceholderUrl }: PlaylistDetailHeaderProps, - ref: Ref<HTMLDivElement>, - ) => { - const { playlistId } = useParams() as { playlistId: string }; - const server = useCurrentServer(); - const detailQuery = usePlaylistDetail({ query: { id: playlistId }, serverId: server?.id }); + ( + { background, imageUrl, imagePlaceholderUrl }: PlaylistDetailHeaderProps, + ref: Ref<HTMLDivElement>, + ) => { + const { playlistId } = useParams() as { playlistId: string }; + const server = useCurrentServer(); + const detailQuery = usePlaylistDetail({ query: { id: playlistId }, serverId: server?.id }); - const metadataItems = [ - { - id: 'songCount', - secondary: false, - value: `${detailQuery?.data?.songCount || 0} songs`, - }, - { - id: 'duration', - secondary: true, - value: detailQuery?.data?.duration && formatDurationString(detailQuery.data.duration), - }, - ]; + const metadataItems = [ + { + id: 'songCount', + secondary: false, + value: `${detailQuery?.data?.songCount || 0} songs`, + }, + { + id: 'duration', + secondary: true, + value: + detailQuery?.data?.duration && formatDurationString(detailQuery.data.duration), + }, + ]; - const isSmartPlaylist = detailQuery?.data?.rules; + const isSmartPlaylist = detailQuery?.data?.rules; - return ( - <Stack> - <LibraryHeader - ref={ref} - background={background} - imagePlaceholderUrl={imagePlaceholderUrl} - imageUrl={imageUrl} - item={{ route: AppRoute.PLAYLISTS, type: LibraryItem.PLAYLIST }} - title={detailQuery?.data?.name || ''} - > - <Stack> - <Group spacing="sm"> - {metadataItems.map((item, index) => ( - <Fragment key={`item-${item.id}-${index}`}> - {index > 0 && <Text $noSelect>•</Text>} - <Text $secondary={item.secondary}>{item.value}</Text> - </Fragment> - ))} - {isSmartPlaylist && ( - <> - <Text $noSelect>•</Text> - <Badge - radius="sm" - size="md" - > - Smart Playlist - </Badge> - </> - )} - </Group> - <Text lineClamp={3}>{detailQuery?.data?.description}</Text> - </Stack> - </LibraryHeader> - </Stack> - ); - }, + return ( + <Stack> + <LibraryHeader + ref={ref} + background={background} + imagePlaceholderUrl={imagePlaceholderUrl} + imageUrl={imageUrl} + item={{ route: AppRoute.PLAYLISTS, type: LibraryItem.PLAYLIST }} + title={detailQuery?.data?.name || ''} + > + <Stack> + <Group spacing="sm"> + {metadataItems.map((item, index) => ( + <Fragment key={`item-${item.id}-${index}`}> + {index > 0 && <Text $noSelect>•</Text>} + <Text $secondary={item.secondary}>{item.value}</Text> + </Fragment> + ))} + {isSmartPlaylist && ( + <> + <Text $noSelect>•</Text> + <Badge + radius="sm" + size="md" + > + Smart Playlist + </Badge> + </> + )} + </Group> + <Text lineClamp={3}>{detailQuery?.data?.description}</Text> + </Stack> + </LibraryHeader> + </Stack> + ); + }, ); diff --git a/src/renderer/features/playlists/components/playlist-detail-song-list-content.tsx b/src/renderer/features/playlists/components/playlist-detail-song-list-content.tsx index 453ff0f6..c6351ce9 100644 --- a/src/renderer/features/playlists/components/playlist-detail-song-list-content.tsx +++ b/src/renderer/features/playlists/components/playlist-detail-song-list-content.tsx @@ -1,19 +1,19 @@ import { MutableRefObject, useCallback, useMemo } from 'react'; import type { - BodyScrollEvent, - ColDef, - GridReadyEvent, - IDatasource, - PaginationChangedEvent, - RowDoubleClickedEvent, + BodyScrollEvent, + ColDef, + GridReadyEvent, + IDatasource, + PaginationChangedEvent, + RowDoubleClickedEvent, } from '@ag-grid-community/core'; import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact'; import { - useCurrentServer, - usePlaylistDetailStore, - usePlaylistDetailTablePagination, - useSetPlaylistDetailTable, - useSetPlaylistDetailTablePagination, + useCurrentServer, + usePlaylistDetailStore, + usePlaylistDetailTablePagination, + useSetPlaylistDetailTable, + useSetPlaylistDetailTablePagination, } from '/@/renderer/store'; import { ListDisplayType } from '/@/renderer/types'; import { useQueryClient } from '@tanstack/react-query'; @@ -21,16 +21,16 @@ import { AnimatePresence } from 'framer-motion'; import debounce from 'lodash/debounce'; import { useHandleTableContextMenu } from '/@/renderer/features/context-menu'; import { - PLAYLIST_SONG_CONTEXT_MENU_ITEMS, - SMART_PLAYLIST_SONG_CONTEXT_MENU_ITEMS, + PLAYLIST_SONG_CONTEXT_MENU_ITEMS, + SMART_PLAYLIST_SONG_CONTEXT_MENU_ITEMS, } from '/@/renderer/features/context-menu/context-menu-items'; import { usePlayButtonBehavior } from '/@/renderer/store/settings.store'; import { - LibraryItem, - PlaylistSongListQuery, - QueueSong, - SongListSort, - SortOrder, + LibraryItem, + PlaylistSongListQuery, + QueueSong, + SongListSort, + SortOrder, } from '/@/renderer/api/types'; import { usePlaylistSongList } from '/@/renderer/features/playlists/queries/playlist-song-list-query'; import { useParams } from 'react-router'; @@ -42,230 +42,232 @@ import { VirtualGridAutoSizerContainer } from '/@/renderer/components/virtual-gr import { getColumnDefs, VirtualTable, TablePagination } from '/@/renderer/components/virtual-table'; interface PlaylistDetailContentProps { - tableRef: MutableRefObject<AgGridReactType | null>; + tableRef: MutableRefObject<AgGridReactType | null>; } export const PlaylistDetailSongListContent = ({ tableRef }: PlaylistDetailContentProps) => { - const { playlistId } = useParams() as { playlistId: string }; - const queryClient = useQueryClient(); - const server = useCurrentServer(); - const page = usePlaylistDetailStore(); - const filters: Partial<PlaylistSongListQuery> = useMemo(() => { - return { - sortBy: page?.table.id[playlistId]?.filter?.sortBy || SongListSort.ID, - sortOrder: page?.table.id[playlistId]?.filter?.sortOrder || SortOrder.ASC, + const { playlistId } = useParams() as { playlistId: string }; + const queryClient = useQueryClient(); + const server = useCurrentServer(); + const page = usePlaylistDetailStore(); + const filters: Partial<PlaylistSongListQuery> = useMemo(() => { + return { + sortBy: page?.table.id[playlistId]?.filter?.sortBy || SongListSort.ID, + sortOrder: page?.table.id[playlistId]?.filter?.sortOrder || SortOrder.ASC, + }; + }, [page?.table.id, playlistId]); + + const detailQuery = usePlaylistDetail({ query: { id: playlistId }, serverId: server?.id }); + + const p = usePlaylistDetailTablePagination(playlistId); + const pagination = { + currentPage: p?.currentPage || 0, + itemsPerPage: p?.itemsPerPage || 100, + scrollOffset: p?.scrollOffset || 0, + totalItems: p?.totalItems || 1, + totalPages: p?.totalPages || 1, }; - }, [page?.table.id, playlistId]); - const detailQuery = usePlaylistDetail({ query: { id: playlistId }, serverId: server?.id }); + const setPagination = useSetPlaylistDetailTablePagination(); + const setTable = useSetPlaylistDetailTable(); + const handlePlayQueueAdd = usePlayQueueAdd(); + const playButtonBehavior = usePlayButtonBehavior(); - const p = usePlaylistDetailTablePagination(playlistId); - const pagination = { - currentPage: p?.currentPage || 0, - itemsPerPage: p?.itemsPerPage || 100, - scrollOffset: p?.scrollOffset || 0, - totalItems: p?.totalItems || 1, - totalPages: p?.totalPages || 1, - }; + const isPaginationEnabled = page.display === ListDisplayType.TABLE_PAGINATED; - const setPagination = useSetPlaylistDetailTablePagination(); - const setTable = useSetPlaylistDetailTable(); - const handlePlayQueueAdd = usePlayQueueAdd(); - const playButtonBehavior = usePlayButtonBehavior(); - - const isPaginationEnabled = page.display === ListDisplayType.TABLE_PAGINATED; - - const checkPlaylistList = usePlaylistSongList({ - query: { - id: playlistId, - limit: 1, - startIndex: 0, - }, - serverId: server?.id, - }); - - const columnDefs: ColDef[] = useMemo( - () => getColumnDefs(page.table.columns), - [page.table.columns], - ); - - const onGridReady = useCallback( - (params: GridReadyEvent) => { - const dataSource: IDatasource = { - getRows: async (params) => { - const limit = params.endRow - params.startRow; - const startIndex = params.startRow; - - const queryKey = queryKeys.playlists.songList(server?.id || '', playlistId, { + const checkPlaylistList = usePlaylistSongList({ + query: { id: playlistId, - limit, - startIndex, - ...filters, - }); - - if (!server) return; - - const songsRes = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.getPlaylistSongList({ - apiClientProps: { - server, - signal, - }, - query: { - id: playlistId, - limit, - startIndex, - ...filters, - }, - }), - { cacheTime: 1000 * 60 * 1 }, - ); - - params.successCallback(songsRes?.items || [], songsRes?.totalRecordCount || 0); + limit: 1, + startIndex: 0, }, - rowCount: undefined, - }; - params.api.setDatasource(dataSource); - params.api?.ensureIndexVisible(pagination.scrollOffset, 'top'); - }, - [filters, pagination.scrollOffset, playlistId, queryClient, server], - ); - - const handleGridSizeChange = () => { - if (page.table.autoFit) { - tableRef?.current?.api.sizeColumnsToFit(); - } - }; - - const onPaginationChanged = useCallback( - (event: PaginationChangedEvent) => { - if (!isPaginationEnabled || !event.api) return; - - try { - // Scroll to top of page on pagination change - const currentPageStartIndex = pagination.currentPage * pagination.itemsPerPage; - event.api?.ensureIndexVisible(currentPageStartIndex, 'top'); - } catch (err) { - console.log(err); - } - - setPagination(playlistId, { - itemsPerPage: event.api.paginationGetPageSize(), - totalItems: event.api.paginationGetRowCount(), - totalPages: event.api.paginationGetTotalPages() + 1, - }); - }, - [ - isPaginationEnabled, - pagination.currentPage, - pagination.itemsPerPage, - playlistId, - setPagination, - ], - ); - - const handleColumnChange = useCallback(() => { - const { columnApi } = tableRef?.current || {}; - const columnsOrder = columnApi?.getAllGridColumns(); - - if (!columnsOrder) return; - - const columnsInSettings = page.table.columns; - const updatedColumns = []; - for (const column of columnsOrder) { - const columnInSettings = columnsInSettings.find((c) => c.column === column.getColDef().colId); - - if (columnInSettings) { - updatedColumns.push({ - ...columnInSettings, - ...(!page.table.autoFit && { - width: column.getActualWidth(), - }), - }); - } - } - - setTable({ columns: updatedColumns }); - }, [page.table.autoFit, page.table.columns, setTable, tableRef]); - - const debouncedColumnChange = debounce(handleColumnChange, 200); - - const handleScroll = (e: BodyScrollEvent) => { - const scrollOffset = Number((e.top / page.table.rowHeight).toFixed(0)); - setPagination(playlistId, { scrollOffset }); - }; - - const contextMenuItems = useMemo(() => { - if (detailQuery?.data?.rules) { - return SMART_PLAYLIST_SONG_CONTEXT_MENU_ITEMS; - } - - return PLAYLIST_SONG_CONTEXT_MENU_ITEMS; - }, [detailQuery?.data?.rules]); - - const handleContextMenu = useHandleTableContextMenu(LibraryItem.SONG, contextMenuItems, { - playlistId, - tableRef, - }); - - const handleRowDoubleClick = (e: RowDoubleClickedEvent<QueueSong>) => { - if (!e.data) return; - handlePlayQueueAdd?.({ - byItemType: { - id: [playlistId], - type: LibraryItem.PLAYLIST, - }, - initialSongId: e.data.id, - playType: playButtonBehavior, + serverId: server?.id, }); - }; - return ( - <> - <VirtualGridAutoSizerContainer> - <VirtualTable - // https://github.com/ag-grid/ag-grid/issues/5284 - // Key is used to force remount of table when display, rowHeight, or server changes - key={`table-${page.display}-${page.table.rowHeight}-${server?.id}`} - ref={tableRef} - alwaysShowHorizontalScroll - autoFitColumns={page.table.autoFit} - columnDefs={columnDefs} - getRowId={(data) => data.data.uniqueId} - infiniteInitialRowCount={checkPlaylistList.data?.totalRecordCount || 100} - pagination={isPaginationEnabled} - paginationAutoPageSize={isPaginationEnabled} - paginationPageSize={pagination.itemsPerPage || 100} - rowHeight={page.table.rowHeight || 40} - rowModelType="infinite" - onBodyScrollEnd={handleScroll} - onCellContextMenu={handleContextMenu} - onColumnMoved={handleColumnChange} - onColumnResized={debouncedColumnChange} - onGridReady={onGridReady} - onGridSizeChanged={handleGridSizeChange} - onPaginationChanged={onPaginationChanged} - onRowDoubleClicked={handleRowDoubleClick} - /> - </VirtualGridAutoSizerContainer> - {isPaginationEnabled && ( - <AnimatePresence - presenceAffectsLayout - initial={false} - mode="wait" - > - {page.display === ListDisplayType.TABLE_PAGINATED && ( - <TablePagination - pageKey={playlistId} - pagination={pagination} - setIdPagination={setPagination} - tableRef={tableRef} - /> - )} - </AnimatePresence> - )} - </> - ); + const columnDefs: ColDef[] = useMemo( + () => getColumnDefs(page.table.columns), + [page.table.columns], + ); + + const onGridReady = useCallback( + (params: GridReadyEvent) => { + const dataSource: IDatasource = { + getRows: async (params) => { + const limit = params.endRow - params.startRow; + const startIndex = params.startRow; + + const queryKey = queryKeys.playlists.songList(server?.id || '', playlistId, { + id: playlistId, + limit, + startIndex, + ...filters, + }); + + if (!server) return; + + const songsRes = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.getPlaylistSongList({ + apiClientProps: { + server, + signal, + }, + query: { + id: playlistId, + limit, + startIndex, + ...filters, + }, + }), + { cacheTime: 1000 * 60 * 1 }, + ); + + params.successCallback(songsRes?.items || [], songsRes?.totalRecordCount || 0); + }, + rowCount: undefined, + }; + params.api.setDatasource(dataSource); + params.api?.ensureIndexVisible(pagination.scrollOffset, 'top'); + }, + [filters, pagination.scrollOffset, playlistId, queryClient, server], + ); + + const handleGridSizeChange = () => { + if (page.table.autoFit) { + tableRef?.current?.api.sizeColumnsToFit(); + } + }; + + const onPaginationChanged = useCallback( + (event: PaginationChangedEvent) => { + if (!isPaginationEnabled || !event.api) return; + + try { + // Scroll to top of page on pagination change + const currentPageStartIndex = pagination.currentPage * pagination.itemsPerPage; + event.api?.ensureIndexVisible(currentPageStartIndex, 'top'); + } catch (err) { + console.log(err); + } + + setPagination(playlistId, { + itemsPerPage: event.api.paginationGetPageSize(), + totalItems: event.api.paginationGetRowCount(), + totalPages: event.api.paginationGetTotalPages() + 1, + }); + }, + [ + isPaginationEnabled, + pagination.currentPage, + pagination.itemsPerPage, + playlistId, + setPagination, + ], + ); + + const handleColumnChange = useCallback(() => { + const { columnApi } = tableRef?.current || {}; + const columnsOrder = columnApi?.getAllGridColumns(); + + if (!columnsOrder) return; + + const columnsInSettings = page.table.columns; + const updatedColumns = []; + for (const column of columnsOrder) { + const columnInSettings = columnsInSettings.find( + (c) => c.column === column.getColDef().colId, + ); + + if (columnInSettings) { + updatedColumns.push({ + ...columnInSettings, + ...(!page.table.autoFit && { + width: column.getActualWidth(), + }), + }); + } + } + + setTable({ columns: updatedColumns }); + }, [page.table.autoFit, page.table.columns, setTable, tableRef]); + + const debouncedColumnChange = debounce(handleColumnChange, 200); + + const handleScroll = (e: BodyScrollEvent) => { + const scrollOffset = Number((e.top / page.table.rowHeight).toFixed(0)); + setPagination(playlistId, { scrollOffset }); + }; + + const contextMenuItems = useMemo(() => { + if (detailQuery?.data?.rules) { + return SMART_PLAYLIST_SONG_CONTEXT_MENU_ITEMS; + } + + return PLAYLIST_SONG_CONTEXT_MENU_ITEMS; + }, [detailQuery?.data?.rules]); + + const handleContextMenu = useHandleTableContextMenu(LibraryItem.SONG, contextMenuItems, { + playlistId, + tableRef, + }); + + const handleRowDoubleClick = (e: RowDoubleClickedEvent<QueueSong>) => { + if (!e.data) return; + handlePlayQueueAdd?.({ + byItemType: { + id: [playlistId], + type: LibraryItem.PLAYLIST, + }, + initialSongId: e.data.id, + playType: playButtonBehavior, + }); + }; + + return ( + <> + <VirtualGridAutoSizerContainer> + <VirtualTable + // https://github.com/ag-grid/ag-grid/issues/5284 + // Key is used to force remount of table when display, rowHeight, or server changes + key={`table-${page.display}-${page.table.rowHeight}-${server?.id}`} + ref={tableRef} + alwaysShowHorizontalScroll + autoFitColumns={page.table.autoFit} + columnDefs={columnDefs} + getRowId={(data) => data.data.uniqueId} + infiniteInitialRowCount={checkPlaylistList.data?.totalRecordCount || 100} + pagination={isPaginationEnabled} + paginationAutoPageSize={isPaginationEnabled} + paginationPageSize={pagination.itemsPerPage || 100} + rowHeight={page.table.rowHeight || 40} + rowModelType="infinite" + onBodyScrollEnd={handleScroll} + onCellContextMenu={handleContextMenu} + onColumnMoved={handleColumnChange} + onColumnResized={debouncedColumnChange} + onGridReady={onGridReady} + onGridSizeChanged={handleGridSizeChange} + onPaginationChanged={onPaginationChanged} + onRowDoubleClicked={handleRowDoubleClick} + /> + </VirtualGridAutoSizerContainer> + {isPaginationEnabled && ( + <AnimatePresence + presenceAffectsLayout + initial={false} + mode="wait" + > + {page.display === ListDisplayType.TABLE_PAGINATED && ( + <TablePagination + pageKey={playlistId} + pagination={pagination} + setIdPagination={setPagination} + tableRef={tableRef} + /> + )} + </AnimatePresence> + )} + </> + ); }; diff --git a/src/renderer/features/playlists/components/playlist-detail-song-list-header-filters.tsx b/src/renderer/features/playlists/components/playlist-detail-song-list-header-filters.tsx index 68796259..5bf0bccb 100644 --- a/src/renderer/features/playlists/components/playlist-detail-song-list-header-filters.tsx +++ b/src/renderer/features/playlists/components/playlist-detail-song-list-header-filters.tsx @@ -5,40 +5,40 @@ import { Flex, Group, Stack } from '@mantine/core'; import { closeAllModals, openModal } from '@mantine/modals'; import { useQueryClient } from '@tanstack/react-query'; import { - RiSortAsc, - RiSortDesc, - RiMoreFill, - RiSettings3Fill, - RiPlayFill, - RiAddCircleFill, - RiAddBoxFill, - RiEditFill, - RiDeleteBinFill, - RiRefreshLine, + RiSortAsc, + RiSortDesc, + RiMoreFill, + RiSettings3Fill, + RiPlayFill, + RiAddCircleFill, + RiAddBoxFill, + RiEditFill, + RiDeleteBinFill, + RiRefreshLine, } from 'react-icons/ri'; import { api } from '/@/renderer/api'; import { queryKeys } from '/@/renderer/api/query-keys'; import { LibraryItem, PlaylistSongListQuery, SongListSort, SortOrder } from '/@/renderer/api/types'; import { - DropdownMenu, - Button, - Slider, - MultiSelect, - Switch, - Text, - ConfirmModal, - toast, + DropdownMenu, + Button, + Slider, + MultiSelect, + Switch, + Text, + ConfirmModal, + toast, } from '/@/renderer/components'; import { usePlayQueueAdd } from '/@/renderer/features/player'; import { useContainerQuery } from '/@/renderer/hooks'; import { - useCurrentServer, - SongListFilter, - usePlaylistDetailStore, - useSetPlaylistDetailFilters, - useSetPlaylistDetailTable, - useSetPlaylistStore, - useSetPlaylistTablePagination, + useCurrentServer, + SongListFilter, + usePlaylistDetailStore, + useSetPlaylistDetailFilters, + useSetPlaylistDetailTable, + useSetPlaylistStore, + useSetPlaylistTablePagination, } from '/@/renderer/store'; import { ListDisplayType, ServerType, Play, TableColumn } from '/@/renderer/types'; import { usePlaylistDetail } from '/@/renderer/features/playlists/queries/playlist-detail-query'; @@ -48,431 +48,446 @@ import { openUpdatePlaylistModal } from '/@/renderer/features/playlists/componen import { useDeletePlaylist } from '/@/renderer/features/playlists/mutations/delete-playlist-mutation'; const FILTERS = { - jellyfin: [ - { defaultOrder: SortOrder.ASC, name: 'Album', value: SongListSort.ALBUM }, - { defaultOrder: SortOrder.ASC, name: 'Album Artist', value: SongListSort.ALBUM_ARTIST }, - { defaultOrder: SortOrder.ASC, name: 'Artist', value: SongListSort.ARTIST }, - { defaultOrder: SortOrder.ASC, name: 'Duration', value: SongListSort.DURATION }, - { defaultOrder: SortOrder.ASC, name: 'Most Played', value: SongListSort.PLAY_COUNT }, - { defaultOrder: SortOrder.ASC, name: 'Name', value: SongListSort.NAME }, - { defaultOrder: SortOrder.ASC, name: 'Random', value: SongListSort.RANDOM }, - { defaultOrder: SortOrder.ASC, name: 'Recently Added', value: SongListSort.RECENTLY_ADDED }, - { defaultOrder: SortOrder.ASC, name: 'Recently Played', value: SongListSort.RECENTLY_PLAYED }, - { defaultOrder: SortOrder.ASC, name: 'Release Date', value: SongListSort.RELEASE_DATE }, - ], - navidrome: [ - { defaultOrder: SortOrder.ASC, name: 'Album', value: SongListSort.ALBUM }, - { defaultOrder: SortOrder.ASC, name: 'Album Artist', value: SongListSort.ALBUM_ARTIST }, - { defaultOrder: SortOrder.ASC, name: 'Artist', value: SongListSort.ARTIST }, - { defaultOrder: SortOrder.DESC, name: 'BPM', value: SongListSort.BPM }, - { defaultOrder: SortOrder.ASC, name: 'Channels', value: SongListSort.CHANNELS }, - { defaultOrder: SortOrder.ASC, name: 'Comment', value: SongListSort.COMMENT }, - { defaultOrder: SortOrder.DESC, name: 'Duration', value: SongListSort.DURATION }, - { defaultOrder: SortOrder.DESC, name: 'Favorited', value: SongListSort.FAVORITED }, - { defaultOrder: SortOrder.ASC, name: 'Genre', value: SongListSort.GENRE }, - { defaultOrder: SortOrder.ASC, name: 'Id', value: SongListSort.ID }, - { defaultOrder: SortOrder.ASC, name: 'Name', value: SongListSort.NAME }, - { defaultOrder: SortOrder.DESC, name: 'Play Count', value: SongListSort.PLAY_COUNT }, - { defaultOrder: SortOrder.DESC, name: 'Rating', value: SongListSort.RATING }, - { defaultOrder: SortOrder.DESC, name: 'Recently Added', value: SongListSort.RECENTLY_ADDED }, - { defaultOrder: SortOrder.DESC, name: 'Recently Played', value: SongListSort.RECENTLY_PLAYED }, - { defaultOrder: SortOrder.DESC, name: 'Year', value: SongListSort.YEAR }, - ], + jellyfin: [ + { defaultOrder: SortOrder.ASC, name: 'Album', value: SongListSort.ALBUM }, + { defaultOrder: SortOrder.ASC, name: 'Album Artist', value: SongListSort.ALBUM_ARTIST }, + { defaultOrder: SortOrder.ASC, name: 'Artist', value: SongListSort.ARTIST }, + { defaultOrder: SortOrder.ASC, name: 'Duration', value: SongListSort.DURATION }, + { defaultOrder: SortOrder.ASC, name: 'Most Played', value: SongListSort.PLAY_COUNT }, + { defaultOrder: SortOrder.ASC, name: 'Name', value: SongListSort.NAME }, + { defaultOrder: SortOrder.ASC, name: 'Random', value: SongListSort.RANDOM }, + { defaultOrder: SortOrder.ASC, name: 'Recently Added', value: SongListSort.RECENTLY_ADDED }, + { + defaultOrder: SortOrder.ASC, + name: 'Recently Played', + value: SongListSort.RECENTLY_PLAYED, + }, + { defaultOrder: SortOrder.ASC, name: 'Release Date', value: SongListSort.RELEASE_DATE }, + ], + navidrome: [ + { defaultOrder: SortOrder.ASC, name: 'Album', value: SongListSort.ALBUM }, + { defaultOrder: SortOrder.ASC, name: 'Album Artist', value: SongListSort.ALBUM_ARTIST }, + { defaultOrder: SortOrder.ASC, name: 'Artist', value: SongListSort.ARTIST }, + { defaultOrder: SortOrder.DESC, name: 'BPM', value: SongListSort.BPM }, + { defaultOrder: SortOrder.ASC, name: 'Channels', value: SongListSort.CHANNELS }, + { defaultOrder: SortOrder.ASC, name: 'Comment', value: SongListSort.COMMENT }, + { defaultOrder: SortOrder.DESC, name: 'Duration', value: SongListSort.DURATION }, + { defaultOrder: SortOrder.DESC, name: 'Favorited', value: SongListSort.FAVORITED }, + { defaultOrder: SortOrder.ASC, name: 'Genre', value: SongListSort.GENRE }, + { defaultOrder: SortOrder.ASC, name: 'Id', value: SongListSort.ID }, + { defaultOrder: SortOrder.ASC, name: 'Name', value: SongListSort.NAME }, + { defaultOrder: SortOrder.DESC, name: 'Play Count', value: SongListSort.PLAY_COUNT }, + { defaultOrder: SortOrder.DESC, name: 'Rating', value: SongListSort.RATING }, + { + defaultOrder: SortOrder.DESC, + name: 'Recently Added', + value: SongListSort.RECENTLY_ADDED, + }, + { + defaultOrder: SortOrder.DESC, + name: 'Recently Played', + value: SongListSort.RECENTLY_PLAYED, + }, + { defaultOrder: SortOrder.DESC, name: 'Year', value: SongListSort.YEAR }, + ], }; const ORDER = [ - { name: 'Ascending', value: SortOrder.ASC }, - { name: 'Descending', value: SortOrder.DESC }, + { name: 'Ascending', value: SortOrder.ASC }, + { name: 'Descending', value: SortOrder.DESC }, ]; interface PlaylistDetailSongListHeaderFiltersProps { - handleToggleShowQueryBuilder: () => void; - tableRef: MutableRefObject<AgGridReactType | null>; + handleToggleShowQueryBuilder: () => void; + tableRef: MutableRefObject<AgGridReactType | null>; } export const PlaylistDetailSongListHeaderFilters = ({ - tableRef, - handleToggleShowQueryBuilder, + tableRef, + handleToggleShowQueryBuilder, }: PlaylistDetailSongListHeaderFiltersProps) => { - const { playlistId } = useParams() as { playlistId: string }; - const queryClient = useQueryClient(); - const server = useCurrentServer(); - const setPage = useSetPlaylistStore(); - const setFilter = useSetPlaylistDetailFilters(); - const page = usePlaylistDetailStore(); - const filters: Partial<PlaylistSongListQuery> = { - sortBy: page?.table.id[playlistId]?.filter?.sortBy || SongListSort.ID, - sortOrder: page?.table.id[playlistId]?.filter?.sortOrder || SortOrder.ASC, - }; + const { playlistId } = useParams() as { playlistId: string }; + const queryClient = useQueryClient(); + const server = useCurrentServer(); + const setPage = useSetPlaylistStore(); + const setFilter = useSetPlaylistDetailFilters(); + const page = usePlaylistDetailStore(); + const filters: Partial<PlaylistSongListQuery> = { + sortBy: page?.table.id[playlistId]?.filter?.sortBy || SongListSort.ID, + sortOrder: page?.table.id[playlistId]?.filter?.sortOrder || SortOrder.ASC, + }; - const detailQuery = usePlaylistDetail({ query: { id: playlistId }, serverId: server?.id }); - const isSmartPlaylist = detailQuery.data?.rules; + const detailQuery = usePlaylistDetail({ query: { id: playlistId }, serverId: server?.id }); + const isSmartPlaylist = detailQuery.data?.rules; - const handlePlayQueueAdd = usePlayQueueAdd(); + const handlePlayQueueAdd = usePlayQueueAdd(); - const cq = useContainerQuery(); + const cq = useContainerQuery(); - const setPagination = useSetPlaylistTablePagination(); - const setTable = useSetPlaylistDetailTable(); + const setPagination = useSetPlaylistTablePagination(); + const setTable = useSetPlaylistDetailTable(); - const sortByLabel = - (server?.type && - FILTERS[server.type as keyof typeof FILTERS].find((f) => f.value === filters.sortBy)?.name) || - 'Unknown'; + const sortByLabel = + (server?.type && + FILTERS[server.type as keyof typeof FILTERS].find((f) => f.value === filters.sortBy) + ?.name) || + 'Unknown'; - const sortOrderLabel = ORDER.find((o) => o.value === filters.sortOrder)?.name || 'Unknown'; + const sortOrderLabel = ORDER.find((o) => o.value === filters.sortOrder)?.name || 'Unknown'; - const handleItemSize = (e: number) => { - setTable({ rowHeight: e }); - }; + const handleItemSize = (e: number) => { + setTable({ rowHeight: e }); + }; - const handleFilterChange = useCallback( - async (filters: SongListFilter) => { - const dataSource: IDatasource = { - getRows: async (params) => { - const limit = params.endRow - params.startRow; - const startIndex = params.startRow; + const handleFilterChange = useCallback( + async (filters: SongListFilter) => { + const dataSource: IDatasource = { + getRows: async (params) => { + const limit = params.endRow - params.startRow; + const startIndex = params.startRow; - const queryKey = queryKeys.playlists.songList(server?.id || '', playlistId, { - id: playlistId, - limit, - startIndex, - ...filters, - }); + const queryKey = queryKeys.playlists.songList(server?.id || '', playlistId, { + id: playlistId, + limit, + startIndex, + ...filters, + }); - const songsRes = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.getPlaylistSongList({ - apiClientProps: { - server, - signal, + const songsRes = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.getPlaylistSongList({ + apiClientProps: { + server, + signal, + }, + query: { + id: playlistId, + limit, + startIndex, + ...filters, + }, + }), + { cacheTime: 1000 * 60 * 1 }, + ); + + params.successCallback(songsRes?.items || [], songsRes?.totalRecordCount || 0); }, - query: { - id: playlistId, - limit, - startIndex, - ...filters, - }, - }), - { cacheTime: 1000 * 60 * 1 }, - ); + rowCount: undefined, + }; + tableRef.current?.api.setDatasource(dataSource); + tableRef.current?.api.purgeInfiniteCache(); + tableRef.current?.api.ensureIndexVisible(0, 'top'); - params.successCallback(songsRes?.items || [], songsRes?.totalRecordCount || 0); + if (page.display === ListDisplayType.TABLE_PAGINATED) { + setPagination({ data: { currentPage: 0 } }); + } }, - rowCount: undefined, - }; - tableRef.current?.api.setDatasource(dataSource); - tableRef.current?.api.purgeInfiniteCache(); - tableRef.current?.api.ensureIndexVisible(0, 'top'); - - if (page.display === ListDisplayType.TABLE_PAGINATED) { - setPagination({ data: { currentPage: 0 } }); - } - }, - [tableRef, page.display, server, playlistId, queryClient, setPagination], - ); - - const handleRefresh = () => { - queryClient.invalidateQueries(queryKeys.albums.list(server?.id || '')); - handleFilterChange({ ...page?.table.id[playlistId].filter, ...filters }); - }; - - const handleSetSortBy = useCallback( - (e: MouseEvent<HTMLButtonElement>) => { - if (!e.currentTarget?.value || !server?.type) return; - - const sortOrder = FILTERS[server.type as keyof typeof FILTERS].find( - (f) => f.value === e.currentTarget.value, - )?.defaultOrder; - - const updatedFilters = setFilter(playlistId, { - sortBy: e.currentTarget.value as SongListSort, - sortOrder: sortOrder || SortOrder.ASC, - }); - - handleFilterChange(updatedFilters); - }, - [handleFilterChange, playlistId, server?.type, setFilter], - ); - - const handleToggleSortOrder = useCallback(() => { - const newSortOrder = filters.sortOrder === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC; - const updatedFilters = setFilter(playlistId, { sortOrder: newSortOrder }); - handleFilterChange(updatedFilters); - }, [filters.sortOrder, handleFilterChange, playlistId, setFilter]); - - const handleSetViewType = useCallback( - (e: MouseEvent<HTMLButtonElement>) => { - if (!e.currentTarget?.value) return; - setPage({ detail: { ...page, display: e.currentTarget.value as ListDisplayType } }); - }, - [page, setPage], - ); - - const handleTableColumns = (values: TableColumn[]) => { - const existingColumns = page.table.columns; - - if (values.length === 0) { - return setTable({ - columns: [], - }); - } - - // If adding a column - if (values.length > existingColumns.length) { - const newColumn = { column: values[values.length - 1], width: 100 }; - - setTable({ columns: [...existingColumns, newColumn] }); - } else { - // If removing a column - const removed = existingColumns.filter((column) => !values.includes(column.column)); - const newColumns = existingColumns.filter((column) => !removed.includes(column)); - - setTable({ columns: newColumns }); - } - - return tableRef.current?.api.sizeColumnsToFit(); - }; - - const handleAutoFitColumns = (e: ChangeEvent<HTMLInputElement>) => { - setTable({ autoFit: e.currentTarget.checked }); - - if (e.currentTarget.checked) { - tableRef.current?.api.sizeColumnsToFit(); - } - }; - - const handlePlay = async (playType: Play) => { - handlePlayQueueAdd?.({ - byItemType: { id: [playlistId], type: LibraryItem.PLAYLIST }, - playType, - }); - }; - - const deletePlaylistMutation = useDeletePlaylist({}); - - const handleDeletePlaylist = useCallback(() => { - if (!detailQuery.data) return; - deletePlaylistMutation?.mutate( - { query: { id: detailQuery.data.id }, serverId: detailQuery.data.id }, - { - onError: (err) => { - toast.error({ - message: err.message, - title: 'Error deleting playlist', - }); - }, - onSuccess: () => { - toast.success({ - message: `Playlist has been deleted`, - }); - }, - }, + [tableRef, page.display, server, playlistId, queryClient, setPagination], ); - closeAllModals(); - }, [deletePlaylistMutation, detailQuery.data]); - const openDeletePlaylistModal = () => { - openModal({ - children: ( - <ConfirmModal onConfirm={handleDeletePlaylist}> - <Text>Are you sure you want to delete this playlist?</Text> - </ConfirmModal> - ), - title: 'Delete playlist(s)', - }); - }; + const handleRefresh = () => { + queryClient.invalidateQueries(queryKeys.albums.list(server?.id || '')); + handleFilterChange({ ...page?.table.id[playlistId].filter, ...filters }); + }; - return ( - <Flex justify="space-between"> - <Group - ref={cq.ref} - spacing="sm" - w="100%" - > - <DropdownMenu position="bottom-start"> - <DropdownMenu.Target> - <Button - compact - fw="600" - size="md" - variant="subtle" + const handleSetSortBy = useCallback( + (e: MouseEvent<HTMLButtonElement>) => { + if (!e.currentTarget?.value || !server?.type) return; + + const sortOrder = FILTERS[server.type as keyof typeof FILTERS].find( + (f) => f.value === e.currentTarget.value, + )?.defaultOrder; + + const updatedFilters = setFilter(playlistId, { + sortBy: e.currentTarget.value as SongListSort, + sortOrder: sortOrder || SortOrder.ASC, + }); + + handleFilterChange(updatedFilters); + }, + [handleFilterChange, playlistId, server?.type, setFilter], + ); + + const handleToggleSortOrder = useCallback(() => { + const newSortOrder = filters.sortOrder === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC; + const updatedFilters = setFilter(playlistId, { sortOrder: newSortOrder }); + handleFilterChange(updatedFilters); + }, [filters.sortOrder, handleFilterChange, playlistId, setFilter]); + + const handleSetViewType = useCallback( + (e: MouseEvent<HTMLButtonElement>) => { + if (!e.currentTarget?.value) return; + setPage({ detail: { ...page, display: e.currentTarget.value as ListDisplayType } }); + }, + [page, setPage], + ); + + const handleTableColumns = (values: TableColumn[]) => { + const existingColumns = page.table.columns; + + if (values.length === 0) { + return setTable({ + columns: [], + }); + } + + // If adding a column + if (values.length > existingColumns.length) { + const newColumn = { column: values[values.length - 1], width: 100 }; + + setTable({ columns: [...existingColumns, newColumn] }); + } else { + // If removing a column + const removed = existingColumns.filter((column) => !values.includes(column.column)); + const newColumns = existingColumns.filter((column) => !removed.includes(column)); + + setTable({ columns: newColumns }); + } + + return tableRef.current?.api.sizeColumnsToFit(); + }; + + const handleAutoFitColumns = (e: ChangeEvent<HTMLInputElement>) => { + setTable({ autoFit: e.currentTarget.checked }); + + if (e.currentTarget.checked) { + tableRef.current?.api.sizeColumnsToFit(); + } + }; + + const handlePlay = async (playType: Play) => { + handlePlayQueueAdd?.({ + byItemType: { id: [playlistId], type: LibraryItem.PLAYLIST }, + playType, + }); + }; + + const deletePlaylistMutation = useDeletePlaylist({}); + + const handleDeletePlaylist = useCallback(() => { + if (!detailQuery.data) return; + deletePlaylistMutation?.mutate( + { query: { id: detailQuery.data.id }, serverId: detailQuery.data.id }, + { + onError: (err) => { + toast.error({ + message: err.message, + title: 'Error deleting playlist', + }); + }, + onSuccess: () => { + toast.success({ + message: `Playlist has been deleted`, + }); + }, + }, + ); + closeAllModals(); + }, [deletePlaylistMutation, detailQuery.data]); + + const openDeletePlaylistModal = () => { + openModal({ + children: ( + <ConfirmModal onConfirm={handleDeletePlaylist}> + <Text>Are you sure you want to delete this playlist?</Text> + </ConfirmModal> + ), + title: 'Delete playlist(s)', + }); + }; + + return ( + <Flex justify="space-between"> + <Group + ref={cq.ref} + spacing="sm" + w="100%" > - {sortByLabel} - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - {FILTERS[server?.type as keyof typeof FILTERS].map((filter) => ( - <DropdownMenu.Item - key={`filter-${filter.name}`} - $isActive={filter.value === filters.sortBy} - value={filter.value} - onClick={handleSetSortBy} - > - {filter.name} - </DropdownMenu.Item> - ))} - </DropdownMenu.Dropdown> - </DropdownMenu> - <Button - compact - fw="600" - size="md" - variant="subtle" - onClick={handleToggleSortOrder} - > - {cq.isSm ? ( - sortOrderLabel - ) : ( - <> - {filters.sortOrder === SortOrder.ASC ? ( - <RiSortAsc size="1.3rem" /> - ) : ( - <RiSortDesc size="1.3rem" /> - )} - </> - )} - </Button> - <DropdownMenu position="bottom-start"> - <DropdownMenu.Target> - <Button - compact - fw="600" - size="md" - variant="subtle" - > - <RiMoreFill size="1.3rem" /> - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - <DropdownMenu.Item - icon={<RiPlayFill />} - onClick={() => handlePlay(Play.NOW)} - > - Play - </DropdownMenu.Item> - <DropdownMenu.Item - icon={<RiAddBoxFill />} - onClick={() => handlePlay(Play.LAST)} - > - Add to queue - </DropdownMenu.Item> - <DropdownMenu.Item - icon={<RiAddCircleFill />} - onClick={() => handlePlay(Play.NEXT)} - > - Add to queue next - </DropdownMenu.Item> - <DropdownMenu.Divider /> - <DropdownMenu.Item - icon={<RiEditFill />} - onClick={() => - openUpdatePlaylistModal({ - playlist: detailQuery.data!, - server: server!, - }) - } - > - Edit playlist - </DropdownMenu.Item> - <DropdownMenu.Item - disabled - icon={<RiDeleteBinFill />} - onClick={openDeletePlaylistModal} - > - Delete playlist - </DropdownMenu.Item> - <DropdownMenu.Divider /> - <DropdownMenu.Item - icon={<RiRefreshLine />} - onClick={handleRefresh} - > - Refresh - </DropdownMenu.Item> - {server?.type === ServerType.NAVIDROME && !isSmartPlaylist && ( - <> - <DropdownMenu.Divider /> - <DropdownMenu.Item - $danger - onClick={handleToggleShowQueryBuilder} + <DropdownMenu position="bottom-start"> + <DropdownMenu.Target> + <Button + compact + fw="600" + size="md" + variant="subtle" + > + {sortByLabel} + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + {FILTERS[server?.type as keyof typeof FILTERS].map((filter) => ( + <DropdownMenu.Item + key={`filter-${filter.name}`} + $isActive={filter.value === filters.sortBy} + value={filter.value} + onClick={handleSetSortBy} + > + {filter.name} + </DropdownMenu.Item> + ))} + </DropdownMenu.Dropdown> + </DropdownMenu> + <Button + compact + fw="600" + size="md" + variant="subtle" + onClick={handleToggleSortOrder} > - Toggle smart playlist editor - </DropdownMenu.Item> - </> - )} - </DropdownMenu.Dropdown> - </DropdownMenu> - </Group> - <Group> - <DropdownMenu position="bottom-end"> - <DropdownMenu.Target> - <Button - compact - size="md" - variant="subtle" - > - <RiSettings3Fill size="1.3rem" /> - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - <DropdownMenu.Label>Display type</DropdownMenu.Label> - <DropdownMenu.Item - $isActive={page.display === ListDisplayType.TABLE} - value={ListDisplayType.TABLE} - onClick={handleSetViewType} - > - Table - </DropdownMenu.Item> - <DropdownMenu.Item - $isActive={page.display === ListDisplayType.TABLE_PAGINATED} - value={ListDisplayType.TABLE_PAGINATED} - onClick={handleSetViewType} - > - Table (paginated) - </DropdownMenu.Item> - <DropdownMenu.Divider /> - <DropdownMenu.Label>Item size</DropdownMenu.Label> - <DropdownMenu.Item closeMenuOnClick={false}> - <Slider - defaultValue={page.table.rowHeight} - label={null} - max={100} - min={25} - onChangeEnd={handleItemSize} - /> - </DropdownMenu.Item> - {(page.display === ListDisplayType.TABLE || - page.display === ListDisplayType.TABLE_PAGINATED) && ( - <> - <DropdownMenu.Label>Table Columns</DropdownMenu.Label> - <DropdownMenu.Item - closeMenuOnClick={false} - component="div" - sx={{ cursor: 'default' }} - > - <Stack> - <MultiSelect - clearable - data={SONG_TABLE_COLUMNS} - defaultValue={page.table?.columns.map((column) => column.column)} - width={300} - onChange={handleTableColumns} - /> - <Group position="apart"> - <Text>Auto Fit Columns</Text> - <Switch - defaultChecked={page.table.autoFit} - onChange={handleAutoFitColumns} - /> - </Group> - </Stack> - </DropdownMenu.Item> - </> - )} - </DropdownMenu.Dropdown> - </DropdownMenu> - </Group> - </Flex> - ); + {cq.isSm ? ( + sortOrderLabel + ) : ( + <> + {filters.sortOrder === SortOrder.ASC ? ( + <RiSortAsc size="1.3rem" /> + ) : ( + <RiSortDesc size="1.3rem" /> + )} + </> + )} + </Button> + <DropdownMenu position="bottom-start"> + <DropdownMenu.Target> + <Button + compact + fw="600" + size="md" + variant="subtle" + > + <RiMoreFill size="1.3rem" /> + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + <DropdownMenu.Item + icon={<RiPlayFill />} + onClick={() => handlePlay(Play.NOW)} + > + Play + </DropdownMenu.Item> + <DropdownMenu.Item + icon={<RiAddBoxFill />} + onClick={() => handlePlay(Play.LAST)} + > + Add to queue + </DropdownMenu.Item> + <DropdownMenu.Item + icon={<RiAddCircleFill />} + onClick={() => handlePlay(Play.NEXT)} + > + Add to queue next + </DropdownMenu.Item> + <DropdownMenu.Divider /> + <DropdownMenu.Item + icon={<RiEditFill />} + onClick={() => + openUpdatePlaylistModal({ + playlist: detailQuery.data!, + server: server!, + }) + } + > + Edit playlist + </DropdownMenu.Item> + <DropdownMenu.Item + disabled + icon={<RiDeleteBinFill />} + onClick={openDeletePlaylistModal} + > + Delete playlist + </DropdownMenu.Item> + <DropdownMenu.Divider /> + <DropdownMenu.Item + icon={<RiRefreshLine />} + onClick={handleRefresh} + > + Refresh + </DropdownMenu.Item> + {server?.type === ServerType.NAVIDROME && !isSmartPlaylist && ( + <> + <DropdownMenu.Divider /> + <DropdownMenu.Item + $danger + onClick={handleToggleShowQueryBuilder} + > + Toggle smart playlist editor + </DropdownMenu.Item> + </> + )} + </DropdownMenu.Dropdown> + </DropdownMenu> + </Group> + <Group> + <DropdownMenu position="bottom-end"> + <DropdownMenu.Target> + <Button + compact + size="md" + variant="subtle" + > + <RiSettings3Fill size="1.3rem" /> + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + <DropdownMenu.Label>Display type</DropdownMenu.Label> + <DropdownMenu.Item + $isActive={page.display === ListDisplayType.TABLE} + value={ListDisplayType.TABLE} + onClick={handleSetViewType} + > + Table + </DropdownMenu.Item> + <DropdownMenu.Item + $isActive={page.display === ListDisplayType.TABLE_PAGINATED} + value={ListDisplayType.TABLE_PAGINATED} + onClick={handleSetViewType} + > + Table (paginated) + </DropdownMenu.Item> + <DropdownMenu.Divider /> + <DropdownMenu.Label>Item size</DropdownMenu.Label> + <DropdownMenu.Item closeMenuOnClick={false}> + <Slider + defaultValue={page.table.rowHeight} + label={null} + max={100} + min={25} + onChangeEnd={handleItemSize} + /> + </DropdownMenu.Item> + {(page.display === ListDisplayType.TABLE || + page.display === ListDisplayType.TABLE_PAGINATED) && ( + <> + <DropdownMenu.Label>Table Columns</DropdownMenu.Label> + <DropdownMenu.Item + closeMenuOnClick={false} + component="div" + sx={{ cursor: 'default' }} + > + <Stack> + <MultiSelect + clearable + data={SONG_TABLE_COLUMNS} + defaultValue={page.table?.columns.map( + (column) => column.column, + )} + width={300} + onChange={handleTableColumns} + /> + <Group position="apart"> + <Text>Auto Fit Columns</Text> + <Switch + defaultChecked={page.table.autoFit} + onChange={handleAutoFitColumns} + /> + </Group> + </Stack> + </DropdownMenu.Item> + </> + )} + </DropdownMenu.Dropdown> + </DropdownMenu> + </Group> + </Flex> + ); }; diff --git a/src/renderer/features/playlists/components/playlist-detail-song-list-header.tsx b/src/renderer/features/playlists/components/playlist-detail-song-list-header.tsx index 197d29d6..2828c03c 100644 --- a/src/renderer/features/playlists/components/playlist-detail-song-list-header.tsx +++ b/src/renderer/features/playlists/components/playlist-detail-song-list-header.tsx @@ -13,56 +13,60 @@ import { usePlayButtonBehavior } from '/@/renderer/store/settings.store'; import { Play } from '/@/renderer/types'; interface PlaylistDetailHeaderProps { - handleToggleShowQueryBuilder: () => void; - itemCount?: number; - tableRef: MutableRefObject<AgGridReactType | null>; + handleToggleShowQueryBuilder: () => void; + itemCount?: number; + tableRef: MutableRefObject<AgGridReactType | null>; } export const PlaylistDetailSongListHeader = ({ - tableRef, - itemCount, - handleToggleShowQueryBuilder, + tableRef, + itemCount, + handleToggleShowQueryBuilder, }: PlaylistDetailHeaderProps) => { - const { playlistId } = useParams() as { playlistId: string }; - const server = useCurrentServer(); - const detailQuery = usePlaylistDetail({ query: { id: playlistId }, serverId: server?.id }); - const handlePlayQueueAdd = usePlayQueueAdd(); + const { playlistId } = useParams() as { playlistId: string }; + const server = useCurrentServer(); + const detailQuery = usePlaylistDetail({ query: { id: playlistId }, serverId: server?.id }); + const handlePlayQueueAdd = usePlayQueueAdd(); - const handlePlay = async (playType: Play) => { - handlePlayQueueAdd?.({ - byItemType: { id: [playlistId], type: LibraryItem.PLAYLIST }, - playType, - }); - }; + const handlePlay = async (playType: Play) => { + handlePlayQueueAdd?.({ + byItemType: { id: [playlistId], type: LibraryItem.PLAYLIST }, + playType, + }); + }; - const playButtonBehavior = usePlayButtonBehavior(); + const playButtonBehavior = usePlayButtonBehavior(); - if (detailQuery.isLoading) return null; - const isSmartPlaylist = detailQuery?.data?.rules; + if (detailQuery.isLoading) return null; + const isSmartPlaylist = detailQuery?.data?.rules; - return ( - <Stack spacing={0}> - <PageHeader backgroundColor="var(--titlebar-bg)"> - <LibraryHeaderBar> - <LibraryHeaderBar.PlayButton onClick={() => handlePlay(playButtonBehavior)} /> - <LibraryHeaderBar.Title>{detailQuery?.data?.name}</LibraryHeaderBar.Title> - <Paper - fw="600" - px="1rem" - py="0.3rem" - radius="sm" - > - {itemCount === null || itemCount === undefined ? <SpinnerIcon /> : itemCount} - </Paper> - {isSmartPlaylist && <Badge size="lg">Smart playlist</Badge>} - </LibraryHeaderBar> - </PageHeader> - <Paper p="1rem"> - <PlaylistDetailSongListHeaderFilters - handleToggleShowQueryBuilder={handleToggleShowQueryBuilder} - tableRef={tableRef} - /> - </Paper> - </Stack> - ); + return ( + <Stack spacing={0}> + <PageHeader backgroundColor="var(--titlebar-bg)"> + <LibraryHeaderBar> + <LibraryHeaderBar.PlayButton onClick={() => handlePlay(playButtonBehavior)} /> + <LibraryHeaderBar.Title>{detailQuery?.data?.name}</LibraryHeaderBar.Title> + <Paper + fw="600" + px="1rem" + py="0.3rem" + radius="sm" + > + {itemCount === null || itemCount === undefined ? ( + <SpinnerIcon /> + ) : ( + itemCount + )} + </Paper> + {isSmartPlaylist && <Badge size="lg">Smart playlist</Badge>} + </LibraryHeaderBar> + </PageHeader> + <Paper p="1rem"> + <PlaylistDetailSongListHeaderFilters + handleToggleShowQueryBuilder={handleToggleShowQueryBuilder} + tableRef={tableRef} + /> + </Paper> + </Stack> + ); }; diff --git a/src/renderer/features/playlists/components/playlist-list-content.tsx b/src/renderer/features/playlists/components/playlist-list-content.tsx index 4cd996a4..c639f650 100644 --- a/src/renderer/features/playlists/components/playlist-list-content.tsx +++ b/src/renderer/features/playlists/components/playlist-list-content.tsx @@ -1,11 +1,11 @@ import { MutableRefObject, useCallback, useMemo } from 'react'; import type { - BodyScrollEvent, - ColDef, - GridReadyEvent, - IDatasource, - PaginationChangedEvent, - RowDoubleClickedEvent, + BodyScrollEvent, + ColDef, + GridReadyEvent, + IDatasource, + PaginationChangedEvent, + RowDoubleClickedEvent, } from '@ag-grid-community/core'; import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact'; import { Stack } from '@mantine/core'; @@ -13,11 +13,11 @@ import { useQueryClient } from '@tanstack/react-query'; import { api } from '/@/renderer/api'; import { queryKeys } from '/@/renderer/api/query-keys'; import { - useCurrentServer, - usePlaylistListStore, - usePlaylistTablePagination, - useSetPlaylistTable, - useSetPlaylistTablePagination, + useCurrentServer, + usePlaylistListStore, + usePlaylistTablePagination, + useSetPlaylistTable, + useSetPlaylistTablePagination, } from '/@/renderer/store'; import { ListDisplayType } from '/@/renderer/types'; import { AnimatePresence } from 'framer-motion'; @@ -31,198 +31,203 @@ import { VirtualGridAutoSizerContainer } from '/@/renderer/components/virtual-gr import { getColumnDefs, VirtualTable, TablePagination } from '/@/renderer/components/virtual-table'; interface PlaylistListContentProps { - itemCount?: number; - tableRef: MutableRefObject<AgGridReactType | null>; + itemCount?: number; + tableRef: MutableRefObject<AgGridReactType | null>; } export const PlaylistListContent = ({ tableRef, itemCount }: PlaylistListContentProps) => { - const navigate = useNavigate(); - const queryClient = useQueryClient(); - const server = useCurrentServer(); - const page = usePlaylistListStore(); + const navigate = useNavigate(); + const queryClient = useQueryClient(); + const server = useCurrentServer(); + const page = usePlaylistListStore(); - const pagination = usePlaylistTablePagination(); - const setPagination = useSetPlaylistTablePagination(); - const setTable = useSetPlaylistTable(); + const pagination = usePlaylistTablePagination(); + const setPagination = useSetPlaylistTablePagination(); + const setTable = useSetPlaylistTable(); - const isPaginationEnabled = page.display === ListDisplayType.TABLE_PAGINATED; + const isPaginationEnabled = page.display === ListDisplayType.TABLE_PAGINATED; - const columnDefs: ColDef[] = useMemo( - () => getColumnDefs(page.table.columns), - [page.table.columns], - ); + const columnDefs: ColDef[] = useMemo( + () => getColumnDefs(page.table.columns), + [page.table.columns], + ); - const defaultColumnDefs: ColDef = useMemo(() => { - return { - lockPinned: true, - lockVisible: true, - resizable: true, + const defaultColumnDefs: ColDef = useMemo(() => { + return { + lockPinned: true, + lockVisible: true, + resizable: true, + }; + }, []); + + const onGridReady = useCallback( + (params: GridReadyEvent) => { + const dataSource: IDatasource = { + getRows: async (params) => { + const limit = params.endRow - params.startRow; + const startIndex = params.startRow; + + const queryKey = queryKeys.playlists.list(server?.id || '', { + limit, + startIndex, + ...page.filter, + }); + + const playlistsRes = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.getPlaylistList({ + apiClientProps: { + server, + signal, + }, + query: { + limit, + startIndex, + ...page.filter, + }, + }), + { cacheTime: 1000 * 60 * 1 }, + ); + + params.successCallback( + playlistsRes?.items || [], + playlistsRes?.totalRecordCount || 0, + ); + }, + rowCount: undefined, + }; + params.api.setDatasource(dataSource); + params.api.ensureIndexVisible(page.table.scrollOffset, 'top'); + }, + [page.filter, page.table.scrollOffset, queryClient, server], + ); + + const onPaginationChanged = useCallback( + (event: PaginationChangedEvent) => { + if (!isPaginationEnabled || !event.api) return; + + try { + // Scroll to top of page on pagination change + const currentPageStartIndex = pagination.currentPage * pagination.itemsPerPage; + event.api?.ensureIndexVisible(currentPageStartIndex, 'top'); + } catch (err) { + console.log(err); + } + + setPagination({ + data: { + itemsPerPage: event.api.paginationGetPageSize(), + totalItems: event.api.paginationGetRowCount(), + totalPages: event.api.paginationGetTotalPages() + 1, + }, + }); + }, + [isPaginationEnabled, pagination.currentPage, pagination.itemsPerPage, setPagination], + ); + + const handleGridSizeChange = () => { + if (page.table.autoFit) { + tableRef?.current?.api.sizeColumnsToFit(); + } }; - }, []); - const onGridReady = useCallback( - (params: GridReadyEvent) => { - const dataSource: IDatasource = { - getRows: async (params) => { - const limit = params.endRow - params.startRow; - const startIndex = params.startRow; + const handleColumnChange = useCallback(() => { + const { columnApi } = tableRef?.current || {}; + const columnsOrder = columnApi?.getAllGridColumns(); - const queryKey = queryKeys.playlists.list(server?.id || '', { - limit, - startIndex, - ...page.filter, - }); + if (!columnsOrder) return; - const playlistsRes = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.getPlaylistList({ - apiClientProps: { - server, - signal, - }, - query: { - limit, - startIndex, - ...page.filter, - }, - }), - { cacheTime: 1000 * 60 * 1 }, - ); + const columnsInSettings = page.table.columns; + const updatedColumns = []; + for (const column of columnsOrder) { + const columnInSettings = columnsInSettings.find( + (c) => c.column === column.getColDef().colId, + ); - params.successCallback(playlistsRes?.items || [], playlistsRes?.totalRecordCount || 0); - }, - rowCount: undefined, - }; - params.api.setDatasource(dataSource); - params.api.ensureIndexVisible(page.table.scrollOffset, 'top'); - }, - [page.filter, page.table.scrollOffset, queryClient, server], - ); + if (columnInSettings) { + updatedColumns.push({ + ...columnInSettings, + ...(!page.table.autoFit && { + width: column.getActualWidth(), + }), + }); + } + } - const onPaginationChanged = useCallback( - (event: PaginationChangedEvent) => { - if (!isPaginationEnabled || !event.api) return; + setTable({ columns: updatedColumns }); + }, [page.table.autoFit, page.table.columns, setTable, tableRef]); - try { - // Scroll to top of page on pagination change - const currentPageStartIndex = pagination.currentPage * pagination.itemsPerPage; - event.api?.ensureIndexVisible(currentPageStartIndex, 'top'); - } catch (err) { - console.log(err); - } + const debouncedColumnChange = debounce(handleColumnChange, 200); - setPagination({ - data: { - itemsPerPage: event.api.paginationGetPageSize(), - totalItems: event.api.paginationGetRowCount(), - totalPages: event.api.paginationGetTotalPages() + 1, - }, - }); - }, - [isPaginationEnabled, pagination.currentPage, pagination.itemsPerPage, setPagination], - ); + const handleScroll = (e: BodyScrollEvent) => { + const scrollOffset = Number((e.top / page.table.rowHeight).toFixed(0)); + setTable({ scrollOffset }); + }; - const handleGridSizeChange = () => { - if (page.table.autoFit) { - tableRef?.current?.api.sizeColumnsToFit(); - } - }; + const handleContextMenu = useHandleTableContextMenu( + LibraryItem.PLAYLIST, + PLAYLIST_CONTEXT_MENU_ITEMS, + ); - const handleColumnChange = useCallback(() => { - const { columnApi } = tableRef?.current || {}; - const columnsOrder = columnApi?.getAllGridColumns(); + const handleRowDoubleClick = (e: RowDoubleClickedEvent) => { + if (!e.data) return; + navigate(generatePath(AppRoute.PLAYLISTS_DETAIL, { playlistId: e.data.id })); + }; - if (!columnsOrder) return; - - const columnsInSettings = page.table.columns; - const updatedColumns = []; - for (const column of columnsOrder) { - const columnInSettings = columnsInSettings.find((c) => c.column === column.getColDef().colId); - - if (columnInSettings) { - updatedColumns.push({ - ...columnInSettings, - ...(!page.table.autoFit && { - width: column.getActualWidth(), - }), - }); - } - } - - setTable({ columns: updatedColumns }); - }, [page.table.autoFit, page.table.columns, setTable, tableRef]); - - const debouncedColumnChange = debounce(handleColumnChange, 200); - - const handleScroll = (e: BodyScrollEvent) => { - const scrollOffset = Number((e.top / page.table.rowHeight).toFixed(0)); - setTable({ scrollOffset }); - }; - - const handleContextMenu = useHandleTableContextMenu( - LibraryItem.PLAYLIST, - PLAYLIST_CONTEXT_MENU_ITEMS, - ); - - const handleRowDoubleClick = (e: RowDoubleClickedEvent) => { - if (!e.data) return; - navigate(generatePath(AppRoute.PLAYLISTS_DETAIL, { playlistId: e.data.id })); - }; - - return ( - <Stack - h="100%" - spacing={0} - > - <VirtualGridAutoSizerContainer> - <VirtualTable - // https://github.com/ag-grid/ag-grid/issues/5284 - // Key is used to force remount of table when display, rowHeight, or server changes - key={`table-${page.display}-${page.table.rowHeight}-${server?.id}`} - ref={tableRef} - alwaysShowHorizontalScroll - suppressRowDrag - autoFitColumns={page.table.autoFit} - blockLoadDebounceMillis={200} - cacheBlockSize={200} - cacheOverflowSize={1} - columnDefs={columnDefs} - defaultColDef={defaultColumnDefs} - enableCellChangeFlash={false} - getRowId={(data) => data.data.id} - infiniteInitialRowCount={itemCount || 100} - pagination={isPaginationEnabled} - paginationAutoPageSize={isPaginationEnabled} - paginationPageSize={page.table.pagination.itemsPerPage || 100} - rowBuffer={20} - rowHeight={page.table.rowHeight || 40} - rowModelType="infinite" - rowSelection="multiple" - onBodyScrollEnd={handleScroll} - onCellContextMenu={handleContextMenu} - onColumnMoved={handleColumnChange} - onColumnResized={debouncedColumnChange} - onGridReady={onGridReady} - onGridSizeChanged={handleGridSizeChange} - onPaginationChanged={onPaginationChanged} - onRowDoubleClicked={handleRowDoubleClick} - /> - </VirtualGridAutoSizerContainer> - <AnimatePresence - presenceAffectsLayout - initial={false} - mode="wait" - > - {page.display === ListDisplayType.TABLE_PAGINATED && ( - <TablePagination - pageKey="" - pagination={pagination} - setPagination={setPagination} - tableRef={tableRef} - /> - )} - </AnimatePresence> - </Stack> - ); + return ( + <Stack + h="100%" + spacing={0} + > + <VirtualGridAutoSizerContainer> + <VirtualTable + // https://github.com/ag-grid/ag-grid/issues/5284 + // Key is used to force remount of table when display, rowHeight, or server changes + key={`table-${page.display}-${page.table.rowHeight}-${server?.id}`} + ref={tableRef} + alwaysShowHorizontalScroll + suppressRowDrag + autoFitColumns={page.table.autoFit} + blockLoadDebounceMillis={200} + cacheBlockSize={200} + cacheOverflowSize={1} + columnDefs={columnDefs} + defaultColDef={defaultColumnDefs} + enableCellChangeFlash={false} + getRowId={(data) => data.data.id} + infiniteInitialRowCount={itemCount || 100} + pagination={isPaginationEnabled} + paginationAutoPageSize={isPaginationEnabled} + paginationPageSize={page.table.pagination.itemsPerPage || 100} + rowBuffer={20} + rowHeight={page.table.rowHeight || 40} + rowModelType="infinite" + rowSelection="multiple" + onBodyScrollEnd={handleScroll} + onCellContextMenu={handleContextMenu} + onColumnMoved={handleColumnChange} + onColumnResized={debouncedColumnChange} + onGridReady={onGridReady} + onGridSizeChanged={handleGridSizeChange} + onPaginationChanged={onPaginationChanged} + onRowDoubleClicked={handleRowDoubleClick} + /> + </VirtualGridAutoSizerContainer> + <AnimatePresence + presenceAffectsLayout + initial={false} + mode="wait" + > + {page.display === ListDisplayType.TABLE_PAGINATED && ( + <TablePagination + pageKey="" + pagination={pagination} + setPagination={setPagination} + tableRef={tableRef} + /> + )} + </AnimatePresence> + </Stack> + ); }; diff --git a/src/renderer/features/playlists/components/playlist-list-header-filters.tsx b/src/renderer/features/playlists/components/playlist-list-header-filters.tsx index 33d31d7d..66a16ce3 100644 --- a/src/renderer/features/playlists/components/playlist-list-header-filters.tsx +++ b/src/renderer/features/playlists/components/playlist-list-header-filters.tsx @@ -10,319 +10,327 @@ import { SortOrder, PlaylistListSort } from '/@/renderer/api/types'; import { DropdownMenu, Text, Button, Slider, MultiSelect, Switch } from '/@/renderer/components'; import { useContainerQuery } from '/@/renderer/hooks'; import { - PlaylistListFilter, - useCurrentServer, - usePlaylistListStore, - useSetPlaylistFilters, - useSetPlaylistStore, - useSetPlaylistTable, - useSetPlaylistTablePagination, + PlaylistListFilter, + useCurrentServer, + usePlaylistListStore, + useSetPlaylistFilters, + useSetPlaylistStore, + useSetPlaylistTable, + useSetPlaylistTablePagination, } from '/@/renderer/store'; import { ListDisplayType, TableColumn } from '/@/renderer/types'; import { PLAYLIST_TABLE_COLUMNS } from '/@/renderer/components/virtual-table'; const FILTERS = { - jellyfin: [ - { defaultOrder: SortOrder.DESC, name: 'Duration', value: PlaylistListSort.DURATION }, - { defaultOrder: SortOrder.ASC, name: 'Name', value: PlaylistListSort.NAME }, - { defaultOrder: SortOrder.DESC, name: 'Song Count', value: PlaylistListSort.SONG_COUNT }, - ], - navidrome: [ - { defaultOrder: SortOrder.DESC, name: 'Duration', value: PlaylistListSort.DURATION }, - { defaultOrder: SortOrder.ASC, name: 'Name', value: PlaylistListSort.NAME }, - { defaultOrder: SortOrder.ASC, name: 'Owner', value: PlaylistListSort.OWNER }, - { defaultOrder: SortOrder.DESC, name: 'Public', value: PlaylistListSort.PUBLIC }, - { defaultOrder: SortOrder.DESC, name: 'Song Count', value: PlaylistListSort.SONG_COUNT }, - { defaultOrder: SortOrder.DESC, name: 'Updated At', value: PlaylistListSort.UPDATED_AT }, - ], + jellyfin: [ + { defaultOrder: SortOrder.DESC, name: 'Duration', value: PlaylistListSort.DURATION }, + { defaultOrder: SortOrder.ASC, name: 'Name', value: PlaylistListSort.NAME }, + { defaultOrder: SortOrder.DESC, name: 'Song Count', value: PlaylistListSort.SONG_COUNT }, + ], + navidrome: [ + { defaultOrder: SortOrder.DESC, name: 'Duration', value: PlaylistListSort.DURATION }, + { defaultOrder: SortOrder.ASC, name: 'Name', value: PlaylistListSort.NAME }, + { defaultOrder: SortOrder.ASC, name: 'Owner', value: PlaylistListSort.OWNER }, + { defaultOrder: SortOrder.DESC, name: 'Public', value: PlaylistListSort.PUBLIC }, + { defaultOrder: SortOrder.DESC, name: 'Song Count', value: PlaylistListSort.SONG_COUNT }, + { defaultOrder: SortOrder.DESC, name: 'Updated At', value: PlaylistListSort.UPDATED_AT }, + ], }; const ORDER = [ - { name: 'Ascending', value: SortOrder.ASC }, - { name: 'Descending', value: SortOrder.DESC }, + { name: 'Ascending', value: SortOrder.ASC }, + { name: 'Descending', value: SortOrder.DESC }, ]; interface PlaylistListHeaderFiltersProps { - tableRef: MutableRefObject<AgGridReactType | null>; + tableRef: MutableRefObject<AgGridReactType | null>; } export const PlaylistListHeaderFilters = ({ tableRef }: PlaylistListHeaderFiltersProps) => { - const queryClient = useQueryClient(); - const server = useCurrentServer(); - const page = usePlaylistListStore(); - const setPage = useSetPlaylistStore(); - const setFilter = useSetPlaylistFilters(); - const setTable = useSetPlaylistTable(); - const setPagination = useSetPlaylistTablePagination(); - const cq = useContainerQuery(); + const queryClient = useQueryClient(); + const server = useCurrentServer(); + const page = usePlaylistListStore(); + const setPage = useSetPlaylistStore(); + const setFilter = useSetPlaylistFilters(); + const setTable = useSetPlaylistTable(); + const setPagination = useSetPlaylistTablePagination(); + const cq = useContainerQuery(); - const sortByLabel = - (server?.type && - (FILTERS[server.type as keyof typeof FILTERS] as { name: string; value: string }[]).find( - (f) => f.value === page.filter.sortBy, - )?.name) || - 'Unknown'; + const sortByLabel = + (server?.type && + ( + FILTERS[server.type as keyof typeof FILTERS] as { name: string; value: string }[] + ).find((f) => f.value === page.filter.sortBy)?.name) || + 'Unknown'; - const sortOrderLabel = ORDER.find((s) => s.value === page.filter.sortOrder)?.name; + const sortOrderLabel = ORDER.find((s) => s.value === page.filter.sortOrder)?.name; - const handleFilterChange = useCallback( - async (filters?: PlaylistListFilter) => { - const dataSource: IDatasource = { - getRows: async (params) => { - const limit = params.endRow - params.startRow; - const startIndex = params.startRow; + const handleFilterChange = useCallback( + async (filters?: PlaylistListFilter) => { + const dataSource: IDatasource = { + getRows: async (params) => { + const limit = params.endRow - params.startRow; + const startIndex = params.startRow; - const pageFilters = filters || page.filter; + const pageFilters = filters || page.filter; - const queryKey = queryKeys.playlists.list(server?.id || '', { - limit, - startIndex, - ...pageFilters, - }); + const queryKey = queryKeys.playlists.list(server?.id || '', { + limit, + startIndex, + ...pageFilters, + }); - const playlistsRes = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.getPlaylistList({ - apiClientProps: { - server, - signal, + const playlistsRes = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.getPlaylistList({ + apiClientProps: { + server, + signal, + }, + query: { + limit, + startIndex, + ...pageFilters, + }, + }), + { cacheTime: 1000 * 60 * 1 }, + ); + + params.successCallback( + playlistsRes?.items || [], + playlistsRes?.totalRecordCount || 0, + ); }, - query: { - limit, - startIndex, - ...pageFilters, - }, - }), - { cacheTime: 1000 * 60 * 1 }, - ); - - params.successCallback(playlistsRes?.items || [], playlistsRes?.totalRecordCount || 0); + rowCount: undefined, + }; + tableRef.current?.api.setDatasource(dataSource); + tableRef.current?.api.purgeInfiniteCache(); + tableRef.current?.api.ensureIndexVisible(0, 'top'); + setPagination({ data: { currentPage: 0 } }); }, - rowCount: undefined, - }; - tableRef.current?.api.setDatasource(dataSource); - tableRef.current?.api.purgeInfiniteCache(); - tableRef.current?.api.ensureIndexVisible(0, 'top'); - setPagination({ data: { currentPage: 0 } }); - }, - [page.filter, queryClient, server, setPagination, tableRef], - ); + [page.filter, queryClient, server, setPagination, tableRef], + ); - const handleSetSortBy = useCallback( - (e: MouseEvent<HTMLButtonElement>) => { - if (!e.currentTarget?.value || !server?.type) return; + const handleSetSortBy = useCallback( + (e: MouseEvent<HTMLButtonElement>) => { + if (!e.currentTarget?.value || !server?.type) return; - const sortOrder = FILTERS[server.type as keyof typeof FILTERS].find( - (f) => f.value === e.currentTarget.value, - )?.defaultOrder; + const sortOrder = FILTERS[server.type as keyof typeof FILTERS].find( + (f) => f.value === e.currentTarget.value, + )?.defaultOrder; - const updatedFilters = setFilter({ - sortBy: e.currentTarget.value as PlaylistListSort, - sortOrder: sortOrder || SortOrder.ASC, - }); + const updatedFilters = setFilter({ + sortBy: e.currentTarget.value as PlaylistListSort, + sortOrder: sortOrder || SortOrder.ASC, + }); - handleFilterChange(updatedFilters); - }, - [handleFilterChange, server?.type, setFilter], - ); + handleFilterChange(updatedFilters); + }, + [handleFilterChange, server?.type, setFilter], + ); - const handleToggleSortOrder = useCallback(() => { - const newSortOrder = page.filter.sortOrder === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC; - const updatedFilters = setFilter({ sortOrder: newSortOrder }); - handleFilterChange(updatedFilters); - }, [page.filter.sortOrder, handleFilterChange, setFilter]); + const handleToggleSortOrder = useCallback(() => { + const newSortOrder = + page.filter.sortOrder === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC; + const updatedFilters = setFilter({ sortOrder: newSortOrder }); + handleFilterChange(updatedFilters); + }, [page.filter.sortOrder, handleFilterChange, setFilter]); - const handleSetViewType = useCallback( - (e: MouseEvent<HTMLButtonElement>) => { - if (!e.currentTarget?.value) return; - const display = e.currentTarget.value as ListDisplayType; - setPage({ list: { ...page, display: e.currentTarget.value as ListDisplayType } }); + const handleSetViewType = useCallback( + (e: MouseEvent<HTMLButtonElement>) => { + if (!e.currentTarget?.value) return; + const display = e.currentTarget.value as ListDisplayType; + setPage({ list: { ...page, display: e.currentTarget.value as ListDisplayType } }); - if (display === ListDisplayType.TABLE) { - tableRef.current?.api.paginationSetPageSize(tableRef.current.props.infiniteInitialRowCount); - setPagination({ data: { currentPage: 0 } }); - } else if (display === ListDisplayType.TABLE_PAGINATED) { - setPagination({ data: { currentPage: 0 } }); - } - }, - [page, setPage, setPagination, tableRef], - ); + if (display === ListDisplayType.TABLE) { + tableRef.current?.api.paginationSetPageSize( + tableRef.current.props.infiniteInitialRowCount, + ); + setPagination({ data: { currentPage: 0 } }); + } else if (display === ListDisplayType.TABLE_PAGINATED) { + setPagination({ data: { currentPage: 0 } }); + } + }, + [page, setPage, setPagination, tableRef], + ); - const handleTableColumns = (values: TableColumn[]) => { - const existingColumns = page.table.columns; + const handleTableColumns = (values: TableColumn[]) => { + const existingColumns = page.table.columns; - if (values.length === 0) { - return setTable({ - columns: [], - }); - } + if (values.length === 0) { + return setTable({ + columns: [], + }); + } - // If adding a column - if (values.length > existingColumns.length) { - const newColumn = { column: values[values.length - 1], width: 100 }; + // If adding a column + if (values.length > existingColumns.length) { + const newColumn = { column: values[values.length - 1], width: 100 }; - return setTable({ columns: [...existingColumns, newColumn] }); - } + return setTable({ columns: [...existingColumns, newColumn] }); + } - // If removing a column - const removed = existingColumns.filter((column) => !values.includes(column.column)); - const newColumns = existingColumns.filter((column) => !removed.includes(column)); + // If removing a column + const removed = existingColumns.filter((column) => !values.includes(column.column)); + const newColumns = existingColumns.filter((column) => !removed.includes(column)); - return setTable({ columns: newColumns }); - }; + return setTable({ columns: newColumns }); + }; - const handleAutoFitColumns = (e: ChangeEvent<HTMLInputElement>) => { - setTable({ autoFit: e.currentTarget.checked }); + const handleAutoFitColumns = (e: ChangeEvent<HTMLInputElement>) => { + setTable({ autoFit: e.currentTarget.checked }); - if (e.currentTarget.checked) { - tableRef.current?.api.sizeColumnsToFit(); - } - }; + if (e.currentTarget.checked) { + tableRef.current?.api.sizeColumnsToFit(); + } + }; - const handleRowHeight = (e: number) => { - setTable({ rowHeight: e }); - }; + const handleRowHeight = (e: number) => { + setTable({ rowHeight: e }); + }; - const handleRefresh = () => { - tableRef?.current?.api?.purgeInfiniteCache(); - }; + const handleRefresh = () => { + tableRef?.current?.api?.purgeInfiniteCache(); + }; - return ( - <Flex justify="space-between"> - <Group - ref={cq.ref} - spacing="sm" - w="100%" - > - <DropdownMenu position="bottom-start"> - <DropdownMenu.Target> - <Button - compact - fw="600" - size="md" - variant="subtle" + return ( + <Flex justify="space-between"> + <Group + ref={cq.ref} + spacing="sm" + w="100%" > - {sortByLabel} - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - {FILTERS[server?.type as keyof typeof FILTERS].map((filter) => ( - <DropdownMenu.Item - key={`filter-${filter.name}`} - $isActive={filter.value === page.filter.sortBy} - value={filter.value} - onClick={handleSetSortBy} - > - {filter.name} - </DropdownMenu.Item> - ))} - </DropdownMenu.Dropdown> - </DropdownMenu> - <Button - compact - fw="600" - size="md" - variant="subtle" - onClick={handleToggleSortOrder} - > - {cq.isSm ? ( - sortOrderLabel - ) : ( - <> - {page.filter.sortOrder === SortOrder.ASC ? ( - <RiSortAsc size="1.3rem" /> - ) : ( - <RiSortDesc size="1.3rem" /> - )} - </> - )} - </Button> - <DropdownMenu position="bottom-start"> - <DropdownMenu.Target> - <Button - compact - fw="600" - size="md" - variant="subtle" - > - <RiMoreFill size="1.3rem" /> - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - <DropdownMenu.Item - icon={<RiRefreshLine />} - onClick={handleRefresh} - > - Refresh - </DropdownMenu.Item> - </DropdownMenu.Dropdown> - </DropdownMenu> - </Group> - <Group> - <DropdownMenu position="bottom-end"> - <DropdownMenu.Target> - <Button - compact - size="md" - variant="subtle" - > - <RiSettings3Fill size="1.3rem" /> - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - <DropdownMenu.Label>Display type</DropdownMenu.Label> - <DropdownMenu.Item - $isActive={page.display === ListDisplayType.TABLE} - value={ListDisplayType.TABLE} - onClick={handleSetViewType} - > - Table - </DropdownMenu.Item> - <DropdownMenu.Item - $isActive={page.display === ListDisplayType.TABLE_PAGINATED} - value={ListDisplayType.TABLE_PAGINATED} - onClick={handleSetViewType} - > - Table (paginated) - </DropdownMenu.Item> - <DropdownMenu.Divider /> - <DropdownMenu.Label>Item Size</DropdownMenu.Label> - <DropdownMenu.Item closeMenuOnClick={false}> - <Slider - defaultValue={page.table.rowHeight || 0} - label={null} - max={100} - min={25} - onChangeEnd={handleRowHeight} - /> - </DropdownMenu.Item> - <DropdownMenu.Label>Table Columns</DropdownMenu.Label> - <DropdownMenu.Item - closeMenuOnClick={false} - component="div" - sx={{ cursor: 'default' }} - > - <Stack> - <MultiSelect - clearable - data={PLAYLIST_TABLE_COLUMNS} - defaultValue={page.table?.columns.map((column) => column.column)} - width={300} - onChange={handleTableColumns} - /> - <Group position="apart"> - <Text>Auto Fit Columns</Text> - <Switch - defaultChecked={page.table.autoFit} - onChange={handleAutoFitColumns} - /> - </Group> - </Stack> - </DropdownMenu.Item> - </DropdownMenu.Dropdown> - </DropdownMenu> - </Group> - </Flex> - ); + <DropdownMenu position="bottom-start"> + <DropdownMenu.Target> + <Button + compact + fw="600" + size="md" + variant="subtle" + > + {sortByLabel} + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + {FILTERS[server?.type as keyof typeof FILTERS].map((filter) => ( + <DropdownMenu.Item + key={`filter-${filter.name}`} + $isActive={filter.value === page.filter.sortBy} + value={filter.value} + onClick={handleSetSortBy} + > + {filter.name} + </DropdownMenu.Item> + ))} + </DropdownMenu.Dropdown> + </DropdownMenu> + <Button + compact + fw="600" + size="md" + variant="subtle" + onClick={handleToggleSortOrder} + > + {cq.isSm ? ( + sortOrderLabel + ) : ( + <> + {page.filter.sortOrder === SortOrder.ASC ? ( + <RiSortAsc size="1.3rem" /> + ) : ( + <RiSortDesc size="1.3rem" /> + )} + </> + )} + </Button> + <DropdownMenu position="bottom-start"> + <DropdownMenu.Target> + <Button + compact + fw="600" + size="md" + variant="subtle" + > + <RiMoreFill size="1.3rem" /> + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + <DropdownMenu.Item + icon={<RiRefreshLine />} + onClick={handleRefresh} + > + Refresh + </DropdownMenu.Item> + </DropdownMenu.Dropdown> + </DropdownMenu> + </Group> + <Group> + <DropdownMenu position="bottom-end"> + <DropdownMenu.Target> + <Button + compact + size="md" + variant="subtle" + > + <RiSettings3Fill size="1.3rem" /> + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + <DropdownMenu.Label>Display type</DropdownMenu.Label> + <DropdownMenu.Item + $isActive={page.display === ListDisplayType.TABLE} + value={ListDisplayType.TABLE} + onClick={handleSetViewType} + > + Table + </DropdownMenu.Item> + <DropdownMenu.Item + $isActive={page.display === ListDisplayType.TABLE_PAGINATED} + value={ListDisplayType.TABLE_PAGINATED} + onClick={handleSetViewType} + > + Table (paginated) + </DropdownMenu.Item> + <DropdownMenu.Divider /> + <DropdownMenu.Label>Item Size</DropdownMenu.Label> + <DropdownMenu.Item closeMenuOnClick={false}> + <Slider + defaultValue={page.table.rowHeight || 0} + label={null} + max={100} + min={25} + onChangeEnd={handleRowHeight} + /> + </DropdownMenu.Item> + <DropdownMenu.Label>Table Columns</DropdownMenu.Label> + <DropdownMenu.Item + closeMenuOnClick={false} + component="div" + sx={{ cursor: 'default' }} + > + <Stack> + <MultiSelect + clearable + data={PLAYLIST_TABLE_COLUMNS} + defaultValue={page.table?.columns.map( + (column) => column.column, + )} + width={300} + onChange={handleTableColumns} + /> + <Group position="apart"> + <Text>Auto Fit Columns</Text> + <Switch + defaultChecked={page.table.autoFit} + onChange={handleAutoFitColumns} + /> + </Group> + </Stack> + </DropdownMenu.Item> + </DropdownMenu.Dropdown> + </DropdownMenu> + </Group> + </Flex> + ); }; diff --git a/src/renderer/features/playlists/components/playlist-list-header.tsx b/src/renderer/features/playlists/components/playlist-list-header.tsx index db96ed66..f320f284 100644 --- a/src/renderer/features/playlists/components/playlist-list-header.tsx +++ b/src/renderer/features/playlists/components/playlist-list-header.tsx @@ -11,53 +11,57 @@ import { useCurrentServer } from '/@/renderer/store'; import { ServerType } from '/@/renderer/types'; interface PlaylistListHeaderProps { - itemCount?: number; - tableRef: MutableRefObject<AgGridReactType | null>; + itemCount?: number; + tableRef: MutableRefObject<AgGridReactType | null>; } export const PlaylistListHeader = ({ itemCount, tableRef }: PlaylistListHeaderProps) => { - const cq = useContainerQuery(); - const server = useCurrentServer(); + const cq = useContainerQuery(); + const server = useCurrentServer(); - const handleCreatePlaylistModal = () => { - openModal({ - children: <CreatePlaylistForm onCancel={() => closeAllModals()} />, - onClose: () => { - tableRef?.current?.api?.purgeInfiniteCache(); - }, - size: server?.type === ServerType?.NAVIDROME ? 'xl' : 'sm', - title: 'Create Playlist', - }); - }; + const handleCreatePlaylistModal = () => { + openModal({ + children: <CreatePlaylistForm onCancel={() => closeAllModals()} />, + onClose: () => { + tableRef?.current?.api?.purgeInfiniteCache(); + }, + size: server?.type === ServerType?.NAVIDROME ? 'xl' : 'sm', + title: 'Create Playlist', + }); + }; - return ( - <Stack - ref={cq.ref} - spacing={0} - > - <PageHeader backgroundColor="var(--titlebar-bg)"> - <Flex - align="center" - justify="space-between" - w="100%" + return ( + <Stack + ref={cq.ref} + spacing={0} > - <LibraryHeaderBar> - <LibraryHeaderBar.Title>Playlists</LibraryHeaderBar.Title> - <Paper - fw="600" - px="1rem" - py="0.3rem" - radius="sm" - > - {itemCount === null || itemCount === undefined ? <SpinnerIcon /> : itemCount} + <PageHeader backgroundColor="var(--titlebar-bg)"> + <Flex + align="center" + justify="space-between" + w="100%" + > + <LibraryHeaderBar> + <LibraryHeaderBar.Title>Playlists</LibraryHeaderBar.Title> + <Paper + fw="600" + px="1rem" + py="0.3rem" + radius="sm" + > + {itemCount === null || itemCount === undefined ? ( + <SpinnerIcon /> + ) : ( + itemCount + )} + </Paper> + </LibraryHeaderBar> + <Button onClick={handleCreatePlaylistModal}>Create playlist</Button> + </Flex> + </PageHeader> + <Paper p="1rem"> + <PlaylistListHeaderFilters tableRef={tableRef} /> </Paper> - </LibraryHeaderBar> - <Button onClick={handleCreatePlaylistModal}>Create playlist</Button> - </Flex> - </PageHeader> - <Paper p="1rem"> - <PlaylistListHeaderFilters tableRef={tableRef} /> - </Paper> - </Stack> - ); + </Stack> + ); }; diff --git a/src/renderer/features/playlists/components/playlist-query-builder.tsx b/src/renderer/features/playlists/components/playlist-query-builder.tsx index 1a34f24c..992cd951 100644 --- a/src/renderer/features/playlists/components/playlist-query-builder.tsx +++ b/src/renderer/features/playlists/components/playlist-query-builder.tsx @@ -6,468 +6,470 @@ import get from 'lodash/get'; import setWith from 'lodash/setWith'; import { nanoid } from 'nanoid'; import { - Button, - DropdownMenu, - MotionFlex, - NumberInput, - QueryBuilder, - ScrollArea, - Select, + Button, + DropdownMenu, + MotionFlex, + NumberInput, + QueryBuilder, + ScrollArea, + Select, } from '/@/renderer/components'; import { - convertNDQueryToQueryGroup, - convertQueryGroupToNDQuery, + convertNDQueryToQueryGroup, + convertQueryGroupToNDQuery, } from '/@/renderer/features/playlists/utils'; import { QueryBuilderGroup, QueryBuilderRule } from '/@/renderer/types'; import { RiMore2Fill, RiSaveLine } from 'react-icons/ri'; import { SongListSort } from '/@/renderer/api/types'; import { - NDSongQueryBooleanOperators, - NDSongQueryDateOperators, - NDSongQueryFields, - NDSongQueryNumberOperators, - NDSongQueryStringOperators, + NDSongQueryBooleanOperators, + NDSongQueryDateOperators, + NDSongQueryFields, + NDSongQueryNumberOperators, + NDSongQueryStringOperators, } from '/@/renderer/api/navidrome.types'; type AddArgs = { - groupIndex: number[]; - level: number; + groupIndex: number[]; + level: number; }; type DeleteArgs = { - groupIndex: number[]; - level: number; - uniqueId: string; + groupIndex: number[]; + level: number; + uniqueId: string; }; interface PlaylistQueryBuilderProps { - isSaving?: boolean; - limit?: number; - onSave?: ( - parsedFilter: any, - extraFilters: { limit?: number; sortBy?: string; sortOrder?: string }, - ) => void; - onSaveAs?: ( - parsedFilter: any, - extraFilters: { limit?: number; sortBy?: string; sortOrder?: string }, - ) => void; - query: any; - sortBy: SongListSort; - sortOrder: 'asc' | 'desc'; + isSaving?: boolean; + limit?: number; + onSave?: ( + parsedFilter: any, + extraFilters: { limit?: number; sortBy?: string; sortOrder?: string }, + ) => void; + onSaveAs?: ( + parsedFilter: any, + extraFilters: { limit?: number; sortBy?: string; sortOrder?: string }, + ) => void; + query: any; + sortBy: SongListSort; + sortOrder: 'asc' | 'desc'; } const DEFAULT_QUERY = { - group: [], - rules: [ - { - field: '', - operator: '', - uniqueId: nanoid(), - value: '', - }, - ], - type: 'all' as 'all' | 'any', - uniqueId: nanoid(), -}; - -export type PlaylistQueryBuilderRef = { - getFilters: () => { - extraFilters: { - limit?: number; - sortBy?: string; - sortOrder?: string; - }; - filters: QueryBuilderGroup; - }; -}; - -export const PlaylistQueryBuilder = forwardRef( - ( - { sortOrder, sortBy, limit, isSaving, query, onSave, onSaveAs }: PlaylistQueryBuilderProps, - ref: Ref<PlaylistQueryBuilderRef>, - ) => { - const [filters, setFilters] = useState<QueryBuilderGroup>( - query ? convertNDQueryToQueryGroup(query) : DEFAULT_QUERY, - ); - - const extraFiltersForm = useForm({ - initialValues: { - limit, - sortBy, - sortOrder, - }, - }); - - useImperativeHandle(ref, () => ({ - getFilters: () => ({ - extraFilters: extraFiltersForm.values, - filters, - }), - })); - - const handleResetFilters = () => { - if (query) { - setFilters(convertNDQueryToQueryGroup(query)); - } else { - setFilters(DEFAULT_QUERY); - } - }; - - const handleClearFilters = () => { - setFilters(DEFAULT_QUERY); - }; - - const setFilterHandler = (newFilters: QueryBuilderGroup) => { - setFilters(newFilters); - }; - - const handleSave = () => { - onSave?.(convertQueryGroupToNDQuery(filters), extraFiltersForm.values); - }; - - const handleSaveAs = () => { - onSaveAs?.(convertQueryGroupToNDQuery(filters), extraFiltersForm.values); - }; - - const handleAddRuleGroup = (args: AddArgs) => { - const { level, groupIndex } = args; - const filtersCopy = clone(filters); - - const getPath = (level: number) => { - if (level === 0) return 'group'; - - const str = []; - for (const index of groupIndex) { - str.push(`group[${index}]`); - } - - return `${str.join('.')}.group`; - }; - - const path = getPath(level); - const updatedFilters = setWith( - filtersCopy, - path, - [ - ...get(filtersCopy, path), - { - group: [], - rules: [ - { - field: '', - operator: '', - uniqueId: nanoid(), - value: '', - }, - ], - type: 'any', - uniqueId: nanoid(), - }, - ], - clone, - ); - - setFilterHandler(updatedFilters); - }; - - const handleDeleteRuleGroup = (args: DeleteArgs) => { - const { uniqueId, level, groupIndex } = args; - const filtersCopy = clone(filters); - - const getPath = (level: number) => { - if (level === 0) return 'group'; - - const str = []; - for (let i = 0; i < groupIndex.length; i += 1) { - if (i !== groupIndex.length - 1) { - str.push(`group[${groupIndex[i]}]`); - } else { - str.push(`group`); - } - } - - return `${str.join('.')}`; - }; - - const path = getPath(level); - - const updatedFilters = setWith( - filtersCopy, - path, - [ - ...get(filtersCopy, path).filter( - (group: QueryBuilderGroup) => group.uniqueId !== uniqueId, - ), - ], - clone, - ); - - setFilterHandler(updatedFilters); - }; - - const getRulePath = (level: number, groupIndex: number[]) => { - if (level === 0) return 'rules'; - - const str = []; - for (const index of groupIndex) { - str.push(`group[${index}]`); - } - - return `${str.join('.')}.rules`; - }; - - const handleAddRule = (args: AddArgs) => { - const { level, groupIndex } = args; - const filtersCopy = clone(filters); - - const path = getRulePath(level, groupIndex); - const updatedFilters = setWith( - filtersCopy, - path, - [ - ...get(filtersCopy, path), - { + group: [], + rules: [ + { field: '', operator: '', uniqueId: nanoid(), - value: null, - }, - ], - clone, - ); - - setFilterHandler(updatedFilters); - }; - - const handleDeleteRule = (args: DeleteArgs) => { - const { uniqueId, level, groupIndex } = args; - const filtersCopy = clone(filters); - - const path = getRulePath(level, groupIndex); - const updatedFilters = setWith( - filtersCopy, - path, - get(filtersCopy, path).filter((rule: QueryBuilderRule) => rule.uniqueId !== uniqueId), - clone, - ); - - setFilterHandler(updatedFilters); - }; - - const handleChangeField = (args: any) => { - const { uniqueId, level, groupIndex, value } = args; - const filtersCopy = clone(filters); - - const path = getRulePath(level, groupIndex); - const updatedFilters = setWith( - filtersCopy, - path, - get(filtersCopy, path).map((rule: QueryBuilderGroup) => { - if (rule.uniqueId !== uniqueId) return rule; - return { - ...rule, - field: value, - operator: '', value: '', - }; - }), - clone, - ); - - setFilterHandler(updatedFilters); - }; - - const handleChangeType = (args: any) => { - const { level, groupIndex, value } = args; - - const filtersCopy = clone(filters); - - if (level === 0) { - return setFilterHandler({ ...filtersCopy, type: value }); - } - - const getTypePath = () => { - const str = []; - for (let i = 0; i < groupIndex.length; i += 1) { - str.push(`group[${groupIndex[i]}]`); - } - - return `${str.join('.')}`; - }; - - const path = getTypePath(); - const updatedFilters = setWith( - filtersCopy, - path, - { - ...get(filtersCopy, path), - type: value, }, - clone, - ); + ], + type: 'all' as 'all' | 'any', + uniqueId: nanoid(), +}; - return setFilterHandler(updatedFilters); +export type PlaylistQueryBuilderRef = { + getFilters: () => { + extraFilters: { + limit?: number; + sortBy?: string; + sortOrder?: string; + }; + filters: QueryBuilderGroup; }; +}; - const handleChangeOperator = (args: any) => { - const { uniqueId, level, groupIndex, value } = args; - const filtersCopy = clone(filters); +export const PlaylistQueryBuilder = forwardRef( + ( + { sortOrder, sortBy, limit, isSaving, query, onSave, onSaveAs }: PlaylistQueryBuilderProps, + ref: Ref<PlaylistQueryBuilderRef>, + ) => { + const [filters, setFilters] = useState<QueryBuilderGroup>( + query ? convertNDQueryToQueryGroup(query) : DEFAULT_QUERY, + ); - const path = getRulePath(level, groupIndex); - const updatedFilters = setWith( - filtersCopy, - path, - get(filtersCopy, path).map((rule: QueryBuilderRule) => { - if (rule.uniqueId !== uniqueId) return rule; - return { - ...rule, - operator: value, - }; - }), - clone, - ); + const extraFiltersForm = useForm({ + initialValues: { + limit, + sortBy, + sortOrder, + }, + }); - setFilterHandler(updatedFilters); - }; + useImperativeHandle(ref, () => ({ + getFilters: () => ({ + extraFilters: extraFiltersForm.values, + filters, + }), + })); - const handleChangeValue = (args: any) => { - const { uniqueId, level, groupIndex, value } = args; - const filtersCopy = clone(filters); + const handleResetFilters = () => { + if (query) { + setFilters(convertNDQueryToQueryGroup(query)); + } else { + setFilters(DEFAULT_QUERY); + } + }; - const path = getRulePath(level, groupIndex); - const updatedFilters = setWith( - filtersCopy, - path, - get(filtersCopy, path).map((rule: QueryBuilderRule) => { - if (rule.uniqueId !== uniqueId) return rule; - return { - ...rule, - value, - }; - }), - clone, - ); + const handleClearFilters = () => { + setFilters(DEFAULT_QUERY); + }; - setFilterHandler(updatedFilters); - }; + const setFilterHandler = (newFilters: QueryBuilderGroup) => { + setFilters(newFilters); + }; - const sortOptions = [ - { label: 'Random', type: 'string', value: 'random' }, - ...NDSongQueryFields, - ]; + const handleSave = () => { + onSave?.(convertQueryGroupToNDQuery(filters), extraFiltersForm.values); + }; - return ( - <MotionFlex - direction="column" - h="calc(100% - 2.5rem)" - justify="space-between" - > - <ScrollArea - h="100%" - p="1rem" - > - <QueryBuilder - data={filters} - filters={NDSongQueryFields} - groupIndex={[]} - level={0} - operators={{ - boolean: NDSongQueryBooleanOperators, - date: NDSongQueryDateOperators, - number: NDSongQueryNumberOperators, - string: NDSongQueryStringOperators, - }} - uniqueId={filters.uniqueId} - onAddRule={handleAddRule} - onAddRuleGroup={handleAddRuleGroup} - onChangeField={handleChangeField} - onChangeOperator={handleChangeOperator} - onChangeType={handleChangeType} - onChangeValue={handleChangeValue} - onClearFilters={handleClearFilters} - onDeleteRule={handleDeleteRule} - onDeleteRuleGroup={handleDeleteRuleGroup} - onResetFilters={handleResetFilters} - /> - </ScrollArea> - <Group - noWrap - align="flex-end" - m="1rem" - position="apart" - > - <Group - noWrap - spacing="sm" - w="100%" - > - <Select - searchable - data={sortOptions} - label="Sort" - maxWidth="20%" - width={150} - {...extraFiltersForm.getInputProps('sortBy')} - /> - <Select - data={[ + const handleSaveAs = () => { + onSaveAs?.(convertQueryGroupToNDQuery(filters), extraFiltersForm.values); + }; + + const handleAddRuleGroup = (args: AddArgs) => { + const { level, groupIndex } = args; + const filtersCopy = clone(filters); + + const getPath = (level: number) => { + if (level === 0) return 'group'; + + const str = []; + for (const index of groupIndex) { + str.push(`group[${index}]`); + } + + return `${str.join('.')}.group`; + }; + + const path = getPath(level); + const updatedFilters = setWith( + filtersCopy, + path, + [ + ...get(filtersCopy, path), + { + group: [], + rules: [ + { + field: '', + operator: '', + uniqueId: nanoid(), + value: '', + }, + ], + type: 'any', + uniqueId: nanoid(), + }, + ], + clone, + ); + + setFilterHandler(updatedFilters); + }; + + const handleDeleteRuleGroup = (args: DeleteArgs) => { + const { uniqueId, level, groupIndex } = args; + const filtersCopy = clone(filters); + + const getPath = (level: number) => { + if (level === 0) return 'group'; + + const str = []; + for (let i = 0; i < groupIndex.length; i += 1) { + if (i !== groupIndex.length - 1) { + str.push(`group[${groupIndex[i]}]`); + } else { + str.push(`group`); + } + } + + return `${str.join('.')}`; + }; + + const path = getPath(level); + + const updatedFilters = setWith( + filtersCopy, + path, + [ + ...get(filtersCopy, path).filter( + (group: QueryBuilderGroup) => group.uniqueId !== uniqueId, + ), + ], + clone, + ); + + setFilterHandler(updatedFilters); + }; + + const getRulePath = (level: number, groupIndex: number[]) => { + if (level === 0) return 'rules'; + + const str = []; + for (const index of groupIndex) { + str.push(`group[${index}]`); + } + + return `${str.join('.')}.rules`; + }; + + const handleAddRule = (args: AddArgs) => { + const { level, groupIndex } = args; + const filtersCopy = clone(filters); + + const path = getRulePath(level, groupIndex); + const updatedFilters = setWith( + filtersCopy, + path, + [ + ...get(filtersCopy, path), + { + field: '', + operator: '', + uniqueId: nanoid(), + value: null, + }, + ], + clone, + ); + + setFilterHandler(updatedFilters); + }; + + const handleDeleteRule = (args: DeleteArgs) => { + const { uniqueId, level, groupIndex } = args; + const filtersCopy = clone(filters); + + const path = getRulePath(level, groupIndex); + const updatedFilters = setWith( + filtersCopy, + path, + get(filtersCopy, path).filter( + (rule: QueryBuilderRule) => rule.uniqueId !== uniqueId, + ), + clone, + ); + + setFilterHandler(updatedFilters); + }; + + const handleChangeField = (args: any) => { + const { uniqueId, level, groupIndex, value } = args; + const filtersCopy = clone(filters); + + const path = getRulePath(level, groupIndex); + const updatedFilters = setWith( + filtersCopy, + path, + get(filtersCopy, path).map((rule: QueryBuilderGroup) => { + if (rule.uniqueId !== uniqueId) return rule; + return { + ...rule, + field: value, + operator: '', + value: '', + }; + }), + clone, + ); + + setFilterHandler(updatedFilters); + }; + + const handleChangeType = (args: any) => { + const { level, groupIndex, value } = args; + + const filtersCopy = clone(filters); + + if (level === 0) { + return setFilterHandler({ ...filtersCopy, type: value }); + } + + const getTypePath = () => { + const str = []; + for (let i = 0; i < groupIndex.length; i += 1) { + str.push(`group[${groupIndex[i]}]`); + } + + return `${str.join('.')}`; + }; + + const path = getTypePath(); + const updatedFilters = setWith( + filtersCopy, + path, { - label: 'Ascending', - value: 'asc', + ...get(filtersCopy, path), + type: value, }, - { - label: 'Descending', - value: 'desc', - }, - ]} - label="Order" - maxWidth="20%" - width={125} - {...extraFiltersForm.getInputProps('sortOrder')} - /> - <NumberInput - label="Limit" - maxWidth="20%" - width={75} - {...extraFiltersForm.getInputProps('limit')} - /> - </Group> - {onSave && onSaveAs && ( - <Group - noWrap - spacing="sm" + clone, + ); + + return setFilterHandler(updatedFilters); + }; + + const handleChangeOperator = (args: any) => { + const { uniqueId, level, groupIndex, value } = args; + const filtersCopy = clone(filters); + + const path = getRulePath(level, groupIndex); + const updatedFilters = setWith( + filtersCopy, + path, + get(filtersCopy, path).map((rule: QueryBuilderRule) => { + if (rule.uniqueId !== uniqueId) return rule; + return { + ...rule, + operator: value, + }; + }), + clone, + ); + + setFilterHandler(updatedFilters); + }; + + const handleChangeValue = (args: any) => { + const { uniqueId, level, groupIndex, value } = args; + const filtersCopy = clone(filters); + + const path = getRulePath(level, groupIndex); + const updatedFilters = setWith( + filtersCopy, + path, + get(filtersCopy, path).map((rule: QueryBuilderRule) => { + if (rule.uniqueId !== uniqueId) return rule; + return { + ...rule, + value, + }; + }), + clone, + ); + + setFilterHandler(updatedFilters); + }; + + const sortOptions = [ + { label: 'Random', type: 'string', value: 'random' }, + ...NDSongQueryFields, + ]; + + return ( + <MotionFlex + direction="column" + h="calc(100% - 2.5rem)" + justify="space-between" > - <Button - loading={isSaving} - variant="filled" - onClick={handleSaveAs} - > - Save as - </Button> - <DropdownMenu position="bottom-end"> - <DropdownMenu.Target> - <Button - disabled={isSaving} - p="0.5em" - variant="default" - > - <RiMore2Fill size={15} /> - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - <DropdownMenu.Item - $danger - icon={<RiSaveLine color="var(--danger-color)" />} - onClick={handleSave} - > - Save and replace - </DropdownMenu.Item> - </DropdownMenu.Dropdown> - </DropdownMenu> - </Group> - )} - </Group> - </MotionFlex> - ); - }, + <ScrollArea + h="100%" + p="1rem" + > + <QueryBuilder + data={filters} + filters={NDSongQueryFields} + groupIndex={[]} + level={0} + operators={{ + boolean: NDSongQueryBooleanOperators, + date: NDSongQueryDateOperators, + number: NDSongQueryNumberOperators, + string: NDSongQueryStringOperators, + }} + uniqueId={filters.uniqueId} + onAddRule={handleAddRule} + onAddRuleGroup={handleAddRuleGroup} + onChangeField={handleChangeField} + onChangeOperator={handleChangeOperator} + onChangeType={handleChangeType} + onChangeValue={handleChangeValue} + onClearFilters={handleClearFilters} + onDeleteRule={handleDeleteRule} + onDeleteRuleGroup={handleDeleteRuleGroup} + onResetFilters={handleResetFilters} + /> + </ScrollArea> + <Group + noWrap + align="flex-end" + m="1rem" + position="apart" + > + <Group + noWrap + spacing="sm" + w="100%" + > + <Select + searchable + data={sortOptions} + label="Sort" + maxWidth="20%" + width={150} + {...extraFiltersForm.getInputProps('sortBy')} + /> + <Select + data={[ + { + label: 'Ascending', + value: 'asc', + }, + { + label: 'Descending', + value: 'desc', + }, + ]} + label="Order" + maxWidth="20%" + width={125} + {...extraFiltersForm.getInputProps('sortOrder')} + /> + <NumberInput + label="Limit" + maxWidth="20%" + width={75} + {...extraFiltersForm.getInputProps('limit')} + /> + </Group> + {onSave && onSaveAs && ( + <Group + noWrap + spacing="sm" + > + <Button + loading={isSaving} + variant="filled" + onClick={handleSaveAs} + > + Save as + </Button> + <DropdownMenu position="bottom-end"> + <DropdownMenu.Target> + <Button + disabled={isSaving} + p="0.5em" + variant="default" + > + <RiMore2Fill size={15} /> + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + <DropdownMenu.Item + $danger + icon={<RiSaveLine color="var(--danger-color)" />} + onClick={handleSave} + > + Save and replace + </DropdownMenu.Item> + </DropdownMenu.Dropdown> + </DropdownMenu> + </Group> + )} + </Group> + </MotionFlex> + ); + }, ); diff --git a/src/renderer/features/playlists/components/save-as-playlist-form.tsx b/src/renderer/features/playlists/components/save-as-playlist-form.tsx index 7ce0246a..a0f87d08 100644 --- a/src/renderer/features/playlists/components/save-as-playlist-form.tsx +++ b/src/renderer/features/playlists/components/save-as-playlist-form.tsx @@ -6,90 +6,90 @@ import { useCreatePlaylist } from '/@/renderer/features/playlists/mutations/crea import { useCurrentServer } from '/@/renderer/store'; interface SaveAsPlaylistFormProps { - body: Partial<CreatePlaylistBody>; - onCancel: () => void; - onSuccess: (data: CreatePlaylistResponse) => void; - serverId: string | undefined; + body: Partial<CreatePlaylistBody>; + onCancel: () => void; + onSuccess: (data: CreatePlaylistResponse) => void; + serverId: string | undefined; } export const SaveAsPlaylistForm = ({ - body, - serverId, - onSuccess, - onCancel, + body, + serverId, + onSuccess, + onCancel, }: SaveAsPlaylistFormProps) => { - const mutation = useCreatePlaylist({}); - const server = useCurrentServer(); + const mutation = useCreatePlaylist({}); + const server = useCurrentServer(); - const form = useForm<CreatePlaylistBody>({ - initialValues: { - _custom: { - navidrome: { - public: false, - rules: undefined, - ...body?._custom?.navidrome, + const form = useForm<CreatePlaylistBody>({ + initialValues: { + _custom: { + navidrome: { + public: false, + rules: undefined, + ...body?._custom?.navidrome, + }, + }, + comment: body.comment || '', + name: body.name || '', }, - }, - comment: body.comment || '', - name: body.name || '', - }, - }); + }); - const handleSubmit = form.onSubmit((values) => { - mutation.mutate( - { body: values, serverId }, - { - onError: (err) => { - toast.error({ message: err.message, title: 'Error creating playlist' }); - }, - onSuccess: (data) => { - toast.success({ message: `Playlist has been created` }); - onSuccess(data); - onCancel(); - }, - }, + const handleSubmit = form.onSubmit((values) => { + mutation.mutate( + { body: values, serverId }, + { + onError: (err) => { + toast.error({ message: err.message, title: 'Error creating playlist' }); + }, + onSuccess: (data) => { + toast.success({ message: `Playlist has been created` }); + onSuccess(data); + onCancel(); + }, + }, + ); + }); + + const isPublicDisplayed = server?.type === ServerType.NAVIDROME; + const isSubmitDisabled = !form.values.name || mutation.isLoading; + + return ( + <form onSubmit={handleSubmit}> + <Stack> + <TextInput + data-autofocus + required + label="Name" + {...form.getInputProps('name')} + /> + <TextInput + label="Description" + {...form.getInputProps('comment')} + /> + {isPublicDisplayed && ( + <Switch + label="Is Public?" + {...form.getInputProps('_custom.navidrome.public', { type: 'checkbox' })} + /> + )} + <Group position="right"> + <Button + variant="subtle" + onClick={onCancel} + > + Cancel + </Button> + <Button + disabled={isSubmitDisabled} + loading={mutation.isLoading} + type="submit" + variant="filled" + > + Save + </Button> + </Group> + </Stack> + </form> ); - }); - - const isPublicDisplayed = server?.type === ServerType.NAVIDROME; - const isSubmitDisabled = !form.values.name || mutation.isLoading; - - return ( - <form onSubmit={handleSubmit}> - <Stack> - <TextInput - data-autofocus - required - label="Name" - {...form.getInputProps('name')} - /> - <TextInput - label="Description" - {...form.getInputProps('comment')} - /> - {isPublicDisplayed && ( - <Switch - label="Is Public?" - {...form.getInputProps('_custom.navidrome.public', { type: 'checkbox' })} - /> - )} - <Group position="right"> - <Button - variant="subtle" - onClick={onCancel} - > - Cancel - </Button> - <Button - disabled={isSubmitDisabled} - loading={mutation.isLoading} - type="submit" - variant="filled" - > - Save - </Button> - </Group> - </Stack> - </form> - ); }; diff --git a/src/renderer/features/playlists/components/update-playlist-form.tsx b/src/renderer/features/playlists/components/update-playlist-form.tsx index 7ed33a88..9f5ca6f6 100644 --- a/src/renderer/features/playlists/components/update-playlist-form.tsx +++ b/src/renderer/features/playlists/components/update-playlist-form.tsx @@ -4,15 +4,15 @@ import { openModal, closeAllModals } from '@mantine/modals'; import { api } from '/@/renderer/api'; import { queryKeys } from '/@/renderer/api/query-keys'; import { - PlaylistDetailResponse, - ServerListItem, - ServerType, - SortOrder, - UpdatePlaylistBody, - UpdatePlaylistQuery, - User, - UserListQuery, - UserListSort, + PlaylistDetailResponse, + ServerListItem, + ServerType, + SortOrder, + UpdatePlaylistBody, + UpdatePlaylistQuery, + User, + UserListQuery, + UserListSort, } from '/@/renderer/api/types'; import { Button, Select, Switch, TextInput, toast } from '/@/renderer/components'; import { useUpdatePlaylist } from '/@/renderer/features/playlists/mutations/update-playlist-mutation'; @@ -20,146 +20,146 @@ import { queryClient } from '/@/renderer/lib/react-query'; import { useCurrentServer } from '/@/renderer/store'; interface UpdatePlaylistFormProps { - body: Partial<UpdatePlaylistBody>; - onCancel: () => void; - query: UpdatePlaylistQuery; - users?: User[]; + body: Partial<UpdatePlaylistBody>; + onCancel: () => void; + query: UpdatePlaylistQuery; + users?: User[]; } export const UpdatePlaylistForm = ({ users, query, body, onCancel }: UpdatePlaylistFormProps) => { - const mutation = useUpdatePlaylist({}); - const server = useCurrentServer(); + const mutation = useUpdatePlaylist({}); + const server = useCurrentServer(); - const userList = users?.map((user) => ({ - label: user.name, - value: user.id, - })); + const userList = users?.map((user) => ({ + label: user.name, + value: user.id, + })); - const form = useForm<UpdatePlaylistBody>({ - initialValues: { - _custom: { - navidrome: { - owner: body?._custom?.navidrome?.owner || '', - ownerId: body?._custom?.navidrome?.ownerId || '', - public: body?._custom?.navidrome?.public || false, - rules: undefined, - sync: body?._custom?.navidrome?.sync || false, + const form = useForm<UpdatePlaylistBody>({ + initialValues: { + _custom: { + navidrome: { + owner: body?._custom?.navidrome?.owner || '', + ownerId: body?._custom?.navidrome?.ownerId || '', + public: body?._custom?.navidrome?.public || false, + rules: undefined, + sync: body?._custom?.navidrome?.sync || false, + }, + }, + comment: body?.comment || '', + name: body?.name || '', }, - }, - comment: body?.comment || '', - name: body?.name || '', - }, - }); + }); - const handleSubmit = form.onSubmit((values) => { - mutation.mutate( - { - body: values, - query, - serverId: server?.id, - }, - { - onError: (err) => { - toast.error({ message: err.message, title: 'Error updating playlist' }); - }, - onSuccess: () => { - toast.success({ message: `Playlist has been saved` }); - onCancel(); - }, - }, + const handleSubmit = form.onSubmit((values) => { + mutation.mutate( + { + body: values, + query, + serverId: server?.id, + }, + { + onError: (err) => { + toast.error({ message: err.message, title: 'Error updating playlist' }); + }, + onSuccess: () => { + toast.success({ message: `Playlist has been saved` }); + onCancel(); + }, + }, + ); + }); + + const isPublicDisplayed = server?.type === ServerType.NAVIDROME; + const isSubmitDisabled = !form.values.name || mutation.isLoading; + + return ( + <form onSubmit={handleSubmit}> + <Stack> + <TextInput + data-autofocus + required + label="Name" + {...form.getInputProps('name')} + /> + <TextInput + label="Description" + {...form.getInputProps('comment')} + /> + <Select + data={userList || []} + {...form.getInputProps('_custom.navidrome.ownerId')} + label="Owner" + /> + {isPublicDisplayed && ( + <Switch + label="Is Public?" + {...form.getInputProps('_custom.navidrome.public', { type: 'checkbox' })} + /> + )} + <Group position="right"> + <Button + variant="subtle" + onClick={onCancel} + > + Cancel + </Button> + <Button + disabled={isSubmitDisabled} + loading={mutation.isLoading} + type="submit" + variant="filled" + > + Save + </Button> + </Group> + </Stack> + </form> ); - }); - - const isPublicDisplayed = server?.type === ServerType.NAVIDROME; - const isSubmitDisabled = !form.values.name || mutation.isLoading; - - return ( - <form onSubmit={handleSubmit}> - <Stack> - <TextInput - data-autofocus - required - label="Name" - {...form.getInputProps('name')} - /> - <TextInput - label="Description" - {...form.getInputProps('comment')} - /> - <Select - data={userList || []} - {...form.getInputProps('_custom.navidrome.ownerId')} - label="Owner" - /> - {isPublicDisplayed && ( - <Switch - label="Is Public?" - {...form.getInputProps('_custom.navidrome.public', { type: 'checkbox' })} - /> - )} - <Group position="right"> - <Button - variant="subtle" - onClick={onCancel} - > - Cancel - </Button> - <Button - disabled={isSubmitDisabled} - loading={mutation.isLoading} - type="submit" - variant="filled" - > - Save - </Button> - </Group> - </Stack> - </form> - ); }; export const openUpdatePlaylistModal = async (args: { - playlist: PlaylistDetailResponse; - server: ServerListItem; + playlist: PlaylistDetailResponse; + server: ServerListItem; }) => { - const { playlist, server } = args; + const { playlist, server } = args; - const query: UserListQuery = { - sortBy: UserListSort.NAME, - sortOrder: SortOrder.ASC, - startIndex: 0, - }; + const query: UserListQuery = { + sortBy: UserListSort.NAME, + sortOrder: SortOrder.ASC, + startIndex: 0, + }; - if (!server) return; + if (!server) return; - const users = await queryClient.fetchQuery({ - queryFn: ({ signal }) => - api.controller.getUserList({ apiClientProps: { server, signal }, query }), - queryKey: queryKeys.users.list(server?.id || '', query), - }); + const users = await queryClient.fetchQuery({ + queryFn: ({ signal }) => + api.controller.getUserList({ apiClientProps: { server, signal }, query }), + queryKey: queryKeys.users.list(server?.id || '', query), + }); - openModal({ - children: ( - <UpdatePlaylistForm - body={{ - _custom: { - navidrome: { - owner: playlist?.owner || undefined, - ownerId: playlist?.ownerId || undefined, - public: playlist?.public || false, - rules: playlist?.rules || undefined, - sync: playlist?.sync || undefined, - }, - }, - comment: playlist?.description || undefined, - genres: playlist?.genres, - name: playlist?.name, - }} - query={{ id: playlist?.id }} - users={users?.items} - onCancel={closeAllModals} - /> - ), - title: 'Edit playlist', - }); + openModal({ + children: ( + <UpdatePlaylistForm + body={{ + _custom: { + navidrome: { + owner: playlist?.owner || undefined, + ownerId: playlist?.ownerId || undefined, + public: playlist?.public || false, + rules: playlist?.rules || undefined, + sync: playlist?.sync || undefined, + }, + }, + comment: playlist?.description || undefined, + genres: playlist?.genres, + name: playlist?.name, + }} + query={{ id: playlist?.id }} + users={users?.items} + onCancel={closeAllModals} + /> + ), + title: 'Edit playlist', + }); }; diff --git a/src/renderer/features/playlists/mutations/add-to-playlist-mutation.ts b/src/renderer/features/playlists/mutations/add-to-playlist-mutation.ts index ecf63ce8..3f1b5eb4 100644 --- a/src/renderer/features/playlists/mutations/add-to-playlist-mutation.ts +++ b/src/renderer/features/playlists/mutations/add-to-playlist-mutation.ts @@ -7,31 +7,31 @@ import { MutationHookArgs } from '/@/renderer/lib/react-query'; import { getServerById } from '/@/renderer/store'; export const useAddToPlaylist = (args: MutationHookArgs) => { - const { options } = args || {}; - const queryClient = useQueryClient(); + const { options } = args || {}; + const queryClient = useQueryClient(); - return useMutation< - AddToPlaylistResponse, - AxiosError, - Omit<AddToPlaylistArgs, 'server' | 'apiClientProps'>, - null - >({ - mutationFn: (args) => { - const server = getServerById(args.serverId); - if (!server) throw new Error('Server not found'); - return api.controller.addToPlaylist({ ...args, apiClientProps: { server } }); - }, - onSuccess: (_data, variables) => { - const { serverId } = variables; + return useMutation< + AddToPlaylistResponse, + AxiosError, + Omit<AddToPlaylistArgs, 'server' | 'apiClientProps'>, + null + >({ + mutationFn: (args) => { + const server = getServerById(args.serverId); + if (!server) throw new Error('Server not found'); + return api.controller.addToPlaylist({ ...args, apiClientProps: { server } }); + }, + onSuccess: (_data, variables) => { + const { serverId } = variables; - if (!serverId) return; + if (!serverId) return; - queryClient.invalidateQueries(queryKeys.playlists.list(serverId), { exact: false }); - queryClient.invalidateQueries(queryKeys.playlists.detail(serverId, variables.query.id)); - queryClient.invalidateQueries( - queryKeys.playlists.detailSongList(serverId, variables.query.id), - ); - }, - ...options, - }); + queryClient.invalidateQueries(queryKeys.playlists.list(serverId), { exact: false }); + queryClient.invalidateQueries(queryKeys.playlists.detail(serverId, variables.query.id)); + queryClient.invalidateQueries( + queryKeys.playlists.detailSongList(serverId, variables.query.id), + ); + }, + ...options, + }); }; diff --git a/src/renderer/features/playlists/mutations/create-playlist-mutation.ts b/src/renderer/features/playlists/mutations/create-playlist-mutation.ts index 98f0b1ee..799b2b50 100644 --- a/src/renderer/features/playlists/mutations/create-playlist-mutation.ts +++ b/src/renderer/features/playlists/mutations/create-playlist-mutation.ts @@ -7,26 +7,26 @@ import { AxiosError } from 'axios'; import { queryKeys } from '../../../api/query-keys'; export const useCreatePlaylist = (args: MutationHookArgs) => { - const { options } = args || {}; - const queryClient = useQueryClient(); + const { options } = args || {}; + const queryClient = useQueryClient(); - return useMutation< - CreatePlaylistResponse, - AxiosError, - Omit<CreatePlaylistArgs, 'server' | 'apiClientProps'>, - null - >({ - mutationFn: (args) => { - const server = getServerById(args.serverId); - if (!server) throw new Error('Server not found'); - return api.controller.createPlaylist({ ...args, apiClientProps: { server } }); - }, - onSuccess: (_args, variables) => { - const server = getServerById(variables.serverId); - if (server) { - queryClient.invalidateQueries(queryKeys.playlists.list(server.id)); - } - }, - ...options, - }); + return useMutation< + CreatePlaylistResponse, + AxiosError, + Omit<CreatePlaylistArgs, 'server' | 'apiClientProps'>, + null + >({ + mutationFn: (args) => { + const server = getServerById(args.serverId); + if (!server) throw new Error('Server not found'); + return api.controller.createPlaylist({ ...args, apiClientProps: { server } }); + }, + onSuccess: (_args, variables) => { + const server = getServerById(variables.serverId); + if (server) { + queryClient.invalidateQueries(queryKeys.playlists.list(server.id)); + } + }, + ...options, + }); }; diff --git a/src/renderer/features/playlists/mutations/delete-playlist-mutation.ts b/src/renderer/features/playlists/mutations/delete-playlist-mutation.ts index d343dc8b..4f6a3cf0 100644 --- a/src/renderer/features/playlists/mutations/delete-playlist-mutation.ts +++ b/src/renderer/features/playlists/mutations/delete-playlist-mutation.ts @@ -7,28 +7,28 @@ import { MutationHookArgs } from '/@/renderer/lib/react-query'; import { getServerById, useCurrentServer } from '/@/renderer/store'; export const useDeletePlaylist = (args: MutationHookArgs) => { - const { options } = args || {}; - const queryClient = useQueryClient(); - const server = useCurrentServer(); + const { options } = args || {}; + const queryClient = useQueryClient(); + const server = useCurrentServer(); - return useMutation< - DeletePlaylistResponse, - AxiosError, - Omit<DeletePlaylistArgs, 'server' | 'apiClientProps'>, - null - >({ - mutationFn: (args) => { - const server = getServerById(args.serverId); - if (!server) throw new Error('Server not found'); - return api.controller.deletePlaylist({ ...args, apiClientProps: { server } }); - }, - onMutate: () => { - queryClient.cancelQueries(queryKeys.playlists.list(server?.id || '')); - return null; - }, - onSuccess: () => { - queryClient.invalidateQueries(queryKeys.playlists.list(server?.id || '')); - }, - ...options, - }); + return useMutation< + DeletePlaylistResponse, + AxiosError, + Omit<DeletePlaylistArgs, 'server' | 'apiClientProps'>, + null + >({ + mutationFn: (args) => { + const server = getServerById(args.serverId); + if (!server) throw new Error('Server not found'); + return api.controller.deletePlaylist({ ...args, apiClientProps: { server } }); + }, + onMutate: () => { + queryClient.cancelQueries(queryKeys.playlists.list(server?.id || '')); + return null; + }, + onSuccess: () => { + queryClient.invalidateQueries(queryKeys.playlists.list(server?.id || '')); + }, + ...options, + }); }; diff --git a/src/renderer/features/playlists/mutations/remove-from-playlist-mutation.ts b/src/renderer/features/playlists/mutations/remove-from-playlist-mutation.ts index b5175252..22d5da94 100644 --- a/src/renderer/features/playlists/mutations/remove-from-playlist-mutation.ts +++ b/src/renderer/features/playlists/mutations/remove-from-playlist-mutation.ts @@ -7,30 +7,30 @@ import { MutationOptions } from '/@/renderer/lib/react-query'; import { getServerById } from '/@/renderer/store'; export const useRemoveFromPlaylist = (options?: MutationOptions) => { - const queryClient = useQueryClient(); + const queryClient = useQueryClient(); - return useMutation< - RemoveFromPlaylistResponse, - AxiosError, - Omit<RemoveFromPlaylistArgs, 'server' | 'apiClientProps'>, - null - >({ - mutationFn: (args) => { - const server = getServerById(args.serverId); - if (!server) throw new Error('Server not found'); - return api.controller.removeFromPlaylist({ ...args, apiClientProps: { server } }); - }, - onSuccess: (_data, variables) => { - const { serverId } = variables; + return useMutation< + RemoveFromPlaylistResponse, + AxiosError, + Omit<RemoveFromPlaylistArgs, 'server' | 'apiClientProps'>, + null + >({ + mutationFn: (args) => { + const server = getServerById(args.serverId); + if (!server) throw new Error('Server not found'); + return api.controller.removeFromPlaylist({ ...args, apiClientProps: { server } }); + }, + onSuccess: (_data, variables) => { + const { serverId } = variables; - if (!serverId) return; + if (!serverId) return; - queryClient.invalidateQueries(queryKeys.playlists.list(serverId), { exact: false }); - queryClient.invalidateQueries(queryKeys.playlists.detail(serverId, variables.query.id)); - queryClient.invalidateQueries( - queryKeys.playlists.detailSongList(serverId, variables.query.id), - ); - }, - ...options, - }); + queryClient.invalidateQueries(queryKeys.playlists.list(serverId), { exact: false }); + queryClient.invalidateQueries(queryKeys.playlists.detail(serverId, variables.query.id)); + queryClient.invalidateQueries( + queryKeys.playlists.detailSongList(serverId, variables.query.id), + ); + }, + ...options, + }); }; diff --git a/src/renderer/features/playlists/mutations/update-playlist-mutation.ts b/src/renderer/features/playlists/mutations/update-playlist-mutation.ts index 4d706d05..ef657013 100644 --- a/src/renderer/features/playlists/mutations/update-playlist-mutation.ts +++ b/src/renderer/features/playlists/mutations/update-playlist-mutation.ts @@ -7,31 +7,31 @@ import { MutationHookArgs } from '/@/renderer/lib/react-query'; import { getServerById } from '/@/renderer/store'; export const useUpdatePlaylist = (args: MutationHookArgs) => { - const { options } = args || {}; - const queryClient = useQueryClient(); + const { options } = args || {}; + const queryClient = useQueryClient(); - return useMutation< - UpdatePlaylistResponse, - AxiosError, - Omit<UpdatePlaylistArgs, 'server' | 'apiClientProps'>, - null - >({ - mutationFn: (args) => { - const server = getServerById(args.serverId); - if (!server) throw new Error('Server not found'); - return api.controller.updatePlaylist({ ...args, apiClientProps: { server } }); - }, - onSuccess: (_data, variables) => { - const { query, serverId } = variables; + return useMutation< + UpdatePlaylistResponse, + AxiosError, + Omit<UpdatePlaylistArgs, 'server' | 'apiClientProps'>, + null + >({ + mutationFn: (args) => { + const server = getServerById(args.serverId); + if (!server) throw new Error('Server not found'); + return api.controller.updatePlaylist({ ...args, apiClientProps: { server } }); + }, + onSuccess: (_data, variables) => { + const { query, serverId } = variables; - if (!serverId) return; + if (!serverId) return; - queryClient.invalidateQueries(queryKeys.playlists.list(serverId)); + queryClient.invalidateQueries(queryKeys.playlists.list(serverId)); - if (query?.id) { - queryClient.invalidateQueries(queryKeys.playlists.detail(serverId, query.id)); - } - }, - ...options, - }); + if (query?.id) { + queryClient.invalidateQueries(queryKeys.playlists.detail(serverId, query.id)); + } + }, + ...options, + }); }; diff --git a/src/renderer/features/playlists/queries/playlist-detail-query.ts b/src/renderer/features/playlists/queries/playlist-detail-query.ts index 8876ef24..fc614dbc 100644 --- a/src/renderer/features/playlists/queries/playlist-detail-query.ts +++ b/src/renderer/features/playlists/queries/playlist-detail-query.ts @@ -6,16 +6,16 @@ import { getServerById } from '/@/renderer/store'; import { api } from '/@/renderer/api'; export const usePlaylistDetail = (args: QueryHookArgs<PlaylistDetailQuery>) => { - const { options, query, serverId } = args || {}; - const server = getServerById(serverId); + const { options, query, serverId } = args || {}; + const server = getServerById(serverId); - return useQuery({ - enabled: !!server?.id, - queryFn: ({ signal }) => { - if (!server) throw new Error('Server not found'); - return api.controller.getPlaylistDetail({ apiClientProps: { server, signal }, query }); - }, - queryKey: queryKeys.playlists.detail(server?.id || '', query.id, query), - ...options, - }); + return useQuery({ + enabled: !!server?.id, + queryFn: ({ signal }) => { + if (!server) throw new Error('Server not found'); + return api.controller.getPlaylistDetail({ apiClientProps: { server, signal }, query }); + }, + queryKey: queryKeys.playlists.detail(server?.id || '', query.id, query), + ...options, + }); }; diff --git a/src/renderer/features/playlists/queries/playlist-list-query.ts b/src/renderer/features/playlists/queries/playlist-list-query.ts index b768fe63..797866c0 100644 --- a/src/renderer/features/playlists/queries/playlist-list-query.ts +++ b/src/renderer/features/playlists/queries/playlist-list-query.ts @@ -6,21 +6,21 @@ import { getServerById } from '/@/renderer/store'; import { api } from '/@/renderer/api'; export const usePlaylistList = (args: { - options?: QueryOptions; - query: PlaylistListQuery; - serverId?: string; + options?: QueryOptions; + query: PlaylistListQuery; + serverId?: string; }) => { - const { options, query, serverId } = args; - const server = getServerById(serverId); + const { options, query, serverId } = args; + const server = getServerById(serverId); - return useQuery({ - cacheTime: 1000 * 60 * 60, - enabled: !!server?.id, - queryFn: ({ signal }) => { - if (!server) throw new Error('Server not found'); - return api.controller.getPlaylistList({ apiClientProps: { server, signal }, query }); - }, - queryKey: queryKeys.playlists.list(server?.id || '', query), - ...options, - }); + return useQuery({ + cacheTime: 1000 * 60 * 60, + enabled: !!server?.id, + queryFn: ({ signal }) => { + if (!server) throw new Error('Server not found'); + return api.controller.getPlaylistList({ apiClientProps: { server, signal }, query }); + }, + queryKey: queryKeys.playlists.list(server?.id || '', query), + ...options, + }); }; diff --git a/src/renderer/features/playlists/queries/playlist-song-list-query.ts b/src/renderer/features/playlists/queries/playlist-song-list-query.ts index a18010e0..8d2699d7 100644 --- a/src/renderer/features/playlists/queries/playlist-song-list-query.ts +++ b/src/renderer/features/playlists/queries/playlist-song-list-query.ts @@ -6,41 +6,48 @@ import { getServerById } from '/@/renderer/store'; import { api } from '/@/renderer/api'; export const usePlaylistSongList = (args: QueryHookArgs<PlaylistSongListQuery>) => { - const { options, query, serverId } = args || {}; - const server = getServerById(serverId); + const { options, query, serverId } = args || {}; + const server = getServerById(serverId); - return useQuery({ - enabled: !!server, - queryFn: ({ signal }) => { - if (!server) throw new Error('Server not found'); - return api.controller.getPlaylistSongList({ apiClientProps: { server, signal }, query }); - }, - queryKey: queryKeys.playlists.songList(server?.id || '', query.id, query), - ...options, - }); + return useQuery({ + enabled: !!server, + queryFn: ({ signal }) => { + if (!server) throw new Error('Server not found'); + return api.controller.getPlaylistSongList({ + apiClientProps: { server, signal }, + query, + }); + }, + queryKey: queryKeys.playlists.songList(server?.id || '', query.id, query), + ...options, + }); }; export const usePlaylistSongListInfinite = (args: QueryHookArgs<PlaylistSongListQuery>) => { - const { options, query, serverId } = args || {}; - const server = getServerById(serverId); + const { options, query, serverId } = args || {}; + const server = getServerById(serverId); - return useInfiniteQuery({ - enabled: !!server, - getNextPageParam: (lastPage: PlaylistSongListResponse | undefined, pages) => { - if (!lastPage?.items) return undefined; - if (lastPage?.items?.length >= (query?.limit || 50)) { - return pages?.length; - } + return useInfiniteQuery({ + enabled: !!server, + getNextPageParam: (lastPage: PlaylistSongListResponse | undefined, pages) => { + if (!lastPage?.items) return undefined; + if (lastPage?.items?.length >= (query?.limit || 50)) { + return pages?.length; + } - return undefined; - }, - queryFn: ({ pageParam = 0, signal }) => { - return api.controller.getPlaylistSongList({ - apiClientProps: { server, signal }, - query: { ...query, limit: query.limit || 50, startIndex: pageParam * (query.limit || 50) }, - }); - }, - queryKey: queryKeys.playlists.detailSongList(server?.id || '', query.id, query), - ...options, - }); + return undefined; + }, + queryFn: ({ pageParam = 0, signal }) => { + return api.controller.getPlaylistSongList({ + apiClientProps: { server, signal }, + query: { + ...query, + limit: query.limit || 50, + startIndex: pageParam * (query.limit || 50), + }, + }); + }, + queryKey: queryKeys.playlists.detailSongList(server?.id || '', query.id, query), + ...options, + }); }; diff --git a/src/renderer/features/playlists/routes/playlist-detail-route.tsx b/src/renderer/features/playlists/routes/playlist-detail-route.tsx index 57391050..818c2873 100644 --- a/src/renderer/features/playlists/routes/playlist-detail-route.tsx +++ b/src/renderer/features/playlists/routes/playlist-detail-route.tsx @@ -13,59 +13,61 @@ import { usePlayButtonBehavior } from '/@/renderer/store/settings.store'; import { useCurrentServer } from '../../../store/auth.store'; const PlaylistDetailRoute = () => { - const tableRef = useRef<AgGridReactType | null>(null); - const scrollAreaRef = useRef<HTMLDivElement>(null); - const headerRef = useRef<HTMLDivElement>(null); - const { playlistId } = useParams() as { playlistId: string }; - const server = useCurrentServer(); + const tableRef = useRef<AgGridReactType | null>(null); + const scrollAreaRef = useRef<HTMLDivElement>(null); + const headerRef = useRef<HTMLDivElement>(null); + const { playlistId } = useParams() as { playlistId: string }; + const server = useCurrentServer(); - const detailQuery = usePlaylistDetail({ query: { id: playlistId }, serverId: server?.id }); - const background = useFastAverageColor( - detailQuery?.data?.imageUrl, - !detailQuery?.isLoading, - 'sqrt', - ); + const detailQuery = usePlaylistDetail({ query: { id: playlistId }, serverId: server?.id }); + const background = useFastAverageColor( + detailQuery?.data?.imageUrl, + !detailQuery?.isLoading, + 'sqrt', + ); - const handlePlayQueueAdd = usePlayQueueAdd(); - const playButtonBehavior = usePlayButtonBehavior(); + const handlePlayQueueAdd = usePlayQueueAdd(); + const playButtonBehavior = usePlayButtonBehavior(); - const handlePlay = () => { - handlePlayQueueAdd?.({ - byItemType: { - id: [playlistId], - type: LibraryItem.PLAYLIST, - }, - playType: playButtonBehavior, - }); - }; + const handlePlay = () => { + handlePlayQueueAdd?.({ + byItemType: { + id: [playlistId], + type: LibraryItem.PLAYLIST, + }, + playType: playButtonBehavior, + }); + }; - if (!background) return null; + if (!background) return null; - return ( - <AnimatedPage key={`playlist-detail-${playlistId}`}> - <NativeScrollArea - ref={scrollAreaRef} - pageHeaderProps={{ - backgroundColor: background, - children: ( - <LibraryHeaderBar> - <LibraryHeaderBar.PlayButton onClick={handlePlay} /> - <LibraryHeaderBar.Title>{detailQuery?.data?.name}</LibraryHeaderBar.Title> - </LibraryHeaderBar> - ), - target: headerRef, - }} - > - <PlaylistDetailHeader - ref={headerRef} - background={background} - imagePlaceholderUrl={detailQuery?.data?.imageUrl} - imageUrl={detailQuery?.data?.imageUrl} - /> - <PlaylistDetailContent tableRef={tableRef} /> - </NativeScrollArea> - </AnimatedPage> - ); + return ( + <AnimatedPage key={`playlist-detail-${playlistId}`}> + <NativeScrollArea + ref={scrollAreaRef} + pageHeaderProps={{ + backgroundColor: background, + children: ( + <LibraryHeaderBar> + <LibraryHeaderBar.PlayButton onClick={handlePlay} /> + <LibraryHeaderBar.Title> + {detailQuery?.data?.name} + </LibraryHeaderBar.Title> + </LibraryHeaderBar> + ), + target: headerRef, + }} + > + <PlaylistDetailHeader + ref={headerRef} + background={background} + imagePlaceholderUrl={detailQuery?.data?.imageUrl} + imageUrl={detailQuery?.data?.imageUrl} + /> + <PlaylistDetailContent tableRef={tableRef} /> + </NativeScrollArea> + </AnimatedPage> + ); }; export default PlaylistDetailRoute; diff --git a/src/renderer/features/playlists/routes/playlist-detail-song-list-route.tsx b/src/renderer/features/playlists/routes/playlist-detail-song-list-route.tsx index 2153e74e..50d15404 100644 --- a/src/renderer/features/playlists/routes/playlist-detail-song-list-route.tsx +++ b/src/renderer/features/playlists/routes/playlist-detail-song-list-route.tsx @@ -20,217 +20,228 @@ import { PlaylistSongListQuery, ServerType, SongListSort, SortOrder } from '/@/r import { usePlaylistSongList } from '/@/renderer/features/playlists/queries/playlist-song-list-query'; const PlaylistDetailSongListRoute = () => { - const navigate = useNavigate(); - const tableRef = useRef<AgGridReactType | null>(null); - const { playlistId } = useParams() as { playlistId: string }; - const server = useCurrentServer(); + const navigate = useNavigate(); + const tableRef = useRef<AgGridReactType | null>(null); + const { playlistId } = useParams() as { playlistId: string }; + const server = useCurrentServer(); - const detailQuery = usePlaylistDetail({ query: { id: playlistId }, serverId: server?.id }); - const createPlaylistMutation = useCreatePlaylist({}); - const deletePlaylistMutation = useDeletePlaylist({}); + const detailQuery = usePlaylistDetail({ query: { id: playlistId }, serverId: server?.id }); + const createPlaylistMutation = useCreatePlaylist({}); + const deletePlaylistMutation = useDeletePlaylist({}); - const handleSave = ( - filter: Record<string, any>, - extraFilters: { limit?: number; sortBy?: string; sortOrder?: string }, - ) => { - const rules = { - ...filter, - limit: extraFilters.limit || undefined, - order: extraFilters.sortOrder || 'desc', - sort: extraFilters.sortBy || 'dateAdded', + const handleSave = ( + filter: Record<string, any>, + extraFilters: { limit?: number; sortBy?: string; sortOrder?: string }, + ) => { + const rules = { + ...filter, + limit: extraFilters.limit || undefined, + order: extraFilters.sortOrder || 'desc', + sort: extraFilters.sortBy || 'dateAdded', + }; + + if (!detailQuery?.data) return; + + createPlaylistMutation.mutate( + { + body: { + _custom: { + navidrome: { + owner: detailQuery?.data?.owner || '', + ownerId: detailQuery?.data?.ownerId || '', + public: detailQuery?.data?.public || false, + rules, + sync: detailQuery?.data?.sync || false, + }, + }, + comment: detailQuery?.data?.description || '', + name: detailQuery?.data?.name, + }, + serverId: detailQuery?.data?.serverId, + }, + { + onSuccess: (data) => { + toast.success({ message: 'Playlist has been saved' }); + navigate( + generatePath(AppRoute.PLAYLISTS_DETAIL_SONGS, { + playlistId: data?.id || '', + }), + { + replace: true, + }, + ); + deletePlaylistMutation.mutate({ + query: { id: playlistId }, + serverId: detailQuery?.data?.serverId, + }); + }, + }, + ); }; - if (!detailQuery?.data) return; + const handleSaveAs = ( + filter: Record<string, any>, + extraFilters: { limit?: number; sortBy?: string; sortOrder?: string }, + ) => { + openModal({ + children: ( + <SaveAsPlaylistForm + body={{ + _custom: { + navidrome: { + owner: detailQuery?.data?.owner || '', + ownerId: detailQuery?.data?.ownerId || '', + public: detailQuery?.data?.public || false, + rules: { + ...filter, + limit: extraFilters.limit || undefined, + order: extraFilters.sortOrder || 'desc', + sort: extraFilters.sortBy || 'dateAdded', + }, + sync: detailQuery?.data?.sync || false, + }, + }, + comment: detailQuery?.data?.description || '', + name: detailQuery?.data?.name, + }} + serverId={detailQuery?.data?.serverId} + onCancel={closeAllModals} + onSuccess={(data) => + navigate( + generatePath(AppRoute.PLAYLISTS_DETAIL_SONGS, { + playlistId: data?.id || '', + }), + ) + } + /> + ), + title: 'Save as', + }); + }; - createPlaylistMutation.mutate( - { - body: { - _custom: { - navidrome: { - owner: detailQuery?.data?.owner || '', - ownerId: detailQuery?.data?.ownerId || '', - public: detailQuery?.data?.public || false, - rules, - sync: detailQuery?.data?.sync || false, - }, - }, - comment: detailQuery?.data?.description || '', - name: detailQuery?.data?.name, - }, - serverId: detailQuery?.data?.serverId, - }, - { - onSuccess: (data) => { - toast.success({ message: 'Playlist has been saved' }); - navigate(generatePath(AppRoute.PLAYLISTS_DETAIL_SONGS, { playlistId: data?.id || '' }), { - replace: true, - }); - deletePlaylistMutation.mutate({ - query: { id: playlistId }, - serverId: detailQuery?.data?.serverId, - }); - }, - }, - ); - }; - - const handleSaveAs = ( - filter: Record<string, any>, - extraFilters: { limit?: number; sortBy?: string; sortOrder?: string }, - ) => { - openModal({ - children: ( - <SaveAsPlaylistForm - body={{ - _custom: { - navidrome: { - owner: detailQuery?.data?.owner || '', - ownerId: detailQuery?.data?.ownerId || '', - public: detailQuery?.data?.public || false, - rules: { - ...filter, - limit: extraFilters.limit || undefined, - order: extraFilters.sortOrder || 'desc', - sort: extraFilters.sortBy || 'dateAdded', + const smartPlaylistVariants: Variants = { + animate: (custom: { isQueryBuilderExpanded: boolean }) => { + return { + maxHeight: custom.isQueryBuilderExpanded ? '35vh' : '3.5em', + opacity: 1, + transition: { + duration: 0.3, + ease: 'easeInOut', }, - sync: detailQuery?.data?.sync || false, - }, - }, - comment: detailQuery?.data?.description || '', - name: detailQuery?.data?.name, - }} - serverId={detailQuery?.data?.serverId} - onCancel={closeAllModals} - onSuccess={(data) => - navigate(generatePath(AppRoute.PLAYLISTS_DETAIL_SONGS, { playlistId: data?.id || '' })) - } - /> - ), - title: 'Save as', - }); - }; - - const smartPlaylistVariants: Variants = { - animate: (custom: { isQueryBuilderExpanded: boolean }) => { - return { - maxHeight: custom.isQueryBuilderExpanded ? '35vh' : '3.5em', - opacity: 1, - transition: { - duration: 0.3, - ease: 'easeInOut', + y: 0, + }; }, - y: 0, - }; - }, - exit: { - opacity: 0, - y: -25, - }, - initial: { - opacity: 0, - y: -25, - }, - }; + exit: { + opacity: 0, + y: -25, + }, + initial: { + opacity: 0, + y: -25, + }, + }; - const isSmartPlaylist = - !detailQuery?.isLoading && detailQuery?.data?.rules && server?.type === ServerType.NAVIDROME; + const isSmartPlaylist = + !detailQuery?.isLoading && + detailQuery?.data?.rules && + server?.type === ServerType.NAVIDROME; - const [showQueryBuilder, setShowQueryBuilder] = useState(false); - const [isQueryBuilderExpanded, setIsQueryBuilderExpanded] = useState(false); + const [showQueryBuilder, setShowQueryBuilder] = useState(false); + const [isQueryBuilderExpanded, setIsQueryBuilderExpanded] = useState(false); - const handleToggleExpand = () => { - setIsQueryBuilderExpanded((prev) => !prev); - }; + const handleToggleExpand = () => { + setIsQueryBuilderExpanded((prev) => !prev); + }; - const handleToggleShowQueryBuilder = () => { - setShowQueryBuilder((prev) => !prev); - setIsQueryBuilderExpanded(true); - }; + const handleToggleShowQueryBuilder = () => { + setShowQueryBuilder((prev) => !prev); + setIsQueryBuilderExpanded(true); + }; - const page = usePlaylistDetailStore(); - const filters: Partial<PlaylistSongListQuery> = { - sortBy: page?.table.id[playlistId]?.filter?.sortBy || SongListSort.ID, - sortOrder: page?.table.id[playlistId]?.filter?.sortOrder || SortOrder.ASC, - }; + const page = usePlaylistDetailStore(); + const filters: Partial<PlaylistSongListQuery> = { + sortBy: page?.table.id[playlistId]?.filter?.sortBy || SongListSort.ID, + sortOrder: page?.table.id[playlistId]?.filter?.sortOrder || SortOrder.ASC, + }; - const itemCountCheck = usePlaylistSongList({ - options: { - cacheTime: 1000 * 60 * 60 * 2, - staleTime: 1000 * 60 * 60 * 2, - }, - query: { - id: playlistId, - limit: 1, - startIndex: 0, - ...filters, - }, - serverId: server?.id, - }); + const itemCountCheck = usePlaylistSongList({ + options: { + cacheTime: 1000 * 60 * 60 * 2, + staleTime: 1000 * 60 * 60 * 2, + }, + query: { + id: playlistId, + limit: 1, + startIndex: 0, + ...filters, + }, + serverId: server?.id, + }); - const itemCount = - itemCountCheck.data?.totalRecordCount === null - ? undefined - : itemCountCheck.data?.totalRecordCount; + const itemCount = + itemCountCheck.data?.totalRecordCount === null + ? undefined + : itemCountCheck.data?.totalRecordCount; - return ( - <AnimatedPage key={`playlist-detail-songList-${playlistId}`}> - <PlaylistDetailSongListHeader - handleToggleShowQueryBuilder={handleToggleShowQueryBuilder} - itemCount={itemCount} - tableRef={tableRef} - /> - <AnimatePresence - custom={{ isQueryBuilderExpanded }} - initial={false} - > - {(isSmartPlaylist || showQueryBuilder) && ( - <motion.div - animate="animate" - custom={{ isQueryBuilderExpanded }} - exit="exit" - initial="initial" - transition={{ duration: 0.2, ease: 'easeInOut' }} - variants={smartPlaylistVariants} - > - <Paper - h="100%" - pos="relative" - w="100%" + return ( + <AnimatedPage key={`playlist-detail-songList-${playlistId}`}> + <PlaylistDetailSongListHeader + handleToggleShowQueryBuilder={handleToggleShowQueryBuilder} + itemCount={itemCount} + tableRef={tableRef} + /> + <AnimatePresence + custom={{ isQueryBuilderExpanded }} + initial={false} > - <Group - pt="1rem" - px="1rem" - > - <Button - compact - variant="default" - onClick={handleToggleExpand} - > - {isQueryBuilderExpanded ? ( - <RiArrowUpSLine size={20} /> - ) : ( - <RiArrowDownSLine size={20} /> - )} - </Button> - <Text>Query Editor</Text> - </Group> - <PlaylistQueryBuilder - key={JSON.stringify(detailQuery?.data?.rules)} - isSaving={createPlaylistMutation?.isLoading} - limit={detailQuery?.data?.rules?.limit} - query={detailQuery?.data?.rules} - sortBy={detailQuery?.data?.rules?.sort || SongListSort.ALBUM} - sortOrder={detailQuery?.data?.rules?.order || 'asc'} - onSave={handleSave} - onSaveAs={handleSaveAs} - /> - </Paper> - </motion.div> - )} - </AnimatePresence> - <PlaylistDetailSongListContent tableRef={tableRef} /> - </AnimatedPage> - ); + {(isSmartPlaylist || showQueryBuilder) && ( + <motion.div + animate="animate" + custom={{ isQueryBuilderExpanded }} + exit="exit" + initial="initial" + transition={{ duration: 0.2, ease: 'easeInOut' }} + variants={smartPlaylistVariants} + > + <Paper + h="100%" + pos="relative" + w="100%" + > + <Group + pt="1rem" + px="1rem" + > + <Button + compact + variant="default" + onClick={handleToggleExpand} + > + {isQueryBuilderExpanded ? ( + <RiArrowUpSLine size={20} /> + ) : ( + <RiArrowDownSLine size={20} /> + )} + </Button> + <Text>Query Editor</Text> + </Group> + <PlaylistQueryBuilder + key={JSON.stringify(detailQuery?.data?.rules)} + isSaving={createPlaylistMutation?.isLoading} + limit={detailQuery?.data?.rules?.limit} + query={detailQuery?.data?.rules} + sortBy={detailQuery?.data?.rules?.sort || SongListSort.ALBUM} + sortOrder={detailQuery?.data?.rules?.order || 'asc'} + onSave={handleSave} + onSaveAs={handleSaveAs} + /> + </Paper> + </motion.div> + )} + </AnimatePresence> + <PlaylistDetailSongListContent tableRef={tableRef} /> + </AnimatedPage> + ); }; export default PlaylistDetailSongListRoute; diff --git a/src/renderer/features/playlists/routes/playlist-list-route.tsx b/src/renderer/features/playlists/routes/playlist-list-route.tsx index 050ef121..231e983c 100644 --- a/src/renderer/features/playlists/routes/playlist-list-route.tsx +++ b/src/renderer/features/playlists/routes/playlist-list-route.tsx @@ -8,37 +8,37 @@ import { AnimatedPage } from '/@/renderer/features/shared'; import { useCurrentServer } from '/@/renderer/store'; const PlaylistListRoute = () => { - const tableRef = useRef<AgGridReactType | null>(null); - const server = useCurrentServer(); + const tableRef = useRef<AgGridReactType | null>(null); + const server = useCurrentServer(); - const itemCountCheck = usePlaylistList({ - options: { - cacheTime: 1000 * 60 * 60 * 2, - staleTime: 1000 * 60 * 60 * 2, - }, - query: { - limit: 1, - sortBy: PlaylistListSort.NAME, - sortOrder: SortOrder.ASC, - startIndex: 0, - }, - serverId: server?.id, - }); + const itemCountCheck = usePlaylistList({ + options: { + cacheTime: 1000 * 60 * 60 * 2, + staleTime: 1000 * 60 * 60 * 2, + }, + query: { + limit: 1, + sortBy: PlaylistListSort.NAME, + sortOrder: SortOrder.ASC, + startIndex: 0, + }, + serverId: server?.id, + }); - const itemCount = - itemCountCheck.data?.totalRecordCount === null - ? undefined - : itemCountCheck.data?.totalRecordCount; + const itemCount = + itemCountCheck.data?.totalRecordCount === null + ? undefined + : itemCountCheck.data?.totalRecordCount; - return ( - <AnimatedPage> - <PlaylistListHeader - itemCount={itemCount} - tableRef={tableRef} - /> - <PlaylistListContent tableRef={tableRef} /> - </AnimatedPage> - ); + return ( + <AnimatedPage> + <PlaylistListHeader + itemCount={itemCount} + tableRef={tableRef} + /> + <PlaylistListContent tableRef={tableRef} /> + </AnimatedPage> + ); }; export default PlaylistListRoute; diff --git a/src/renderer/features/playlists/utils.ts b/src/renderer/features/playlists/utils.ts index cf48f5dd..753c3d67 100644 --- a/src/renderer/features/playlists/utils.ts +++ b/src/renderer/features/playlists/utils.ts @@ -3,126 +3,126 @@ import { NDSongQueryFields } from '/@/renderer/api/navidrome.types'; import { QueryBuilderGroup } from '/@/renderer/types'; export const parseQueryBuilderChildren = (groups: QueryBuilderGroup[], data: any[]) => { - if (groups.length === 0) { - return data; - } + if (groups.length === 0) { + return data; + } - const filterGroups: any[] = []; + const filterGroups: any[] = []; - for (const group of groups) { - const rootType = group.type; - const query: any = { - [rootType]: [], - }; + for (const group of groups) { + const rootType = group.type; + const query: any = { + [rootType]: [], + }; - for (const rule of group.rules) { - if (rule.field && rule.operator) { - const [table, field] = rule.field.split('.'); - const operator = rule.operator; - const value = field !== 'releaseDate' ? rule.value : new Date(rule.value); + for (const rule of group.rules) { + if (rule.field && rule.operator) { + const [table, field] = rule.field.split('.'); + const operator = rule.operator; + const value = field !== 'releaseDate' ? rule.value : new Date(rule.value); - switch (table) { - default: - query[rootType].push({ - [operator]: { - [table]: value, - }, - }); - break; + switch (table) { + default: + query[rootType].push({ + [operator]: { + [table]: value, + }, + }); + break; + } + } } - } + + if (group.group.length > 0) { + const b = parseQueryBuilderChildren(group.group, data); + b.forEach((c) => query[rootType].push(c)); + } + + data.push(query); + filterGroups.push(query); } - if (group.group.length > 0) { - const b = parseQueryBuilderChildren(group.group, data); - b.forEach((c) => query[rootType].push(c)); - } - - data.push(query); - filterGroups.push(query); - } - - return filterGroups; + return filterGroups; }; // Convert QueryBuilderGroup to default query export const convertQueryGroupToNDQuery = (filter: QueryBuilderGroup) => { - const rootQueryType = filter.type; - const rootQuery = { - [rootQueryType]: [] as any[], - }; + const rootQueryType = filter.type; + const rootQuery = { + [rootQueryType]: [] as any[], + }; - for (const rule of filter.rules) { - if (rule.field && rule.operator) { - const [field] = rule.field.split('.'); - const operator = rule.operator; - let value = rule.value; + for (const rule of filter.rules) { + if (rule.field && rule.operator) { + const [field] = rule.field.split('.'); + const operator = rule.operator; + let value = rule.value; - const booleanFields = NDSongQueryFields.filter( - (queryField) => queryField.type === 'boolean', - ).map((field) => field.value); + const booleanFields = NDSongQueryFields.filter( + (queryField) => queryField.type === 'boolean', + ).map((field) => field.value); - // Convert string values to boolean - if (booleanFields.includes(field)) { - value = value === 'true'; - } + // Convert string values to boolean + if (booleanFields.includes(field)) { + value = value === 'true'; + } - switch (field) { - default: - rootQuery[rootQueryType].push({ - [operator]: { - [field]: value, - }, - }); - break; - } + switch (field) { + default: + rootQuery[rootQueryType].push({ + [operator]: { + [field]: value, + }, + }); + break; + } + } } - } - const groups = parseQueryBuilderChildren(filter.group, []); - for (const group of groups) { - rootQuery[rootQueryType].push(group); - } + const groups = parseQueryBuilderChildren(filter.group, []); + for (const group of groups) { + rootQuery[rootQueryType].push(group); + } - return rootQuery; + return rootQuery; }; // Convert default query to QueryBuilderGroup export const convertNDQueryToQueryGroup = (query: Record<string, any>) => { - const rootType = Object.keys(query)[0]; - const rootGroup: QueryBuilderGroup = { - group: [], - rules: [], - type: rootType as 'any' | 'all', - uniqueId: nanoid(), - }; - - for (const rule of query[rootType]) { - if (rule.any || rule.all) { - const group = convertNDQueryToQueryGroup(rule); - rootGroup.group.push(group); - } else { - const operator = Object.keys(rule)[0]; - const field = Object.keys(rule[operator])[0]; - let value = rule[operator][field]; - - const booleanFields = NDSongQueryFields.filter( - (queryField) => queryField.type === 'boolean', - ).map((field) => field.value); - - // Convert boolean values to string - if (booleanFields.includes(field)) { - value = value.toString(); - } - - rootGroup.rules.push({ - field, - operator, + const rootType = Object.keys(query)[0]; + const rootGroup: QueryBuilderGroup = { + group: [], + rules: [], + type: rootType as 'any' | 'all', uniqueId: nanoid(), - value, - }); - } - } + }; - return rootGroup; + for (const rule of query[rootType]) { + if (rule.any || rule.all) { + const group = convertNDQueryToQueryGroup(rule); + rootGroup.group.push(group); + } else { + const operator = Object.keys(rule)[0]; + const field = Object.keys(rule[operator])[0]; + let value = rule[operator][field]; + + const booleanFields = NDSongQueryFields.filter( + (queryField) => queryField.type === 'boolean', + ).map((field) => field.value); + + // Convert boolean values to string + if (booleanFields.includes(field)) { + value = value.toString(); + } + + rootGroup.rules.push({ + field, + operator, + uniqueId: nanoid(), + value, + }); + } + } + + return rootGroup; }; diff --git a/src/renderer/features/search/components/command-palette.tsx b/src/renderer/features/search/components/command-palette.tsx index 5bbff572..6bb23508 100644 --- a/src/renderer/features/search/components/command-palette.tsx +++ b/src/renderer/features/search/components/command-palette.tsx @@ -18,249 +18,261 @@ import { LibraryItem } from '/@/renderer/api/types'; import { usePlayQueueAdd } from '/@/renderer/features/player'; interface CommandPaletteProps { - modalProps: typeof useDisclosure['arguments']; + modalProps: typeof useDisclosure['arguments']; } const CustomModal = styled(Modal)` - & .mantine-Modal-header { - display: none; - } + & .mantine-Modal-header { + display: none; + } `; export const CommandPalette = ({ modalProps }: CommandPaletteProps) => { - const navigate = useNavigate(); - const server = useCurrentServer(); - const [value, setValue] = useState(''); - const [query, setQuery] = useState(''); - const [debouncedQuery] = useDebouncedValue(query, 400); - const [pages, setPages] = useState<CommandPalettePages[]>([CommandPalettePages.HOME]); - const activePage = pages[pages.length - 1]; - const isHome = activePage === CommandPalettePages.HOME; - const searchInputRef = useRef<HTMLInputElement>(null); + const navigate = useNavigate(); + const server = useCurrentServer(); + const [value, setValue] = useState(''); + const [query, setQuery] = useState(''); + const [debouncedQuery] = useDebouncedValue(query, 400); + const [pages, setPages] = useState<CommandPalettePages[]>([CommandPalettePages.HOME]); + const activePage = pages[pages.length - 1]; + const isHome = activePage === CommandPalettePages.HOME; + const searchInputRef = useRef<HTMLInputElement>(null); - const popPage = useCallback(() => { - setPages((pages) => { - const x = [...pages]; - x.splice(-1, 1); - return x; + const popPage = useCallback(() => { + setPages((pages) => { + const x = [...pages]; + x.splice(-1, 1); + return x; + }); + }, []); + + const { data, isLoading } = useSearch({ + options: { enabled: isHome && debouncedQuery !== '' && query !== '' }, + query: { + albumArtistLimit: 4, + albumArtistStartIndex: 0, + albumLimit: 4, + albumStartIndex: 0, + query: debouncedQuery, + songLimit: 4, + songStartIndex: 0, + }, + serverId: server?.id, }); - }, []); - const { data, isLoading } = useSearch({ - options: { enabled: isHome && debouncedQuery !== '' && query !== '' }, - query: { - albumArtistLimit: 4, - albumArtistStartIndex: 0, - albumLimit: 4, - albumStartIndex: 0, - query: debouncedQuery, - songLimit: 4, - songStartIndex: 0, - }, - serverId: server?.id, - }); + const showAlbumGroup = isHome && Boolean(query && data && data?.albums?.length > 0); + const showArtistGroup = isHome && Boolean(query && data && data?.albumArtists?.length > 0); + const showTrackGroup = isHome && Boolean(query && data && data?.songs?.length > 0); - const showAlbumGroup = isHome && Boolean(query && data && data?.albums?.length > 0); - const showArtistGroup = isHome && Boolean(query && data && data?.albumArtists?.length > 0); - const showTrackGroup = isHome && Boolean(query && data && data?.songs?.length > 0); + const handlePlayQueueAdd = usePlayQueueAdd(); - const handlePlayQueueAdd = usePlayQueueAdd(); - - return ( - <CustomModal - {...modalProps} - centered - handlers={{ - ...modalProps.handlers, - close: () => { - if (isHome) { - modalProps.handlers.close(); - setQuery(''); - } else { - popPage(); - } - }, - toggle: () => { - if (isHome) { - modalProps.handlers.toggle(); - setQuery(''); - } else { - popPage(); - } - }, - }} - scrollAreaComponent={ScrollArea.Autosize} - size="lg" - > - <Group - mb="1rem" - spacing="sm" - > - {pages.map((page, index) => ( - <Fragment key={page}> - {index > 0 && ' > '} - <Button - compact - disabled - variant="default" - > - {page?.toLocaleUpperCase()} - </Button> - </Fragment> - ))} - </Group> - <Command - filter={(value, search) => { - if (value.includes(search)) return 1; - if (value.includes('search')) return 1; - return 0; - }} - label="Global Command Menu" - value={value} - onValueChange={setValue} - > - <TextInput - ref={searchInputRef} - data-autofocus - icon={<RiSearchLine />} - rightSection={ - <ActionIcon - onClick={() => { - setQuery(''); - searchInputRef.current?.focus(); - }} - > - <RiCloseFill /> - </ActionIcon> - } - size="lg" - value={query} - onChange={(e) => setQuery(e.currentTarget.value)} - /> - <Command.Separator /> - <Command.List> - <Command.Empty>No results found.</Command.Empty> - {showAlbumGroup && ( - <Command.Group heading="Albums"> - {data?.albums?.map((album) => ( - <Command.Item - key={`search-album-${album.id}`} - value={`search-${album.id}`} - onSelect={() => { - navigate(generatePath(AppRoute.LIBRARY_ALBUMS_DETAIL, { albumId: album.id })); - modalProps.handlers.close(); - setQuery(''); - }} - > - <LibraryCommandItem - handlePlayQueueAdd={handlePlayQueueAdd} - id={album.id} - imageUrl={album.imageUrl} - itemType={LibraryItem.ALBUM} - subtitle={album.albumArtists.map((artist) => artist.name).join(', ')} - title={album.name} - /> - </Command.Item> - ))} - </Command.Group> - )} - {showArtistGroup && ( - <Command.Group heading="Artists"> - {data?.albumArtists.map((artist) => ( - <Command.Item - key={`artist-${artist.id}`} - value={`search-${artist.id}`} - onSelect={() => { - navigate( - generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, { - albumArtistId: artist.id, - }), - ); - modalProps.handlers.close(); - setQuery(''); - }} - > - <LibraryCommandItem - handlePlayQueueAdd={handlePlayQueueAdd} - id={artist.id} - imageUrl={artist.imageUrl} - itemType={LibraryItem.ALBUM_ARTIST} - subtitle={ - (artist?.albumCount || 0) > 0 ? `${artist.albumCount} albums` : undefined + return ( + <CustomModal + {...modalProps} + centered + handlers={{ + ...modalProps.handlers, + close: () => { + if (isHome) { + modalProps.handlers.close(); + setQuery(''); + } else { + popPage(); } - title={artist.name} - /> - </Command.Item> - ))} - </Command.Group> - )} - {showTrackGroup && ( - <Command.Group heading="Tracks"> - {data?.songs.map((song) => ( - <Command.Item - key={`artist-${song.id}`} - value={`search-${song.id}`} - onSelect={() => { - navigate( - generatePath(AppRoute.LIBRARY_ALBUMS_DETAIL, { - albumId: song.albumId, - }), - ); - modalProps.handlers.close(); - setQuery(''); - }} - > - <LibraryCommandItem - handlePlayQueueAdd={handlePlayQueueAdd} - id={song.id} - imageUrl={song.imageUrl} - itemType={LibraryItem.SONG} - subtitle={song.artists.map((artist) => artist.name).join(', ')} - title={song.name} - /> - </Command.Item> - ))} - </Command.Group> - )} - {activePage === CommandPalettePages.HOME && ( - <HomeCommands - handleClose={modalProps.handlers.close} - pages={pages} - query={query} - setPages={setPages} - setQuery={setQuery} - /> - )} - {activePage === CommandPalettePages.GO_TO && ( - <GoToCommands - handleClose={modalProps.handlers.close} - setPages={setPages} - setQuery={setQuery} - /> - )} - {activePage === CommandPalettePages.MANAGE_SERVERS && ( - <ServerCommands - handleClose={modalProps.handlers.close} - setPages={setPages} - setQuery={setQuery} - /> - )} - </Command.List> - </Command> - <Paper - mt="0.5rem" - p="0.5rem" - > - <Group position="apart"> - <Command.Loading>{isHome && isLoading && query !== '' && <Spinner />}</Command.Loading> - <Group spacing="sm"> - <Kbd size="md">ESC</Kbd> - <Kbd size="md">↑</Kbd> - <Kbd size="md">↓</Kbd> - <Kbd size="md">⏎</Kbd> - </Group> - </Group> - </Paper> - </CustomModal> - ); + }, + toggle: () => { + if (isHome) { + modalProps.handlers.toggle(); + setQuery(''); + } else { + popPage(); + } + }, + }} + scrollAreaComponent={ScrollArea.Autosize} + size="lg" + > + <Group + mb="1rem" + spacing="sm" + > + {pages.map((page, index) => ( + <Fragment key={page}> + {index > 0 && ' > '} + <Button + compact + disabled + variant="default" + > + {page?.toLocaleUpperCase()} + </Button> + </Fragment> + ))} + </Group> + <Command + filter={(value, search) => { + if (value.includes(search)) return 1; + if (value.includes('search')) return 1; + return 0; + }} + label="Global Command Menu" + value={value} + onValueChange={setValue} + > + <TextInput + ref={searchInputRef} + data-autofocus + icon={<RiSearchLine />} + rightSection={ + <ActionIcon + onClick={() => { + setQuery(''); + searchInputRef.current?.focus(); + }} + > + <RiCloseFill /> + </ActionIcon> + } + size="lg" + value={query} + onChange={(e) => setQuery(e.currentTarget.value)} + /> + <Command.Separator /> + <Command.List> + <Command.Empty>No results found.</Command.Empty> + {showAlbumGroup && ( + <Command.Group heading="Albums"> + {data?.albums?.map((album) => ( + <Command.Item + key={`search-album-${album.id}`} + value={`search-${album.id}`} + onSelect={() => { + navigate( + generatePath(AppRoute.LIBRARY_ALBUMS_DETAIL, { + albumId: album.id, + }), + ); + modalProps.handlers.close(); + setQuery(''); + }} + > + <LibraryCommandItem + handlePlayQueueAdd={handlePlayQueueAdd} + id={album.id} + imageUrl={album.imageUrl} + itemType={LibraryItem.ALBUM} + subtitle={album.albumArtists + .map((artist) => artist.name) + .join(', ')} + title={album.name} + /> + </Command.Item> + ))} + </Command.Group> + )} + {showArtistGroup && ( + <Command.Group heading="Artists"> + {data?.albumArtists.map((artist) => ( + <Command.Item + key={`artist-${artist.id}`} + value={`search-${artist.id}`} + onSelect={() => { + navigate( + generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, { + albumArtistId: artist.id, + }), + ); + modalProps.handlers.close(); + setQuery(''); + }} + > + <LibraryCommandItem + handlePlayQueueAdd={handlePlayQueueAdd} + id={artist.id} + imageUrl={artist.imageUrl} + itemType={LibraryItem.ALBUM_ARTIST} + subtitle={ + (artist?.albumCount || 0) > 0 + ? `${artist.albumCount} albums` + : undefined + } + title={artist.name} + /> + </Command.Item> + ))} + </Command.Group> + )} + {showTrackGroup && ( + <Command.Group heading="Tracks"> + {data?.songs.map((song) => ( + <Command.Item + key={`artist-${song.id}`} + value={`search-${song.id}`} + onSelect={() => { + navigate( + generatePath(AppRoute.LIBRARY_ALBUMS_DETAIL, { + albumId: song.albumId, + }), + ); + modalProps.handlers.close(); + setQuery(''); + }} + > + <LibraryCommandItem + handlePlayQueueAdd={handlePlayQueueAdd} + id={song.id} + imageUrl={song.imageUrl} + itemType={LibraryItem.SONG} + subtitle={song.artists + .map((artist) => artist.name) + .join(', ')} + title={song.name} + /> + </Command.Item> + ))} + </Command.Group> + )} + {activePage === CommandPalettePages.HOME && ( + <HomeCommands + handleClose={modalProps.handlers.close} + pages={pages} + query={query} + setPages={setPages} + setQuery={setQuery} + /> + )} + {activePage === CommandPalettePages.GO_TO && ( + <GoToCommands + handleClose={modalProps.handlers.close} + setPages={setPages} + setQuery={setQuery} + /> + )} + {activePage === CommandPalettePages.MANAGE_SERVERS && ( + <ServerCommands + handleClose={modalProps.handlers.close} + setPages={setPages} + setQuery={setQuery} + /> + )} + </Command.List> + </Command> + <Paper + mt="0.5rem" + p="0.5rem" + > + <Group position="apart"> + <Command.Loading> + {isHome && isLoading && query !== '' && <Spinner />} + </Command.Loading> + <Group spacing="sm"> + <Kbd size="md">ESC</Kbd> + <Kbd size="md">↑</Kbd> + <Kbd size="md">↓</Kbd> + <Kbd size="md">⏎</Kbd> + </Group> + </Group> + </Paper> + </CustomModal> + ); }; diff --git a/src/renderer/features/search/components/command.tsx b/src/renderer/features/search/components/command.tsx index 9b2c4081..c6edfa3f 100644 --- a/src/renderer/features/search/components/command.tsx +++ b/src/renderer/features/search/components/command.tsx @@ -2,69 +2,69 @@ import { Command as Cmdk } from 'cmdk'; import styled from 'styled-components'; export enum CommandPalettePages { - GO_TO = 'go', - HOME = 'home', - MANAGE_SERVERS = 'servers', + GO_TO = 'go', + HOME = 'home', + MANAGE_SERVERS = 'servers', } export const Command = styled(Cmdk)` - [cmdk-root] { - background-color: var(--background-color); - } - - input[cmdk-input] { - width: 100%; - height: 1.5rem; - margin-bottom: 1rem; - padding: 1.3rem 0.5rem; - color: var(--input-fg); - font-family: var(--content-font-family); - background: var(--input-bg); - border: none; - border-radius: 5px; - - &::placeholder { - color: var(--input-placeholder-fg); - } - } - - [cmdk-group-heading] { - margin: 1rem 0; - font-size: 0.9rem; - opacity: 0.8; - } - - [cmdk-group-items] { - display: flex; - flex-direction: column; - gap: 0.4rem; - } - - [cmdk-item] { - display: flex; - gap: 0.5rem; - align-items: center; - padding: 0.5rem; - color: var(--btn-default-fg); - font-family: var(--content-font-family); - background: var(--btn-default-bg); - border-radius: 5px; - cursor: pointer; - - svg { - width: 1.2rem; - height: 1.2rem; + [cmdk-root] { + background-color: var(--background-color); } - &[data-selected] { - color: var(--btn-default-fg-hover); - background: var(--btn-default-bg-hover); - } - } + input[cmdk-input] { + width: 100%; + height: 1.5rem; + margin-bottom: 1rem; + padding: 1.3rem 0.5rem; + color: var(--input-fg); + font-family: var(--content-font-family); + background: var(--input-bg); + border: none; + border-radius: 5px; - [cmdk-separator] { - height: 1px; - margin: 0 0 0.5rem; - background: var(--generic-border-color); - } + &::placeholder { + color: var(--input-placeholder-fg); + } + } + + [cmdk-group-heading] { + margin: 1rem 0; + font-size: 0.9rem; + opacity: 0.8; + } + + [cmdk-group-items] { + display: flex; + flex-direction: column; + gap: 0.4rem; + } + + [cmdk-item] { + display: flex; + gap: 0.5rem; + align-items: center; + padding: 0.5rem; + color: var(--btn-default-fg); + font-family: var(--content-font-family); + background: var(--btn-default-bg); + border-radius: 5px; + cursor: pointer; + + svg { + width: 1.2rem; + height: 1.2rem; + } + + &[data-selected] { + color: var(--btn-default-fg-hover); + background: var(--btn-default-bg-hover); + } + } + + [cmdk-separator] { + height: 1px; + margin: 0 0 0.5rem; + background: var(--generic-border-color); + } `; diff --git a/src/renderer/features/search/components/go-to-commands.tsx b/src/renderer/features/search/components/go-to-commands.tsx index 42ffeebd..dc9f31c5 100644 --- a/src/renderer/features/search/components/go-to-commands.tsx +++ b/src/renderer/features/search/components/go-to-commands.tsx @@ -4,42 +4,42 @@ import { Command, CommandPalettePages } from '/@/renderer/features/search/compon import { AppRoute } from '/@/renderer/router/routes'; interface GoToCommandsProps { - handleClose: () => void; - setPages: (pages: CommandPalettePages[]) => void; - setQuery: Dispatch<string>; + handleClose: () => void; + setPages: (pages: CommandPalettePages[]) => void; + setQuery: Dispatch<string>; } export const GoToCommands = ({ setQuery, setPages, handleClose }: GoToCommandsProps) => { - const navigate = useNavigate(); + const navigate = useNavigate(); - const goTo = useCallback( - (route: string) => { - navigate(route); - handleClose(); - setPages([CommandPalettePages.HOME]); - setQuery(''); - }, - [handleClose, navigate, setPages, setQuery], - ); + const goTo = useCallback( + (route: string) => { + navigate(route); + handleClose(); + setPages([CommandPalettePages.HOME]); + setQuery(''); + }, + [handleClose, navigate, setPages, setQuery], + ); - return ( - <> - <Command.Group> - <Command.Item onSelect={() => goTo(AppRoute.HOME)}>Home</Command.Item> - <Command.Item onSelect={() => goTo(AppRoute.SEARCH)}>Search</Command.Item> - <Command.Item onSelect={() => goTo(AppRoute.SETTINGS)}>Settings</Command.Item> - </Command.Group> - <Command.Group heading="Library"> - <Command.Item onSelect={() => goTo(AppRoute.LIBRARY_ALBUMS)}>Albums</Command.Item> - <Command.Item onSelect={() => goTo(AppRoute.LIBRARY_SONGS)}>Tracks</Command.Item> - <Command.Item onSelect={() => goTo(AppRoute.LIBRARY_ALBUM_ARTISTS)}> - Album artists - </Command.Item> - <Command.Item onSelect={() => goTo(AppRoute.LIBRARY_GENRES)}>Genres</Command.Item> - <Command.Item onSelect={() => goTo(AppRoute.LIBRARY_FOLDERS)}>Folders</Command.Item> - <Command.Item onSelect={() => goTo(AppRoute.PLAYLISTS)}>Playlists</Command.Item> - </Command.Group> - <Command.Separator /> - </> - ); + return ( + <> + <Command.Group> + <Command.Item onSelect={() => goTo(AppRoute.HOME)}>Home</Command.Item> + <Command.Item onSelect={() => goTo(AppRoute.SEARCH)}>Search</Command.Item> + <Command.Item onSelect={() => goTo(AppRoute.SETTINGS)}>Settings</Command.Item> + </Command.Group> + <Command.Group heading="Library"> + <Command.Item onSelect={() => goTo(AppRoute.LIBRARY_ALBUMS)}>Albums</Command.Item> + <Command.Item onSelect={() => goTo(AppRoute.LIBRARY_SONGS)}>Tracks</Command.Item> + <Command.Item onSelect={() => goTo(AppRoute.LIBRARY_ALBUM_ARTISTS)}> + Album artists + </Command.Item> + <Command.Item onSelect={() => goTo(AppRoute.LIBRARY_GENRES)}>Genres</Command.Item> + <Command.Item onSelect={() => goTo(AppRoute.LIBRARY_FOLDERS)}>Folders</Command.Item> + <Command.Item onSelect={() => goTo(AppRoute.PLAYLISTS)}>Playlists</Command.Item> + </Command.Group> + <Command.Separator /> + </> + ); }; diff --git a/src/renderer/features/search/components/home-commands.tsx b/src/renderer/features/search/components/home-commands.tsx index fde78ed8..a68351ab 100644 --- a/src/renderer/features/search/components/home-commands.tsx +++ b/src/renderer/features/search/components/home-commands.tsx @@ -11,68 +11,70 @@ import { useCurrentServer } from '/@/renderer/store'; import { ServerType } from '/@/renderer/types'; interface HomeCommandsProps { - handleClose: () => void; - pages: CommandPalettePages[]; - query: string; - setPages: Dispatch<CommandPalettePages[]>; - setQuery: Dispatch<string>; + handleClose: () => void; + pages: CommandPalettePages[]; + query: string; + setPages: Dispatch<CommandPalettePages[]>; + setQuery: Dispatch<string>; } export const HomeCommands = ({ - query, - setQuery, - pages, - setPages, - handleClose, + query, + setQuery, + pages, + setPages, + handleClose, }: HomeCommandsProps) => { - const navigate = useNavigate(); - const server = useCurrentServer(); + const navigate = useNavigate(); + const server = useCurrentServer(); - const handleCreatePlaylistModal = useCallback(() => { - handleClose(); + const handleCreatePlaylistModal = useCallback(() => { + handleClose(); - openModal({ - children: <CreatePlaylistForm onCancel={() => closeAllModals()} />, - size: server?.type === ServerType?.NAVIDROME ? 'xl' : 'sm', - title: 'Create Playlist', - }); - }, [handleClose, server?.type]); + openModal({ + children: <CreatePlaylistForm onCancel={() => closeAllModals()} />, + size: server?.type === ServerType?.NAVIDROME ? 'xl' : 'sm', + title: 'Create Playlist', + }); + }, [handleClose, server?.type]); - const handleSearch = () => { - navigate( - { - pathname: generatePath(AppRoute.SEARCH, { itemType: LibraryItem.SONG }), - search: createSearchParams({ - query, - }).toString(), - }, - { - state: { - navigationId: nanoid(), - }, - }, + const handleSearch = () => { + navigate( + { + pathname: generatePath(AppRoute.SEARCH, { itemType: LibraryItem.SONG }), + search: createSearchParams({ + query, + }).toString(), + }, + { + state: { + navigationId: nanoid(), + }, + }, + ); + handleClose(); + setQuery(''); + }; + + return ( + <> + <Command.Group heading="Commands"> + <Command.Item + value="Search" + onSelect={handleSearch} + > + {query ? `Search for "${query}"...` : 'Search...'} + </Command.Item> + <Command.Item onSelect={handleCreatePlaylistModal}>Create playlist...</Command.Item> + <Command.Item onSelect={() => setPages([...pages, CommandPalettePages.GO_TO])}> + Go to page... + </Command.Item> + <Command.Item + onSelect={() => setPages([...pages, CommandPalettePages.MANAGE_SERVERS])} + > + Server commands... + </Command.Item> + </Command.Group> + </> ); - handleClose(); - setQuery(''); - }; - - return ( - <> - <Command.Group heading="Commands"> - <Command.Item - value="Search" - onSelect={handleSearch} - > - {query ? `Search for "${query}"...` : 'Search...'} - </Command.Item> - <Command.Item onSelect={handleCreatePlaylistModal}>Create playlist...</Command.Item> - <Command.Item onSelect={() => setPages([...pages, CommandPalettePages.GO_TO])}> - Go to page... - </Command.Item> - <Command.Item onSelect={() => setPages([...pages, CommandPalettePages.MANAGE_SERVERS])}> - Server commands... - </Command.Item> - </Command.Group> - </> - ); }; diff --git a/src/renderer/features/search/components/library-command-item.tsx b/src/renderer/features/search/components/library-command-item.tsx index 3301bb3f..5b3ca716 100644 --- a/src/renderer/features/search/components/library-command-item.tsx +++ b/src/renderer/features/search/components/library-command-item.tsx @@ -1,12 +1,12 @@ import { Center, Flex } from '@mantine/core'; import { useCallback, MouseEvent } from 'react'; import { - RiAddBoxFill, - RiAddCircleFill, - RiAlbumFill, - RiPlayFill, - RiPlayListFill, - RiUserVoiceFill, + RiAddBoxFill, + RiAddCircleFill, + RiAlbumFill, + RiPlayFill, + RiPlayListFill, + RiUserVoiceFill, } from 'react-icons/ri'; import styled from 'styled-components'; import { LibraryItem } from '/@/renderer/api/types'; @@ -16,168 +16,168 @@ import { Play, PlayQueueAddOptions } from '/@/renderer/types'; const Item = styled(Flex)``; const ItemGrid = styled.div<{ height: number }>` - display: grid; - grid-auto-columns: 1fr; - grid-template-areas: 'image info'; - grid-template-rows: 1fr; - grid-template-columns: ${(props) => props.height}px minmax(0, 1fr); - gap: 0.5rem; - width: 100%; - max-width: 100%; - height: 100%; - letter-spacing: 0.5px; + display: grid; + grid-auto-columns: 1fr; + grid-template-areas: 'image info'; + grid-template-rows: 1fr; + grid-template-columns: ${(props) => props.height}px minmax(0, 1fr); + gap: 0.5rem; + width: 100%; + max-width: 100%; + height: 100%; + letter-spacing: 0.5px; `; const ImageWrapper = styled.div` - display: flex; - grid-area: image; - align-items: center; - justify-content: center; - height: 100%; + display: flex; + grid-area: image; + align-items: center; + justify-content: center; + height: 100%; `; const MetadataWrapper = styled.div` - display: flex; - flex-direction: column; - grid-area: info; - justify-content: center; - width: 100%; + display: flex; + flex-direction: column; + grid-area: info; + justify-content: center; + width: 100%; `; const StyledImage = styled.img` - object-fit: cover; - border-radius: 4px; + object-fit: cover; + border-radius: 4px; `; const ActionsContainer = styled(Flex)``; interface LibraryCommandItemProps { - handlePlayQueueAdd?: (options: PlayQueueAddOptions) => void; - id: string; - imageUrl: string | null; - itemType: LibraryItem; - subtitle?: string; - title?: string; + handlePlayQueueAdd?: (options: PlayQueueAddOptions) => void; + id: string; + imageUrl: string | null; + itemType: LibraryItem; + subtitle?: string; + title?: string; } export const LibraryCommandItem = ({ - id, - imageUrl, - subtitle, - title, - itemType, - handlePlayQueueAdd, + id, + imageUrl, + subtitle, + title, + itemType, + handlePlayQueueAdd, }: LibraryCommandItemProps) => { - let Placeholder = RiAlbumFill; + let Placeholder = RiAlbumFill; - switch (itemType) { - case LibraryItem.ALBUM: - Placeholder = RiAlbumFill; - break; - case LibraryItem.ARTIST: - Placeholder = RiUserVoiceFill; - break; - case LibraryItem.ALBUM_ARTIST: - Placeholder = RiUserVoiceFill; - break; - case LibraryItem.PLAYLIST: - Placeholder = RiPlayListFill; - break; - default: - Placeholder = RiAlbumFill; - break; - } + switch (itemType) { + case LibraryItem.ALBUM: + Placeholder = RiAlbumFill; + break; + case LibraryItem.ARTIST: + Placeholder = RiUserVoiceFill; + break; + case LibraryItem.ALBUM_ARTIST: + Placeholder = RiUserVoiceFill; + break; + case LibraryItem.PLAYLIST: + Placeholder = RiPlayListFill; + break; + default: + Placeholder = RiAlbumFill; + break; + } - const handlePlay = useCallback( - (e: MouseEvent, id: string, playType: Play) => { - e.stopPropagation(); - handlePlayQueueAdd?.({ - byItemType: { - id: [id], - type: itemType, + const handlePlay = useCallback( + (e: MouseEvent, id: string, playType: Play) => { + e.stopPropagation(); + handlePlayQueueAdd?.({ + byItemType: { + id: [id], + type: itemType, + }, + playType, + }); }, - playType, - }); - }, - [handlePlayQueueAdd, itemType], - ); + [handlePlayQueueAdd, itemType], + ); - return ( - <Item - gap="xl" - justify="space-between" - style={{ height: '40px', width: '100%' }} - > - <ItemGrid height={40}> - <ImageWrapper> - {imageUrl ? ( - <StyledImage - alt="cover" - height={40} - placeholder="var(--placeholder-bg)" - src={imageUrl} - style={{}} - width={40} - /> - ) : ( - <Center - style={{ - background: 'var(--placeholder-bg)', - borderRadius: 'var(--card-default-radius)', - height: `${40}px`, - width: `${40}px`, - }} + return ( + <Item + gap="xl" + justify="space-between" + style={{ height: '40px', width: '100%' }} + > + <ItemGrid height={40}> + <ImageWrapper> + {imageUrl ? ( + <StyledImage + alt="cover" + height={40} + placeholder="var(--placeholder-bg)" + src={imageUrl} + style={{}} + width={40} + /> + ) : ( + <Center + style={{ + background: 'var(--placeholder-bg)', + borderRadius: 'var(--card-default-radius)', + height: `${40}px`, + width: `${40}px`, + }} + > + <Placeholder + color="var(--placeholder-fg)" + size={35} + /> + </Center> + )} + </ImageWrapper> + <MetadataWrapper> + <Text overflow="hidden">{title}</Text> + <Text + $secondary + overflow="hidden" + > + {subtitle} + </Text> + </MetadataWrapper> + </ItemGrid> + <ActionsContainer + align="center" + gap="sm" + justify="flex-end" > - <Placeholder - color="var(--placeholder-fg)" - size={35} - /> - </Center> - )} - </ImageWrapper> - <MetadataWrapper> - <Text overflow="hidden">{title}</Text> - <Text - $secondary - overflow="hidden" - > - {subtitle} - </Text> - </MetadataWrapper> - </ItemGrid> - <ActionsContainer - align="center" - gap="sm" - justify="flex-end" - > - <Button - compact - size="md" - tooltip={{ label: 'Play', openDelay: 500 }} - variant="default" - onClick={(e) => handlePlay(e, id, Play.NOW)} - > - <RiPlayFill /> - </Button> - <Button - compact - size="md" - tooltip={{ label: 'Add to queue', openDelay: 500 }} - variant="default" - onClick={(e) => handlePlay(e, id, Play.LAST)} - > - <RiAddBoxFill /> - </Button> - <Button - compact - size="md" - tooltip={{ label: 'Play next', openDelay: 500 }} - variant="default" - onClick={(e) => handlePlay(e, id, Play.NEXT)} - > - <RiAddCircleFill /> - </Button> - </ActionsContainer> - </Item> - ); + <Button + compact + size="md" + tooltip={{ label: 'Play', openDelay: 500 }} + variant="default" + onClick={(e) => handlePlay(e, id, Play.NOW)} + > + <RiPlayFill /> + </Button> + <Button + compact + size="md" + tooltip={{ label: 'Add to queue', openDelay: 500 }} + variant="default" + onClick={(e) => handlePlay(e, id, Play.LAST)} + > + <RiAddBoxFill /> + </Button> + <Button + compact + size="md" + tooltip={{ label: 'Play next', openDelay: 500 }} + variant="default" + onClick={(e) => handlePlay(e, id, Play.NEXT)} + > + <RiAddCircleFill /> + </Button> + </ActionsContainer> + </Item> + ); }; diff --git a/src/renderer/features/search/components/search-content.tsx b/src/renderer/features/search/components/search-content.tsx index 522986dd..c7985b97 100644 --- a/src/renderer/features/search/components/search-content.tsx +++ b/src/renderer/features/search/components/search-content.tsx @@ -1,9 +1,9 @@ import { MutableRefObject, useMemo, useCallback } from 'react'; import { - ColDef, - GridReadyEvent, - RowDoubleClickedEvent, - IDatasource, + ColDef, + GridReadyEvent, + RowDoubleClickedEvent, + IDatasource, } from '@ag-grid-community/core'; import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact'; import { Stack } from '@mantine/core'; @@ -14,139 +14,143 @@ import { VirtualGridAutoSizerContainer } from '/@/renderer/components/virtual-gr import { VirtualTable, getColumnDefs } from '/@/renderer/components/virtual-table'; import { useHandleTableContextMenu } from '/@/renderer/features/context-menu'; import { - ALBUM_CONTEXT_MENU_ITEMS, - ARTIST_CONTEXT_MENU_ITEMS, - SONG_CONTEXT_MENU_ITEMS, + ALBUM_CONTEXT_MENU_ITEMS, + ARTIST_CONTEXT_MENU_ITEMS, + SONG_CONTEXT_MENU_ITEMS, } from '/@/renderer/features/context-menu/context-menu-items'; import { usePlayQueueAdd } from '/@/renderer/features/player'; import { AppRoute } from '../../../router/routes'; import { - useCurrentServer, - useSongListStore, - usePlayButtonBehavior, - useAlbumListStore, - useAlbumArtistListStore, + useCurrentServer, + useSongListStore, + usePlayButtonBehavior, + useAlbumListStore, + useAlbumArtistListStore, } from '/@/renderer/store'; interface SearchContentProps { - getDatasource: (searchQuery: string, itemType: LibraryItem) => IDatasource | undefined; - tableRef: MutableRefObject<AgGridReactType | null>; + getDatasource: (searchQuery: string, itemType: LibraryItem) => IDatasource | undefined; + tableRef: MutableRefObject<AgGridReactType | null>; } export const SearchContent = ({ tableRef, getDatasource }: SearchContentProps) => { - const navigate = useNavigate(); - const server = useCurrentServer(); - const { itemType } = useParams() as { itemType: LibraryItem }; - const [searchParams] = useSearchParams(); - const songListStore = useSongListStore(); - const albumListStore = useAlbumListStore(); - const albumArtistListStore = useAlbumArtistListStore(); - const handlePlayQueueAdd = usePlayQueueAdd(); - const playButtonBehavior = usePlayButtonBehavior(); + const navigate = useNavigate(); + const server = useCurrentServer(); + const { itemType } = useParams() as { itemType: LibraryItem }; + const [searchParams] = useSearchParams(); + const songListStore = useSongListStore(); + const albumListStore = useAlbumListStore(); + const albumArtistListStore = useAlbumArtistListStore(); + const handlePlayQueueAdd = usePlayQueueAdd(); + const playButtonBehavior = usePlayButtonBehavior(); - const getTable = useCallback( - (itemType: string) => { - switch (itemType) { - case LibraryItem.SONG: - return songListStore.table; - case LibraryItem.ALBUM: - return albumListStore.table; - case LibraryItem.ALBUM_ARTIST: - return albumArtistListStore.table; - default: - return undefined; - } - }, - [albumArtistListStore.table, albumListStore.table, songListStore.table], - ); + const getTable = useCallback( + (itemType: string) => { + switch (itemType) { + case LibraryItem.SONG: + return songListStore.table; + case LibraryItem.ALBUM: + return albumListStore.table; + case LibraryItem.ALBUM_ARTIST: + return albumArtistListStore.table; + default: + return undefined; + } + }, + [albumArtistListStore.table, albumListStore.table, songListStore.table], + ); - const table = getTable(itemType)!; + const table = getTable(itemType)!; - const columnDefs: ColDef[] = useMemo(() => getColumnDefs(table.columns), [table.columns]); + const columnDefs: ColDef[] = useMemo(() => getColumnDefs(table.columns), [table.columns]); - const onGridReady = useCallback( - (params: GridReadyEvent) => { - const datasource = getDatasource(searchParams.get('query') || '', itemType); - if (!datasource) return; + const onGridReady = useCallback( + (params: GridReadyEvent) => { + const datasource = getDatasource(searchParams.get('query') || '', itemType); + if (!datasource) return; - params.api.setDatasource(datasource); - params.api.ensureIndexVisible(table.scrollOffset, 'top'); - }, - [getDatasource, itemType, searchParams, table.scrollOffset], - ); + params.api.setDatasource(datasource); + params.api.ensureIndexVisible(table.scrollOffset, 'top'); + }, + [getDatasource, itemType, searchParams, table.scrollOffset], + ); - const handleGridSizeChange = () => { - if (table.autoFit) { - tableRef?.current?.api.sizeColumnsToFit(); - } - }; + const handleGridSizeChange = () => { + if (table.autoFit) { + tableRef?.current?.api.sizeColumnsToFit(); + } + }; - const contextMenuItems = () => { - switch (itemType) { - case LibraryItem.ALBUM: - return ALBUM_CONTEXT_MENU_ITEMS; - case LibraryItem.ALBUM_ARTIST: - return ARTIST_CONTEXT_MENU_ITEMS; - case LibraryItem.SONG: - return SONG_CONTEXT_MENU_ITEMS; - default: - return []; - } - }; + const contextMenuItems = () => { + switch (itemType) { + case LibraryItem.ALBUM: + return ALBUM_CONTEXT_MENU_ITEMS; + case LibraryItem.ALBUM_ARTIST: + return ARTIST_CONTEXT_MENU_ITEMS; + case LibraryItem.SONG: + return SONG_CONTEXT_MENU_ITEMS; + default: + return []; + } + }; - const handleContextMenu = useHandleTableContextMenu(itemType, contextMenuItems()); + const handleContextMenu = useHandleTableContextMenu(itemType, contextMenuItems()); - const handleRowDoubleClick = (e: RowDoubleClickedEvent<QueueSong>) => { - if (!e.data) return; - switch (itemType) { - case LibraryItem.ALBUM: - navigate(generatePath(AppRoute.LIBRARY_ALBUMS_DETAIL, { albumId: e.data.id })); - break; - case LibraryItem.ALBUM_ARTIST: - navigate(generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, { albumArtistId: e.data.id })); - break; - case LibraryItem.SONG: - handlePlayQueueAdd?.({ - byData: [e.data], - playType: playButtonBehavior, - }); - break; - } - }; + const handleRowDoubleClick = (e: RowDoubleClickedEvent<QueueSong>) => { + if (!e.data) return; + switch (itemType) { + case LibraryItem.ALBUM: + navigate(generatePath(AppRoute.LIBRARY_ALBUMS_DETAIL, { albumId: e.data.id })); + break; + case LibraryItem.ALBUM_ARTIST: + navigate( + generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, { + albumArtistId: e.data.id, + }), + ); + break; + case LibraryItem.SONG: + handlePlayQueueAdd?.({ + byData: [e.data], + playType: playButtonBehavior, + }); + break; + } + }; - return ( - <Stack - h="100%" - spacing={0} - > - <VirtualGridAutoSizerContainer> - <VirtualTable - // https://github.com/ag-grid/ag-grid/issues/5284 - // Key is used to force remount of table when display, rowHeight, or server changes - key={`table-${itemType}-${table.rowHeight}-${server?.id}`} - ref={tableRef} - alwaysShowHorizontalScroll - suppressRowDrag - autoFitColumns={table.autoFit} - blockLoadDebounceMillis={200} - cacheBlockSize={25} - cacheOverflowSize={1} - columnDefs={columnDefs} - context={{ - query: searchParams.get('query'), - }} - getRowId={(data) => data.data.id} - infiniteInitialRowCount={25} - rowBuffer={20} - rowHeight={table.rowHeight || 40} - rowModelType="infinite" - rowSelection="multiple" - onCellContextMenu={handleContextMenu} - onGridReady={onGridReady} - onGridSizeChanged={handleGridSizeChange} - onRowDoubleClicked={handleRowDoubleClick} - /> - </VirtualGridAutoSizerContainer> - </Stack> - ); + return ( + <Stack + h="100%" + spacing={0} + > + <VirtualGridAutoSizerContainer> + <VirtualTable + // https://github.com/ag-grid/ag-grid/issues/5284 + // Key is used to force remount of table when display, rowHeight, or server changes + key={`table-${itemType}-${table.rowHeight}-${server?.id}`} + ref={tableRef} + alwaysShowHorizontalScroll + suppressRowDrag + autoFitColumns={table.autoFit} + blockLoadDebounceMillis={200} + cacheBlockSize={25} + cacheOverflowSize={1} + columnDefs={columnDefs} + context={{ + query: searchParams.get('query'), + }} + getRowId={(data) => data.data.id} + infiniteInitialRowCount={25} + rowBuffer={20} + rowHeight={table.rowHeight || 40} + rowModelType="infinite" + rowSelection="multiple" + onCellContextMenu={handleContextMenu} + onGridReady={onGridReady} + onGridSizeChanged={handleGridSizeChange} + onRowDoubleClicked={handleRowDoubleClick} + /> + </VirtualGridAutoSizerContainer> + </Stack> + ); }; diff --git a/src/renderer/features/search/components/search-header.tsx b/src/renderer/features/search/components/search-header.tsx index 12ad4e04..b8124d66 100644 --- a/src/renderer/features/search/components/search-header.tsx +++ b/src/renderer/features/search/components/search-header.tsx @@ -11,96 +11,100 @@ import { useContainerQuery } from '/@/renderer/hooks'; import { AppRoute } from '/@/renderer/router/routes'; interface SearchHeaderProps { - getDatasource: (searchQuery: string, itemType: LibraryItem) => IDatasource | undefined; - navigationId: string; - tableRef: MutableRefObject<AgGridReactType | null>; + getDatasource: (searchQuery: string, itemType: LibraryItem) => IDatasource | undefined; + navigationId: string; + tableRef: MutableRefObject<AgGridReactType | null>; } export const SearchHeader = ({ tableRef, getDatasource, navigationId }: SearchHeaderProps) => { - const { itemType } = useParams() as { itemType: LibraryItem }; - const [searchParams, setSearchParams] = useSearchParams(); - const cq = useContainerQuery(); + const { itemType } = useParams() as { itemType: LibraryItem }; + const [searchParams, setSearchParams] = useSearchParams(); + const cq = useContainerQuery(); - const handleSearch = debounce((e: ChangeEvent<HTMLInputElement>) => { - if (!e.target.value) return; - setSearchParams({ query: e.target.value }, { replace: true, state: { navigationId } }); - const datasource = getDatasource(e.target.value, itemType); - if (!datasource) return; - tableRef.current?.api.setDatasource(datasource); - }, 200); + const handleSearch = debounce((e: ChangeEvent<HTMLInputElement>) => { + if (!e.target.value) return; + setSearchParams({ query: e.target.value }, { replace: true, state: { navigationId } }); + const datasource = getDatasource(e.target.value, itemType); + if (!datasource) return; + tableRef.current?.api.setDatasource(datasource); + }, 200); - return ( - <Stack - ref={cq.ref} - spacing={0} - > - <PageHeader> - <Flex - justify="space-between" - w="100%" + return ( + <Stack + ref={cq.ref} + spacing={0} > - <LibraryHeaderBar> - <LibraryHeaderBar.Title>Search</LibraryHeaderBar.Title> - </LibraryHeaderBar> - <Group> - <SearchInput - // key={`search-input-${initialQuery}`} - defaultValue={searchParams.get('query') || ''} - openedWidth={cq.isMd ? 250 : cq.isSm ? 200 : 150} - onChange={handleSearch} - /> - </Group> - </Flex> - </PageHeader> - <FilterBar> - <Group> - <Button - compact - replace - component={Link} - fw={600} - size="md" - state={{ navigationId }} - to={{ - pathname: generatePath(AppRoute.SEARCH, { itemType: LibraryItem.SONG }), - search: searchParams.toString(), - }} - variant={itemType === LibraryItem.SONG ? 'filled' : 'subtle'} - > - Tracks - </Button> - <Button - compact - replace - component={Link} - fw={600} - size="md" - state={{ navigationId }} - to={{ - pathname: generatePath(AppRoute.SEARCH, { itemType: LibraryItem.ALBUM }), - search: searchParams.toString(), - }} - variant={itemType === LibraryItem.ALBUM ? 'filled' : 'subtle'} - > - Albums - </Button> - <Button - compact - replace - component={Link} - fw={600} - size="md" - state={{ navigationId }} - to={{ - pathname: generatePath(AppRoute.SEARCH, { itemType: LibraryItem.ALBUM_ARTIST }), - search: searchParams.toString(), - }} - variant={itemType === LibraryItem.ALBUM_ARTIST ? 'filled' : 'subtle'} - > - Artists - </Button> - </Group> - </FilterBar> - </Stack> - ); + <PageHeader> + <Flex + justify="space-between" + w="100%" + > + <LibraryHeaderBar> + <LibraryHeaderBar.Title>Search</LibraryHeaderBar.Title> + </LibraryHeaderBar> + <Group> + <SearchInput + // key={`search-input-${initialQuery}`} + defaultValue={searchParams.get('query') || ''} + openedWidth={cq.isMd ? 250 : cq.isSm ? 200 : 150} + onChange={handleSearch} + /> + </Group> + </Flex> + </PageHeader> + <FilterBar> + <Group> + <Button + compact + replace + component={Link} + fw={600} + size="md" + state={{ navigationId }} + to={{ + pathname: generatePath(AppRoute.SEARCH, { itemType: LibraryItem.SONG }), + search: searchParams.toString(), + }} + variant={itemType === LibraryItem.SONG ? 'filled' : 'subtle'} + > + Tracks + </Button> + <Button + compact + replace + component={Link} + fw={600} + size="md" + state={{ navigationId }} + to={{ + pathname: generatePath(AppRoute.SEARCH, { + itemType: LibraryItem.ALBUM, + }), + search: searchParams.toString(), + }} + variant={itemType === LibraryItem.ALBUM ? 'filled' : 'subtle'} + > + Albums + </Button> + <Button + compact + replace + component={Link} + fw={600} + size="md" + state={{ navigationId }} + to={{ + pathname: generatePath(AppRoute.SEARCH, { + itemType: LibraryItem.ALBUM_ARTIST, + }), + search: searchParams.toString(), + }} + variant={itemType === LibraryItem.ALBUM_ARTIST ? 'filled' : 'subtle'} + > + Artists + </Button> + </Group> + </FilterBar> + </Stack> + ); }; diff --git a/src/renderer/features/search/components/server-commands.tsx b/src/renderer/features/search/components/server-commands.tsx index 8042b863..17b8be66 100644 --- a/src/renderer/features/search/components/server-commands.tsx +++ b/src/renderer/features/search/components/server-commands.tsx @@ -8,51 +8,51 @@ import { useNavigate } from 'react-router'; import { AppRoute } from '/@/renderer/router/routes'; interface ServerCommandsProps { - handleClose: () => void; - setPages: (pages: CommandPalettePages[]) => void; - setQuery: Dispatch<string>; + handleClose: () => void; + setPages: (pages: CommandPalettePages[]) => void; + setQuery: Dispatch<string>; } export const ServerCommands = ({ setQuery, setPages, handleClose }: ServerCommandsProps) => { - const serverList = useServerList(); - const navigate = useNavigate(); - const { setCurrentServer } = useAuthStoreActions(); + const serverList = useServerList(); + const navigate = useNavigate(); + const { setCurrentServer } = useAuthStoreActions(); - const handleManageServersModal = useCallback(() => { - openModal({ - children: <ServerList />, - title: 'Manage Servers', - }); - handleClose(); - setQuery(''); - setPages([CommandPalettePages.HOME]); - }, [handleClose, setPages, setQuery]); + const handleManageServersModal = useCallback(() => { + openModal({ + children: <ServerList />, + title: 'Manage Servers', + }); + handleClose(); + setQuery(''); + setPages([CommandPalettePages.HOME]); + }, [handleClose, setPages, setQuery]); - const handleSelectServer = useCallback( - (server: ServerListItem) => { - navigate(AppRoute.HOME); - setCurrentServer(server); - handleClose(); - setQuery(''); - setPages([CommandPalettePages.HOME]); - }, - [handleClose, navigate, setCurrentServer, setPages, setQuery], - ); + const handleSelectServer = useCallback( + (server: ServerListItem) => { + navigate(AppRoute.HOME); + setCurrentServer(server); + handleClose(); + setQuery(''); + setPages([CommandPalettePages.HOME]); + }, + [handleClose, navigate, setCurrentServer, setPages, setQuery], + ); - return ( - <> - <Command.Group heading="Select a server"> - {Object.keys(serverList).map((key) => ( - <Command.Item - key={key} - onSelect={() => handleSelectServer(serverList[key])} - >{`Switch to ${serverList[key].name}...`}</Command.Item> - ))} - </Command.Group> - <Command.Group heading="Manage"> - <Command.Item onSelect={handleManageServersModal}>Manage servers...</Command.Item> - </Command.Group> - <Command.Separator /> - </> - ); + return ( + <> + <Command.Group heading="Select a server"> + {Object.keys(serverList).map((key) => ( + <Command.Item + key={key} + onSelect={() => handleSelectServer(serverList[key])} + >{`Switch to ${serverList[key].name}...`}</Command.Item> + ))} + </Command.Group> + <Command.Group heading="Manage"> + <Command.Item onSelect={handleManageServersModal}>Manage servers...</Command.Item> + </Command.Group> + <Command.Separator /> + </> + ); }; diff --git a/src/renderer/features/search/queries/search-query.ts b/src/renderer/features/search/queries/search-query.ts index a121626d..4f863a8f 100644 --- a/src/renderer/features/search/queries/search-query.ts +++ b/src/renderer/features/search/queries/search-query.ts @@ -6,22 +6,22 @@ import { getServerById } from '/@/renderer/store'; import { api } from '/@/renderer/api'; export const useSearch = (args: QueryHookArgs<SearchQuery>) => { - const { options, query, serverId } = args; - const server = getServerById(serverId); + const { options, query, serverId } = args; + const server = getServerById(serverId); - return useQuery({ - enabled: !!serverId, - queryFn: ({ signal }) => { - if (!server) throw new Error('Server not found'); - return api.controller.search({ - apiClientProps: { - server, - signal, + return useQuery({ + enabled: !!serverId, + queryFn: ({ signal }) => { + if (!server) throw new Error('Server not found'); + return api.controller.search({ + apiClientProps: { + server, + signal, + }, + query, + }); }, - query, - }); - }, - queryKey: queryKeys.search.list(serverId || '', query), - ...options, - }); + queryKey: queryKeys.search.list(serverId || '', query), + ...options, + }); }; diff --git a/src/renderer/features/search/routes/search-route.tsx b/src/renderer/features/search/routes/search-route.tsx index f4e7a46f..adf4513c 100644 --- a/src/renderer/features/search/routes/search-route.tsx +++ b/src/renderer/features/search/routes/search-route.tsx @@ -12,175 +12,175 @@ import { LibraryItem, SearchQuery } from '/@/renderer/api/types'; import { useLocation, useParams } from 'react-router'; const SearchRoute = () => { - const { state: locationState } = useLocation(); - const localNavigationId = useId(); - const navigationId = locationState?.navigationId || localNavigationId; - const { itemType } = useParams() as { itemType: string }; - const tableRef = useRef<AgGridReactType | null>(null); - const server = useCurrentServer(); - const queryClient = useQueryClient(); + const { state: locationState } = useLocation(); + const localNavigationId = useId(); + const navigationId = locationState?.navigationId || localNavigationId; + const { itemType } = useParams() as { itemType: string }; + const tableRef = useRef<AgGridReactType | null>(null); + const server = useCurrentServer(); + const queryClient = useQueryClient(); - const getDatasource = useCallback( - (searchQuery: string, itemType: LibraryItem) => { - let dataSource: IDatasource | undefined; + const getDatasource = useCallback( + (searchQuery: string, itemType: LibraryItem) => { + let dataSource: IDatasource | undefined; - switch (itemType) { - case LibraryItem.ALBUM: - dataSource = { - getRows: async (params) => { - const limit = params.endRow - params.startRow; - const startIndex = params.startRow; + switch (itemType) { + case LibraryItem.ALBUM: + dataSource = { + getRows: async (params) => { + const limit = params.endRow - params.startRow; + const startIndex = params.startRow; - const query: SearchQuery = { - albumArtistLimit: 0, - albumArtistStartIndex: 0, - albumLimit: limit, - albumStartIndex: startIndex, - query: searchQuery || ' ', - songLimit: 0, - songStartIndex: 0, - }; + const query: SearchQuery = { + albumArtistLimit: 0, + albumArtistStartIndex: 0, + albumLimit: limit, + albumStartIndex: startIndex, + query: searchQuery || ' ', + songLimit: 0, + songStartIndex: 0, + }; - const queryKey = queryKeys.search.list(server?.id || '', query); + const queryKey = queryKeys.search.list(server?.id || '', query); - const res = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.search({ - apiClientProps: { - server, - signal, - }, - query, - }), - { cacheTime: 1000 * 60 }, - ); + const res = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.search({ + apiClientProps: { + server, + signal, + }, + query, + }), + { cacheTime: 1000 * 60 }, + ); - if (!res) return; + if (!res) return; - const items = res.albums || []; - const numOfItems = items.length; + const items = res.albums || []; + const numOfItems = items.length; - let lastRow = -1; - if (numOfItems < limit) { - lastRow = startIndex + numOfItems; - } + let lastRow = -1; + if (numOfItems < limit) { + lastRow = startIndex + numOfItems; + } - params.successCallback(items, lastRow); - }, - }; - break; - case LibraryItem.ALBUM_ARTIST: - dataSource = { - getRows: async (params) => { - const limit = params.endRow - params.startRow; - const startIndex = params.startRow; + params.successCallback(items, lastRow); + }, + }; + break; + case LibraryItem.ALBUM_ARTIST: + dataSource = { + getRows: async (params) => { + const limit = params.endRow - params.startRow; + const startIndex = params.startRow; - const query: SearchQuery = { - albumArtistLimit: limit, - albumArtistStartIndex: startIndex, - albumLimit: 0, - albumStartIndex: 0, - query: searchQuery || ' ', - songLimit: 0, - songStartIndex: 0, - }; + const query: SearchQuery = { + albumArtistLimit: limit, + albumArtistStartIndex: startIndex, + albumLimit: 0, + albumStartIndex: 0, + query: searchQuery || ' ', + songLimit: 0, + songStartIndex: 0, + }; - const queryKey = queryKeys.search.list(server?.id || '', query); + const queryKey = queryKeys.search.list(server?.id || '', query); - const res = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.search({ - apiClientProps: { - server, - signal, - }, - query, - }), - { cacheTime: 1000 * 60 }, - ); + const res = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.search({ + apiClientProps: { + server, + signal, + }, + query, + }), + { cacheTime: 1000 * 60 }, + ); - if (!res) return; + if (!res) return; - const items = res.albumArtists || []; - const numOfItems = items.length; + const items = res.albumArtists || []; + const numOfItems = items.length; - let lastRow = -1; - if (numOfItems < limit) { - lastRow = startIndex + numOfItems; - } + let lastRow = -1; + if (numOfItems < limit) { + lastRow = startIndex + numOfItems; + } - params.successCallback(items, lastRow); - }, - }; - break; - case LibraryItem.SONG: - dataSource = { - getRows: async (params) => { - const limit = params.endRow - params.startRow; - const startIndex = params.startRow; + params.successCallback(items, lastRow); + }, + }; + break; + case LibraryItem.SONG: + dataSource = { + getRows: async (params) => { + const limit = params.endRow - params.startRow; + const startIndex = params.startRow; - const query: SearchQuery = { - albumArtistLimit: 0, - albumArtistStartIndex: 0, - albumLimit: 0, - albumStartIndex: 0, - query: searchQuery || ' ', - songLimit: limit, - songStartIndex: startIndex, - }; + const query: SearchQuery = { + albumArtistLimit: 0, + albumArtistStartIndex: 0, + albumLimit: 0, + albumStartIndex: 0, + query: searchQuery || ' ', + songLimit: limit, + songStartIndex: startIndex, + }; - const queryKey = queryKeys.search.list(server?.id || '', query); + const queryKey = queryKeys.search.list(server?.id || '', query); - const res = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.search({ - apiClientProps: { - server, - signal, - }, - query, - }), - { cacheTime: 1000 * 60 }, - ); + const res = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.search({ + apiClientProps: { + server, + signal, + }, + query, + }), + { cacheTime: 1000 * 60 }, + ); - if (!res) return; + if (!res) return; - const items = res.songs || []; - const numOfItems = items.length; + const items = res.songs || []; + const numOfItems = items.length; - let lastRow = -1; - if (numOfItems < limit) { - lastRow = startIndex + numOfItems; - } + let lastRow = -1; + if (numOfItems < limit) { + lastRow = startIndex + numOfItems; + } - params.successCallback(items, lastRow); - }, - }; - break; - } + params.successCallback(items, lastRow); + }, + }; + break; + } - return dataSource; - }, - [queryClient, server], - ); + return dataSource; + }, + [queryClient, server], + ); - return ( - <AnimatedPage key={`search-${navigationId}`}> - <SearchHeader - getDatasource={getDatasource} - navigationId={navigationId} - tableRef={tableRef} - /> - <SearchContent - key={`page-${itemType}`} - getDatasource={getDatasource} - tableRef={tableRef} - /> - </AnimatedPage> - ); + return ( + <AnimatedPage key={`search-${navigationId}`}> + <SearchHeader + getDatasource={getDatasource} + navigationId={navigationId} + tableRef={tableRef} + /> + <SearchContent + key={`page-${itemType}`} + getDatasource={getDatasource} + tableRef={tableRef} + /> + </AnimatedPage> + ); }; export default SearchRoute; diff --git a/src/renderer/features/servers/components/add-server-form.tsx b/src/renderer/features/servers/components/add-server-form.tsx index a18269e8..31e4e2d0 100644 --- a/src/renderer/features/servers/components/add-server-form.tsx +++ b/src/renderer/features/servers/components/add-server-form.tsx @@ -14,154 +14,154 @@ import { api } from '/@/renderer/api'; const localSettings = isElectron() ? window.electron.localSettings : null; const SERVER_TYPES = [ - { label: 'Jellyfin', value: ServerType.JELLYFIN }, - { label: 'Navidrome', value: ServerType.NAVIDROME }, - // { label: 'Subsonic', value: ServerType.SUBSONIC }, + { label: 'Jellyfin', value: ServerType.JELLYFIN }, + { label: 'Navidrome', value: ServerType.NAVIDROME }, + // { label: 'Subsonic', value: ServerType.SUBSONIC }, ]; interface AddServerFormProps { - onCancel: () => void; + onCancel: () => void; } export const AddServerForm = ({ onCancel }: AddServerFormProps) => { - const focusTrapRef = useFocusTrap(true); - const [isLoading, setIsLoading] = useState(false); - const { addServer, setCurrentServer } = useAuthStoreActions(); - const serverList = useAuthStore((state) => state.serverList); + const focusTrapRef = useFocusTrap(true); + const [isLoading, setIsLoading] = useState(false); + const { addServer, setCurrentServer } = useAuthStoreActions(); + const serverList = useAuthStore((state) => state.serverList); - const form = useForm({ - initialValues: { - legacyAuth: false, - name: '', - password: '', - savePassword: false, - type: ServerType.JELLYFIN, - url: 'http://', - username: '', - }, - }); - - const isSubmitDisabled = !form.values.name || !form.values.url || !form.values.username; - - const handleSubmit = form.onSubmit(async (values) => { - const authFunction = api.controller.authenticate; - - if (!authFunction) { - return toast.error({ message: 'Selected server type is invalid' }); - } - - try { - setIsLoading(true); - const data: AuthenticationResponse | undefined = await authFunction( - values.url, - { - legacy: values.legacyAuth, - password: values.password, - username: values.username, + const form = useForm({ + initialValues: { + legacyAuth: false, + name: '', + password: '', + savePassword: false, + type: ServerType.JELLYFIN, + url: 'http://', + username: '', }, - values.type, - ); + }); - if (!data) { - return toast.error({ message: 'Authentication failed' }); - } + const isSubmitDisabled = !form.values.name || !form.values.url || !form.values.username; - const serverItem = { - credential: data.credential, - id: nanoid(), - name: values.name, - ndCredential: data.ndCredential, - type: values.type, - url: values.url.replace(/\/$/, ''), - userId: data.userId, - username: data.username, - }; + const handleSubmit = form.onSubmit(async (values) => { + const authFunction = api.controller.authenticate; - addServer(serverItem); - setCurrentServer(serverItem); - closeAllModals(); - - if (Object.keys(serverList).length === 0) { - toast.success({ message: 'Server has been added, reloading...' }); - setTimeout(() => window.location.reload(), 2000); - } else { - toast.success({ message: 'Server has been added' }); - } - - if (localSettings && values.savePassword) { - const saved = await localSettings.passwordSet(values.password, serverItem.id); - if (!saved) { - toast.error({ message: 'Could not save password' }); + if (!authFunction) { + return toast.error({ message: 'Selected server type is invalid' }); } - } - } catch (err: any) { - setIsLoading(false); - return toast.error({ message: err?.message }); - } - return setIsLoading(false); - }); + try { + setIsLoading(true); + const data: AuthenticationResponse | undefined = await authFunction( + values.url, + { + legacy: values.legacyAuth, + password: values.password, + username: values.username, + }, + values.type, + ); - return ( - <form onSubmit={handleSubmit}> - <Stack - ref={focusTrapRef} - m={5} - > - <SegmentedControl - data={SERVER_TYPES} - {...form.getInputProps('type')} - /> - <Group grow> - <TextInput - data-autofocus - label="Name" - {...form.getInputProps('name')} - /> - <TextInput - label="Url" - {...form.getInputProps('url')} - /> - </Group> - <TextInput - label="Username" - {...form.getInputProps('username')} - /> - <PasswordInput - label="Password" - {...form.getInputProps('password')} - /> - {localSettings && form.values.type === ServerType.NAVIDROME && ( - <Checkbox - label="Save password" - {...form.getInputProps('savePassword', { - type: 'checkbox', - })} - /> - )} - {form.values.type === ServerType.SUBSONIC && ( - <Checkbox - label="Enable legacy authentication" - {...form.getInputProps('legacyAuth', { type: 'checkbox' })} - /> - )} - <Group position="right"> - <Button - variant="subtle" - onClick={onCancel} - > - Cancel - </Button> - <Button - disabled={isSubmitDisabled} - loading={isLoading} - type="submit" - variant="filled" - > - Add - </Button> - </Group> - </Stack> - </form> - ); + if (!data) { + return toast.error({ message: 'Authentication failed' }); + } + + const serverItem = { + credential: data.credential, + id: nanoid(), + name: values.name, + ndCredential: data.ndCredential, + type: values.type, + url: values.url.replace(/\/$/, ''), + userId: data.userId, + username: data.username, + }; + + addServer(serverItem); + setCurrentServer(serverItem); + closeAllModals(); + + if (Object.keys(serverList).length === 0) { + toast.success({ message: 'Server has been added, reloading...' }); + setTimeout(() => window.location.reload(), 2000); + } else { + toast.success({ message: 'Server has been added' }); + } + + if (localSettings && values.savePassword) { + const saved = await localSettings.passwordSet(values.password, serverItem.id); + if (!saved) { + toast.error({ message: 'Could not save password' }); + } + } + } catch (err: any) { + setIsLoading(false); + return toast.error({ message: err?.message }); + } + + return setIsLoading(false); + }); + + return ( + <form onSubmit={handleSubmit}> + <Stack + ref={focusTrapRef} + m={5} + > + <SegmentedControl + data={SERVER_TYPES} + {...form.getInputProps('type')} + /> + <Group grow> + <TextInput + data-autofocus + label="Name" + {...form.getInputProps('name')} + /> + <TextInput + label="Url" + {...form.getInputProps('url')} + /> + </Group> + <TextInput + label="Username" + {...form.getInputProps('username')} + /> + <PasswordInput + label="Password" + {...form.getInputProps('password')} + /> + {localSettings && form.values.type === ServerType.NAVIDROME && ( + <Checkbox + label="Save password" + {...form.getInputProps('savePassword', { + type: 'checkbox', + })} + /> + )} + {form.values.type === ServerType.SUBSONIC && ( + <Checkbox + label="Enable legacy authentication" + {...form.getInputProps('legacyAuth', { type: 'checkbox' })} + /> + )} + <Group position="right"> + <Button + variant="subtle" + onClick={onCancel} + > + Cancel + </Button> + <Button + disabled={isSubmitDisabled} + loading={isLoading} + type="submit" + variant="filled" + > + Add + </Button> + </Group> + </Stack> + </form> + ); }; diff --git a/src/renderer/features/servers/components/edit-server-form.tsx b/src/renderer/features/servers/components/edit-server-form.tsx index 63412e65..fece0ee6 100644 --- a/src/renderer/features/servers/components/edit-server-form.tsx +++ b/src/renderer/features/servers/components/edit-server-form.tsx @@ -14,157 +14,157 @@ import { api } from '/@/renderer/api'; const localSettings = isElectron() ? window.electron.localSettings : null; interface EditServerFormProps { - isUpdate?: boolean; - onCancel: () => void; - password?: string; - server: ServerListItem; + isUpdate?: boolean; + onCancel: () => void; + password?: string; + server: ServerListItem; } const ModifiedFieldIndicator = () => { - return ( - <Tooltip label="Field has been modified"> - <span> - <RiInformationLine color="red" /> - </span> - </Tooltip> - ); + return ( + <Tooltip label="Field has been modified"> + <span> + <RiInformationLine color="red" /> + </span> + </Tooltip> + ); }; export const EditServerForm = ({ isUpdate, password, server, onCancel }: EditServerFormProps) => { - const { updateServer } = useAuthStoreActions(); - const focusTrapRef = useFocusTrap(); - const [isLoading, setIsLoading] = useState(false); + const { updateServer } = useAuthStoreActions(); + const focusTrapRef = useFocusTrap(); + const [isLoading, setIsLoading] = useState(false); - const form = useForm({ - initialValues: { - legacyAuth: false, - name: server?.name, - password: password || '', - savePassword: server.savePassword || false, - type: server?.type, - url: server?.url, - username: server?.username, - }, - }); - - const isSubsonic = form.values.type === ServerType.SUBSONIC; - const isNavidrome = form.values.type === ServerType.NAVIDROME; - - const handleSubmit = form.onSubmit(async (values) => { - const authFunction = api.controller.authenticate; - - if (!authFunction) { - return toast.error({ message: 'Selected server type is invalid' }); - } - - try { - setIsLoading(true); - const data: AuthenticationResponse | undefined = await authFunction( - values.url, - { - legacy: values.legacyAuth, - password: values.password, - username: values.username, + const form = useForm({ + initialValues: { + legacyAuth: false, + name: server?.name, + password: password || '', + savePassword: server.savePassword || false, + type: server?.type, + url: server?.url, + username: server?.username, }, - values.type, - ); + }); - if (!data) { - return toast.error({ message: 'Authentication failed' }); - } + const isSubsonic = form.values.type === ServerType.SUBSONIC; + const isNavidrome = form.values.type === ServerType.NAVIDROME; - const serverItem = { - credential: data.credential, - name: values.name, - ndCredential: data.ndCredential, - savePassword: values.savePassword, - type: values.type, - url: values.url, - userId: data.userId, - username: data.username, - }; + const handleSubmit = form.onSubmit(async (values) => { + const authFunction = api.controller.authenticate; - updateServer(server.id, serverItem); - toast.success({ message: 'Server has been updated' }); - - if (localSettings) { - if (values.savePassword) { - const saved = await localSettings.passwordSet(values.password, server.id); - if (!saved) { - toast.error({ message: 'Could not save password' }); - } - } else { - localSettings.passwordRemove(server.id); + if (!authFunction) { + return toast.error({ message: 'Selected server type is invalid' }); } - } - } catch (err: any) { - setIsLoading(false); - return toast.error({ message: err?.message }); - } - if (isUpdate) closeAllModals(); - return setIsLoading(false); - }); + try { + setIsLoading(true); + const data: AuthenticationResponse | undefined = await authFunction( + values.url, + { + legacy: values.legacyAuth, + password: values.password, + username: values.username, + }, + values.type, + ); - return ( - <form onSubmit={handleSubmit}> - <Stack ref={focusTrapRef}> - <TextInput - required - label="Name" - rightSection={form.isDirty('name') && <ModifiedFieldIndicator />} - {...form.getInputProps('name')} - /> - <TextInput - required - label="Url" - rightSection={form.isDirty('url') && <ModifiedFieldIndicator />} - {...form.getInputProps('url')} - /> - <TextInput - required - label="Username" - rightSection={form.isDirty('username') && <ModifiedFieldIndicator />} - {...form.getInputProps('username')} - /> - <PasswordInput - data-autofocus - required - label="Password" - {...form.getInputProps('password')} - /> - {localSettings && isNavidrome && ( - <Checkbox - label="Save password" - {...form.getInputProps('savePassword', { - type: 'checkbox', - })} - /> - )} - {isSubsonic && ( - <Checkbox - label="Enable legacy authentication" - {...form.getInputProps('legacyAuth', { - type: 'checkbox', - })} - /> - )} - <Group position="right"> - <Button - variant="subtle" - onClick={onCancel} - > - Cancel - </Button> - <Button - loading={isLoading} - type="submit" - variant="filled" - > - Save - </Button> - </Group> - </Stack> - </form> - ); + if (!data) { + return toast.error({ message: 'Authentication failed' }); + } + + const serverItem = { + credential: data.credential, + name: values.name, + ndCredential: data.ndCredential, + savePassword: values.savePassword, + type: values.type, + url: values.url, + userId: data.userId, + username: data.username, + }; + + updateServer(server.id, serverItem); + toast.success({ message: 'Server has been updated' }); + + if (localSettings) { + if (values.savePassword) { + const saved = await localSettings.passwordSet(values.password, server.id); + if (!saved) { + toast.error({ message: 'Could not save password' }); + } + } else { + localSettings.passwordRemove(server.id); + } + } + } catch (err: any) { + setIsLoading(false); + return toast.error({ message: err?.message }); + } + + if (isUpdate) closeAllModals(); + return setIsLoading(false); + }); + + return ( + <form onSubmit={handleSubmit}> + <Stack ref={focusTrapRef}> + <TextInput + required + label="Name" + rightSection={form.isDirty('name') && <ModifiedFieldIndicator />} + {...form.getInputProps('name')} + /> + <TextInput + required + label="Url" + rightSection={form.isDirty('url') && <ModifiedFieldIndicator />} + {...form.getInputProps('url')} + /> + <TextInput + required + label="Username" + rightSection={form.isDirty('username') && <ModifiedFieldIndicator />} + {...form.getInputProps('username')} + /> + <PasswordInput + data-autofocus + required + label="Password" + {...form.getInputProps('password')} + /> + {localSettings && isNavidrome && ( + <Checkbox + label="Save password" + {...form.getInputProps('savePassword', { + type: 'checkbox', + })} + /> + )} + {isSubsonic && ( + <Checkbox + label="Enable legacy authentication" + {...form.getInputProps('legacyAuth', { + type: 'checkbox', + })} + /> + )} + <Group position="right"> + <Button + variant="subtle" + onClick={onCancel} + > + Cancel + </Button> + <Button + loading={isLoading} + type="submit" + variant="filled" + > + Save + </Button> + </Group> + </Stack> + </form> + ); }; diff --git a/src/renderer/features/servers/components/server-list-item.tsx b/src/renderer/features/servers/components/server-list-item.tsx index 45b2e956..bfc8ca01 100644 --- a/src/renderer/features/servers/components/server-list-item.tsx +++ b/src/renderer/features/servers/components/server-list-item.tsx @@ -12,91 +12,91 @@ import { ServerListItem as ServerItem } from '/@/renderer/types'; const localSettings = isElectron() ? window.electron.localSettings : null; interface ServerListItemProps { - server: ServerItem; + server: ServerItem; } export const ServerListItem = ({ server }: ServerListItemProps) => { - const [edit, editHandlers] = useDisclosure(false); - const [savedPassword, setSavedPassword] = useState(''); - const { deleteServer } = useAuthStoreActions(); + const [edit, editHandlers] = useDisclosure(false); + const [savedPassword, setSavedPassword] = useState(''); + const { deleteServer } = useAuthStoreActions(); - const handleDeleteServer = () => { - deleteServer(server.id); - localSettings?.passwordRemove(server.name); - }; + const handleDeleteServer = () => { + deleteServer(server.id); + localSettings?.passwordRemove(server.name); + }; - const handleEdit = useCallback(() => { - if (!edit && localSettings && server.savePassword) { - localSettings - .passwordGet(server.id) - .then((password: string | null) => { - if (password) { - setSavedPassword(password); - } else { + const handleEdit = useCallback(() => { + if (!edit && localSettings && server.savePassword) { + localSettings + .passwordGet(server.id) + .then((password: string | null) => { + if (password) { + setSavedPassword(password); + } else { + setSavedPassword(''); + } + editHandlers.open(); + return null; + }) + .catch((error: any) => { + console.error(error); + setSavedPassword(''); + editHandlers.open(); + }); + } else { setSavedPassword(''); - } - editHandlers.open(); - return null; - }) - .catch((error: any) => { - console.error(error); - setSavedPassword(''); - editHandlers.open(); - }); - } else { - setSavedPassword(''); - editHandlers.open(); - } - }, [edit, editHandlers, server.id, server.savePassword]); - - return ( - <Stack> - <ServerSection - title={ - <Group position="apart"> - <Text>Server details</Text> - </Group> + editHandlers.open(); } - > - {edit ? ( - <EditServerForm - password={savedPassword} - server={server} - onCancel={() => editHandlers.toggle()} - /> - ) : ( - <Stack> - <Group noWrap> - <Stack> - <Text>URL</Text> - <Text>Username</Text> - </Stack> - <Stack> - <Text>{server.url}</Text> - <Text>{server.username}</Text> - </Stack> - </Group> - <Group grow> - <Button - leftIcon={<RiEdit2Fill />} - tooltip={{ label: 'Edit server details' }} + }, [edit, editHandlers, server.id, server.savePassword]); + + return ( + <Stack> + <ServerSection + title={ + <Group position="apart"> + <Text>Server details</Text> + </Group> + } + > + {edit ? ( + <EditServerForm + password={savedPassword} + server={server} + onCancel={() => editHandlers.toggle()} + /> + ) : ( + <Stack> + <Group noWrap> + <Stack> + <Text>URL</Text> + <Text>Username</Text> + </Stack> + <Stack> + <Text>{server.url}</Text> + <Text>{server.username}</Text> + </Stack> + </Group> + <Group grow> + <Button + leftIcon={<RiEdit2Fill />} + tooltip={{ label: 'Edit server details' }} + variant="subtle" + onClick={() => handleEdit()} + > + Edit + </Button> + </Group> + </Stack> + )} + </ServerSection> + <Divider my="sm" /> + <TimeoutButton + leftIcon={<RiDeleteBin2Line />} + timeoutProps={{ callback: handleDeleteServer, duration: 1000 }} variant="subtle" - onClick={() => handleEdit()} - > - Edit - </Button> - </Group> - </Stack> - )} - </ServerSection> - <Divider my="sm" /> - <TimeoutButton - leftIcon={<RiDeleteBin2Line />} - timeoutProps={{ callback: handleDeleteServer, duration: 1000 }} - variant="subtle" - > - Remove server - </TimeoutButton> - </Stack> - ); + > + Remove server + </TimeoutButton> + </Stack> + ); }; diff --git a/src/renderer/features/servers/components/server-list.tsx b/src/renderer/features/servers/components/server-list.tsx index fd8d38c6..0c8d79d3 100644 --- a/src/renderer/features/servers/components/server-list.tsx +++ b/src/renderer/features/servers/components/server-list.tsx @@ -13,106 +13,106 @@ import { titleCase } from '/@/renderer/utils'; const localSettings = isElectron() ? window.electron.localSettings : null; export const ServerList = () => { - const serverListQuery = useServerList(); + const serverListQuery = useServerList(); - const handleAddServerModal = () => { - openContextModal({ - innerProps: { - modalBody: (vars: ContextModalVars) => ( - <AddServerForm onCancel={() => vars.context.closeModal(vars.id)} /> - ), - }, - modal: 'base', - title: 'Add server', + const handleAddServerModal = () => { + openContextModal({ + innerProps: { + modalBody: (vars: ContextModalVars) => ( + <AddServerForm onCancel={() => vars.context.closeModal(vars.id)} /> + ), + }, + modal: 'base', + title: 'Add server', + }); + }; + + const [ignoreCORS, setIgnoreCORS] = useLocalStorage({ + defaultValue: 'false', + key: 'ignore_cors', }); - }; - const [ignoreCORS, setIgnoreCORS] = useLocalStorage({ - defaultValue: 'false', - key: 'ignore_cors', - }); + const [ignoreSSL, setIgnoreSSL] = useLocalStorage({ + defaultValue: 'false', + key: 'ignore_ssl', + }); - const [ignoreSSL, setIgnoreSSL] = useLocalStorage({ - defaultValue: 'false', - key: 'ignore_ssl', - }); + const handleUpdateIgnoreCORS = (e: ChangeEvent<HTMLInputElement>) => { + setIgnoreCORS(String(e.currentTarget.checked)); - const handleUpdateIgnoreCORS = (e: ChangeEvent<HTMLInputElement>) => { - setIgnoreCORS(String(e.currentTarget.checked)); + if (isElectron()) { + localSettings?.set('ignore_cors', e.currentTarget.checked); + } + }; - if (isElectron()) { - localSettings?.set('ignore_cors', e.currentTarget.checked); - } - }; + const handleUpdateIgnoreSSL = (e: ChangeEvent<HTMLInputElement>) => { + setIgnoreSSL(String(e.currentTarget.checked)); - const handleUpdateIgnoreSSL = (e: ChangeEvent<HTMLInputElement>) => { - setIgnoreSSL(String(e.currentTarget.checked)); + if (isElectron()) { + localSettings?.set('ignore_ssl', e.currentTarget.checked); + } + }; - if (isElectron()) { - localSettings?.set('ignore_ssl', e.currentTarget.checked); - } - }; - - return ( - <> - <Group - mb={10} - position="right" - sx={{ - position: 'absolute', - right: 55, - transform: 'translateY(-3.5rem)', - zIndex: 2000, - }} - > - <Button - autoFocus - compact - leftIcon={<RiAddFill size={15} />} - size="sm" - variant="filled" - onClick={handleAddServerModal} - > - Add server - </Button> - </Group> - <Stack> - <Accordion variant="separated"> - {Object.keys(serverListQuery)?.map((serverId) => { - const server = serverListQuery[serverId]; - return ( - <Accordion.Item - key={server.id} - value={server.name} - > - <Accordion.Control icon={<RiServerFill size={15} />}> - <Group position="apart"> - {titleCase(server?.type)} - {server?.name} - </Group> - </Accordion.Control> - <Accordion.Panel> - <ServerListItem server={server} /> - </Accordion.Panel> - </Accordion.Item> - ); - })} - </Accordion> - <Divider /> - <Group> - <Switch - checked={ignoreCORS === 'true'} - label="Ignore CORS (requires restart)" - onChange={handleUpdateIgnoreCORS} - /> - </Group> - <Group> - <Switch - checked={ignoreSSL === 'true'} - label="Ignore SSL (requires restart)" - onChange={handleUpdateIgnoreSSL} - /> - </Group> - </Stack> - </> - ); + return ( + <> + <Group + mb={10} + position="right" + sx={{ + position: 'absolute', + right: 55, + transform: 'translateY(-3.5rem)', + zIndex: 2000, + }} + > + <Button + autoFocus + compact + leftIcon={<RiAddFill size={15} />} + size="sm" + variant="filled" + onClick={handleAddServerModal} + > + Add server + </Button> + </Group> + <Stack> + <Accordion variant="separated"> + {Object.keys(serverListQuery)?.map((serverId) => { + const server = serverListQuery[serverId]; + return ( + <Accordion.Item + key={server.id} + value={server.name} + > + <Accordion.Control icon={<RiServerFill size={15} />}> + <Group position="apart"> + {titleCase(server?.type)} - {server?.name} + </Group> + </Accordion.Control> + <Accordion.Panel> + <ServerListItem server={server} /> + </Accordion.Panel> + </Accordion.Item> + ); + })} + </Accordion> + <Divider /> + <Group> + <Switch + checked={ignoreCORS === 'true'} + label="Ignore CORS (requires restart)" + onChange={handleUpdateIgnoreCORS} + /> + </Group> + <Group> + <Switch + checked={ignoreSSL === 'true'} + label="Ignore SSL (requires restart)" + onChange={handleUpdateIgnoreSSL} + /> + </Group> + </Stack> + </> + ); }; diff --git a/src/renderer/features/servers/components/server-section.tsx b/src/renderer/features/servers/components/server-section.tsx index 38c61280..928f1019 100644 --- a/src/renderer/features/servers/components/server-section.tsx +++ b/src/renderer/features/servers/components/server-section.tsx @@ -3,22 +3,22 @@ import styled from 'styled-components'; import { Text } from '/@/renderer/components'; interface ServerSectionProps { - children: React.ReactNode; - title: string | React.ReactNode; + children: React.ReactNode; + title: string | React.ReactNode; } const Container = styled.div``; const Section = styled.div` - padding: 1rem; - border: 1px dashed var(--generic-border-color); + padding: 1rem; + border: 1px dashed var(--generic-border-color); `; export const ServerSection = ({ title, children }: ServerSectionProps) => { - return ( - <Container> - {React.isValidElement(title) ? title : <Text>{title}</Text>} - <Section>{children}</Section> - </Container> - ); + return ( + <Container> + {React.isValidElement(title) ? title : <Text>{title}</Text>} + <Section>{children}</Section> + </Container> + ); }; diff --git a/src/renderer/features/settings/components/general/application-settings.tsx b/src/renderer/features/settings/components/general/application-settings.tsx index da952335..b15b8d2e 100644 --- a/src/renderer/features/settings/components/general/application-settings.tsx +++ b/src/renderer/features/settings/components/general/application-settings.tsx @@ -1,87 +1,87 @@ import isElectron from 'is-electron'; import { NumberInput, Select } from '/@/renderer/components'; import { - SettingsSection, - SettingOption, + SettingsSection, + SettingOption, } from '/@/renderer/features/settings/components/settings-section'; import { useGeneralSettings, useSettingsStoreActions } from '/@/renderer/store/settings.store'; const localSettings = isElectron() ? window.electron.localSettings : null; const FONT_OPTIONS = [ - { label: 'Archivo', value: 'Archivo' }, - { label: 'Fredoka', value: 'Fredoka' }, - { label: 'League Spartan', value: 'League Spartan' }, - { label: 'Lexend', value: 'Lexend' }, - { label: 'Poppins', value: 'Poppins' }, - { label: 'Raleway', value: 'Raleway' }, - { label: 'Sora', value: 'Sora' }, - { label: 'Work Sans', value: 'Work Sans' }, + { label: 'Archivo', value: 'Archivo' }, + { label: 'Fredoka', value: 'Fredoka' }, + { label: 'League Spartan', value: 'League Spartan' }, + { label: 'Lexend', value: 'Lexend' }, + { label: 'Poppins', value: 'Poppins' }, + { label: 'Raleway', value: 'Raleway' }, + { label: 'Sora', value: 'Sora' }, + { label: 'Work Sans', value: 'Work Sans' }, ]; export const ApplicationSettings = () => { - const settings = useGeneralSettings(); - const { setSettings } = useSettingsStoreActions(); + const settings = useGeneralSettings(); + const { setSettings } = useSettingsStoreActions(); - const options: SettingOption[] = [ - { - control: ( - <Select - disabled - data={[]} - /> - ), - description: 'Sets the application language', - isHidden: false, - title: 'Language', - }, - { - control: ( - <Select - searchable - data={FONT_OPTIONS} - defaultValue={settings.fontContent} - onChange={(e) => { - if (!e) return; - setSettings({ - general: { - ...settings, - fontContent: e, - }, - }); - }} - /> - ), - description: 'Sets the application content font', - isHidden: false, - title: 'Font (Content)', - }, - { - control: ( - <NumberInput - max={300} - min={50} - value={settings.zoomFactor} - onBlur={(e) => { - if (!e) return; - const newVal = e.currentTarget.value - ? Math.min(Math.max(Number(e.currentTarget.value), 50), 300) - : settings.zoomFactor; - setSettings({ - general: { - ...settings, - zoomFactor: newVal, - }, - }); - localSettings.setZoomFactor(newVal); - }} - /> - ), - description: 'Sets the application zoom factor in percent', - isHidden: !isElectron(), - title: 'Zoom factor', - }, - ]; + const options: SettingOption[] = [ + { + control: ( + <Select + disabled + data={[]} + /> + ), + description: 'Sets the application language', + isHidden: false, + title: 'Language', + }, + { + control: ( + <Select + searchable + data={FONT_OPTIONS} + defaultValue={settings.fontContent} + onChange={(e) => { + if (!e) return; + setSettings({ + general: { + ...settings, + fontContent: e, + }, + }); + }} + /> + ), + description: 'Sets the application content font', + isHidden: false, + title: 'Font (Content)', + }, + { + control: ( + <NumberInput + max={300} + min={50} + value={settings.zoomFactor} + onBlur={(e) => { + if (!e) return; + const newVal = e.currentTarget.value + ? Math.min(Math.max(Number(e.currentTarget.value), 50), 300) + : settings.zoomFactor; + setSettings({ + general: { + ...settings, + zoomFactor: newVal, + }, + }); + localSettings.setZoomFactor(newVal); + }} + /> + ), + description: 'Sets the application zoom factor in percent', + isHidden: !isElectron(), + title: 'Zoom factor', + }, + ]; - return <SettingsSection options={options} />; + return <SettingsSection options={options} />; }; diff --git a/src/renderer/features/settings/components/general/control-settings.tsx b/src/renderer/features/settings/components/general/control-settings.tsx index 13ab4ea3..f825b019 100644 --- a/src/renderer/features/settings/components/general/control-settings.tsx +++ b/src/renderer/features/settings/components/general/control-settings.tsx @@ -3,196 +3,199 @@ import { Group } from '@mantine/core'; import { Select, Tooltip, NumberInput, Switch, Slider } from '/@/renderer/components'; import { SettingsSection } from '/@/renderer/features/settings/components/settings-section'; import { - SideQueueType, - useGeneralSettings, - useSettingsStoreActions, + SideQueueType, + useGeneralSettings, + useSettingsStoreActions, } from '/@/renderer/store/settings.store'; import { Play } from '/@/renderer/types'; const localSettings = isElectron() ? window.electron.localSettings : null; const SIDE_QUEUE_OPTIONS = [ - { label: 'Fixed', value: 'sideQueue' }, - { label: 'Floating', value: 'sideDrawerQueue' }, + { label: 'Fixed', value: 'sideQueue' }, + { label: 'Floating', value: 'sideDrawerQueue' }, ]; export const ControlSettings = () => { - const settings = useGeneralSettings(); - const { setSettings } = useSettingsStoreActions(); + const settings = useGeneralSettings(); + const { setSettings } = useSettingsStoreActions(); - const controlOptions = [ - { - control: ( - <Switch - aria-label="Toggle skip buttons" - defaultChecked={settings.skipButtons?.enabled} - onChange={(e) => - setSettings({ - general: { - ...settings, - skipButtons: { - ...settings.skipButtons, - enabled: e.currentTarget.checked, - }, - }, - }) - } - /> - ), - description: 'Show or hide the skip buttons on the playerbar', - isHidden: false, - title: 'Show skip buttons', - }, - { - control: ( - <Group> - <Tooltip label="Backward"> - <NumberInput - defaultValue={settings.skipButtons.skipBackwardSeconds} - min={0} - width={75} - onBlur={(e) => - setSettings({ - general: { - ...settings, - skipButtons: { - ...settings.skipButtons, - skipBackwardSeconds: e.currentTarget.value - ? Number(e.currentTarget.value) - : 0, - }, - }, - }) - } - /> - </Tooltip> - <Tooltip label="Forward"> - <NumberInput - defaultValue={settings.skipButtons.skipForwardSeconds} - min={0} - width={75} - onBlur={(e) => - setSettings({ - general: { - ...settings, - skipButtons: { - ...settings.skipButtons, - skipForwardSeconds: e.currentTarget.value ? Number(e.currentTarget.value) : 0, - }, - }, - }) - } - /> - </Tooltip> - </Group> - ), - description: - 'The number (in seconds) to skip forward or backward when using the skip buttons', - isHidden: false, - title: 'Skip duration', - }, - { - control: ( - <Select - data={[ - { label: 'Now', value: Play.NOW }, - { label: 'Next', value: Play.NEXT }, - { label: 'Last', value: Play.LAST }, - ]} - defaultValue={settings.playButtonBehavior} - onChange={(e) => - setSettings({ - general: { - ...settings, - playButtonBehavior: e as Play, - }, - }) - } - /> - ), - description: 'The default behavior of the play button when adding songs to the queue', - isHidden: false, - title: 'Play button behavior', - }, - { - control: ( - <Select - data={SIDE_QUEUE_OPTIONS} - defaultValue={settings.sideQueueType} - onChange={(e) => { - setSettings({ - general: { - ...settings, - sideQueueType: e as SideQueueType, - }, - }); - }} - /> - ), - description: 'The style of the sidebar play queue', - isHidden: false, - title: 'Side play queue style', - }, - { - control: ( - <Switch - defaultChecked={settings.showQueueDrawerButton} - onChange={(e) => { - setSettings({ - general: { - ...settings, - showQueueDrawerButton: e.currentTarget.checked, - }, - }); - }} - /> - ), - description: 'Display a hover icon on the right side of the application view the play queue', - isHidden: false, - title: 'Show floating queue hover area', - }, - { - control: ( - <Slider - defaultValue={settings.volumeWheelStep} - max={20} - min={1} - w={100} - onChangeEnd={(e) => { - setSettings({ - general: { - ...settings, - volumeWheelStep: e, - }, - }); - }} - /> - ), - description: - 'The amount of volume to change when scrolling the mouse wheel on the volume slider', - isHidden: false, - title: 'Volume wheel step', - }, - { - control: ( - <Switch - defaultChecked={settings.resume} - onChange={(e) => { - localSettings?.set('resume', e.target.checked); - setSettings({ - general: { - ...settings, - resume: e.currentTarget.checked, - }, - }); - }} - /> - ), - description: 'When exiting, save the current play queue and restore it when reopening', - isHidden: !isElectron(), - title: 'Save play queue', - }, - ]; + const controlOptions = [ + { + control: ( + <Switch + aria-label="Toggle skip buttons" + defaultChecked={settings.skipButtons?.enabled} + onChange={(e) => + setSettings({ + general: { + ...settings, + skipButtons: { + ...settings.skipButtons, + enabled: e.currentTarget.checked, + }, + }, + }) + } + /> + ), + description: 'Show or hide the skip buttons on the playerbar', + isHidden: false, + title: 'Show skip buttons', + }, + { + control: ( + <Group> + <Tooltip label="Backward"> + <NumberInput + defaultValue={settings.skipButtons.skipBackwardSeconds} + min={0} + width={75} + onBlur={(e) => + setSettings({ + general: { + ...settings, + skipButtons: { + ...settings.skipButtons, + skipBackwardSeconds: e.currentTarget.value + ? Number(e.currentTarget.value) + : 0, + }, + }, + }) + } + /> + </Tooltip> + <Tooltip label="Forward"> + <NumberInput + defaultValue={settings.skipButtons.skipForwardSeconds} + min={0} + width={75} + onBlur={(e) => + setSettings({ + general: { + ...settings, + skipButtons: { + ...settings.skipButtons, + skipForwardSeconds: e.currentTarget.value + ? Number(e.currentTarget.value) + : 0, + }, + }, + }) + } + /> + </Tooltip> + </Group> + ), + description: + 'The number (in seconds) to skip forward or backward when using the skip buttons', + isHidden: false, + title: 'Skip duration', + }, + { + control: ( + <Select + data={[ + { label: 'Now', value: Play.NOW }, + { label: 'Next', value: Play.NEXT }, + { label: 'Last', value: Play.LAST }, + ]} + defaultValue={settings.playButtonBehavior} + onChange={(e) => + setSettings({ + general: { + ...settings, + playButtonBehavior: e as Play, + }, + }) + } + /> + ), + description: 'The default behavior of the play button when adding songs to the queue', + isHidden: false, + title: 'Play button behavior', + }, + { + control: ( + <Select + data={SIDE_QUEUE_OPTIONS} + defaultValue={settings.sideQueueType} + onChange={(e) => { + setSettings({ + general: { + ...settings, + sideQueueType: e as SideQueueType, + }, + }); + }} + /> + ), + description: 'The style of the sidebar play queue', + isHidden: false, + title: 'Side play queue style', + }, + { + control: ( + <Switch + defaultChecked={settings.showQueueDrawerButton} + onChange={(e) => { + setSettings({ + general: { + ...settings, + showQueueDrawerButton: e.currentTarget.checked, + }, + }); + }} + /> + ), + description: + 'Display a hover icon on the right side of the application view the play queue', + isHidden: false, + title: 'Show floating queue hover area', + }, + { + control: ( + <Slider + defaultValue={settings.volumeWheelStep} + max={20} + min={1} + w={100} + onChangeEnd={(e) => { + setSettings({ + general: { + ...settings, + volumeWheelStep: e, + }, + }); + }} + /> + ), + description: + 'The amount of volume to change when scrolling the mouse wheel on the volume slider', + isHidden: false, + title: 'Volume wheel step', + }, + { + control: ( + <Switch + defaultChecked={settings.resume} + onChange={(e) => { + localSettings?.set('resume', e.target.checked); + setSettings({ + general: { + ...settings, + resume: e.currentTarget.checked, + }, + }); + }} + /> + ), + description: 'When exiting, save the current play queue and restore it when reopening', + isHidden: !isElectron(), + title: 'Save play queue', + }, + ]; - return <SettingsSection options={controlOptions} />; + return <SettingsSection options={controlOptions} />; }; diff --git a/src/renderer/features/settings/components/general/general-tab.tsx b/src/renderer/features/settings/components/general/general-tab.tsx index 48968289..19bffa02 100644 --- a/src/renderer/features/settings/components/general/general-tab.tsx +++ b/src/renderer/features/settings/components/general/general-tab.tsx @@ -5,15 +5,15 @@ import { SidebarSettings } from '/@/renderer/features/settings/components/genera import { ThemeSettings } from '/@/renderer/features/settings/components/general/theme-settings'; export const GeneralTab = () => { - return ( - <Stack spacing="md"> - <ApplicationSettings /> - <Divider /> - <ThemeSettings /> - <Divider /> - <ControlSettings /> - <Divider /> - <SidebarSettings /> - </Stack> - ); + return ( + <Stack spacing="md"> + <ApplicationSettings /> + <Divider /> + <ThemeSettings /> + <Divider /> + <ControlSettings /> + <Divider /> + <SidebarSettings /> + </Stack> + ); }; diff --git a/src/renderer/features/settings/components/general/sidebar-settings.tsx b/src/renderer/features/settings/components/general/sidebar-settings.tsx index 6951a8a6..e966c4e6 100644 --- a/src/renderer/features/settings/components/general/sidebar-settings.tsx +++ b/src/renderer/features/settings/components/general/sidebar-settings.tsx @@ -8,126 +8,126 @@ import { useSettingsStoreActions, useGeneralSettings } from '../../../../store/s import { SettingsOptions } from '/@/renderer/features/settings/components/settings-option'; const DragHandle = ({ dragControls }: any) => { - return ( - <MdDragIndicator - color="white" - style={{ cursor: 'grab' }} - onPointerDown={(event) => dragControls.start(event)} - /> - ); + return ( + <MdDragIndicator + color="white" + style={{ cursor: 'grab' }} + onPointerDown={(event) => dragControls.start(event)} + /> + ); }; interface SidebarItem { - disabled: boolean; - id: string; + disabled: boolean; + id: string; } interface DraggableSidebarItemProps { - handleChangeDisabled: (id: string, e: boolean) => void; - item: SidebarItem; + handleChangeDisabled: (id: string, e: boolean) => void; + item: SidebarItem; } const DraggableSidebarItem = ({ item, handleChangeDisabled }: DraggableSidebarItemProps) => { - const dragControls = useDragControls(); + const dragControls = useDragControls(); - return ( - <Reorder.Item - as="div" - dragControls={dragControls} - dragListener={false} - value={item} - > - <Group - noWrap - h="3rem" - style={{ boxShadow: '0 1px 3px rgba(0,0,0,.1)' }} - > - <Checkbox - checked={!item.disabled} - onChange={(e) => handleChangeDisabled(item.id, e.target.checked)} - /> - <DragHandle dragControls={dragControls} /> - {item.id} - </Group> - </Reorder.Item> - ); + return ( + <Reorder.Item + as="div" + dragControls={dragControls} + dragListener={false} + value={item} + > + <Group + noWrap + h="3rem" + style={{ boxShadow: '0 1px 3px rgba(0,0,0,.1)' }} + > + <Checkbox + checked={!item.disabled} + onChange={(e) => handleChangeDisabled(item.id, e.target.checked)} + /> + <DragHandle dragControls={dragControls} /> + {item.id} + </Group> + </Reorder.Item> + ); }; export const SidebarSettings = () => { - const settings = useGeneralSettings(); - const { setSidebarItems, setSettings } = useSettingsStoreActions(); + const settings = useGeneralSettings(); + const { setSidebarItems, setSettings } = useSettingsStoreActions(); - const [localSidebarItems, setLocalSidebarItems] = useState(settings.sidebarItems); + const [localSidebarItems, setLocalSidebarItems] = useState(settings.sidebarItems); - const handleSave = () => { - setSidebarItems(localSidebarItems); - }; + const handleSave = () => { + setSidebarItems(localSidebarItems); + }; - const handleChangeDisabled = useCallback((id: string, e: boolean) => { - setLocalSidebarItems((items) => - items.map((item) => { - if (item.id === id) { - return { - ...item, - disabled: !e, - }; - } + const handleChangeDisabled = useCallback((id: string, e: boolean) => { + setLocalSidebarItems((items) => + items.map((item) => { + if (item.id === id) { + return { + ...item, + disabled: !e, + }; + } - return item; - }), + return item; + }), + ); + }, []); + + const handleSetSidebarPlaylistList = (e: ChangeEvent<HTMLInputElement>) => { + setSettings({ + general: { + ...settings, + sidebarPlaylistList: e.target.checked, + }, + }); + }; + + const isSaveButtonDisabled = isEqual(settings.sidebarItems, localSidebarItems); + + return ( + <> + <SettingsOptions + control={ + <Switch + checked={settings.sidebarPlaylistList} + onChange={handleSetSidebarPlaylistList} + /> + } + description="Show playlist list in sidebar" + title="Sidebar playlist list" + /> + <SettingsOptions + control={ + <Button + compact + disabled={isSaveButtonDisabled} + variant="filled" + onClick={handleSave} + > + Save sidebar configuration + </Button> + } + description="Select the items and order in which they appear in the sidebar" + title="Sidebar configuration" + /> + <Reorder.Group + axis="y" + values={localSidebarItems} + onReorder={setLocalSidebarItems} + > + {localSidebarItems.map((item) => ( + <DraggableSidebarItem + key={item.id} + handleChangeDisabled={handleChangeDisabled} + item={item} + /> + ))} + </Reorder.Group> + </> ); - }, []); - - const handleSetSidebarPlaylistList = (e: ChangeEvent<HTMLInputElement>) => { - setSettings({ - general: { - ...settings, - sidebarPlaylistList: e.target.checked, - }, - }); - }; - - const isSaveButtonDisabled = isEqual(settings.sidebarItems, localSidebarItems); - - return ( - <> - <SettingsOptions - control={ - <Switch - checked={settings.sidebarPlaylistList} - onChange={handleSetSidebarPlaylistList} - /> - } - description="Show playlist list in sidebar" - title="Sidebar playlist list" - /> - <SettingsOptions - control={ - <Button - compact - disabled={isSaveButtonDisabled} - variant="filled" - onClick={handleSave} - > - Save sidebar configuration - </Button> - } - description="Select the items and order in which they appear in the sidebar" - title="Sidebar configuration" - /> - <Reorder.Group - axis="y" - values={localSidebarItems} - onReorder={setLocalSidebarItems} - > - {localSidebarItems.map((item) => ( - <DraggableSidebarItem - key={item.id} - handleChangeDisabled={handleChangeDisabled} - item={item} - /> - ))} - </Reorder.Group> - </> - ); }; diff --git a/src/renderer/features/settings/components/general/theme-settings.tsx b/src/renderer/features/settings/components/general/theme-settings.tsx index 169e4ce4..86525135 100644 --- a/src/renderer/features/settings/components/general/theme-settings.tsx +++ b/src/renderer/features/settings/components/general/theme-settings.tsx @@ -1,93 +1,93 @@ import { Switch, Select } from '/@/renderer/components'; import { - SettingsSection, - SettingOption, + SettingsSection, + SettingOption, } from '/@/renderer/features/settings/components/settings-section'; import { THEME_DATA } from '/@/renderer/hooks'; import { useGeneralSettings, useSettingsStoreActions } from '/@/renderer/store/settings.store'; import { AppTheme } from '/@/renderer/themes/types'; export const ThemeSettings = () => { - const settings = useGeneralSettings(); - const { setSettings } = useSettingsStoreActions(); + const settings = useGeneralSettings(); + const { setSettings } = useSettingsStoreActions(); - const themeOptions: SettingOption[] = [ - { - control: ( - <Switch - defaultChecked={settings.followSystemTheme} - onChange={(e) => { - setSettings({ - general: { - ...settings, - followSystemTheme: e.currentTarget.checked, - }, - }); - }} - /> - ), - description: 'Follows the system-defined light or dark preference', - isHidden: false, - title: 'Use system theme', - }, - { - control: ( - <Select - data={THEME_DATA} - defaultValue={settings.theme} - onChange={(e) => { - setSettings({ - general: { - ...settings, - theme: e as AppTheme, - }, - }); - }} - /> - ), - description: 'Sets the default theme', - isHidden: settings.followSystemTheme, - title: 'Theme', - }, - { - control: ( - <Select - data={THEME_DATA} - defaultValue={settings.themeDark} - onChange={(e) => { - setSettings({ - general: { - ...settings, - themeDark: e as AppTheme, - }, - }); - }} - /> - ), - description: 'Sets the dark theme', - isHidden: !settings.followSystemTheme, - title: 'Theme (dark)', - }, - { - control: ( - <Select - data={THEME_DATA} - defaultValue={settings.themeLight} - onChange={(e) => { - setSettings({ - general: { - ...settings, - themeLight: e as AppTheme, - }, - }); - }} - /> - ), - description: 'Sets the light theme', - isHidden: !settings.followSystemTheme, - title: 'Theme (light)', - }, - ]; + const themeOptions: SettingOption[] = [ + { + control: ( + <Switch + defaultChecked={settings.followSystemTheme} + onChange={(e) => { + setSettings({ + general: { + ...settings, + followSystemTheme: e.currentTarget.checked, + }, + }); + }} + /> + ), + description: 'Follows the system-defined light or dark preference', + isHidden: false, + title: 'Use system theme', + }, + { + control: ( + <Select + data={THEME_DATA} + defaultValue={settings.theme} + onChange={(e) => { + setSettings({ + general: { + ...settings, + theme: e as AppTheme, + }, + }); + }} + /> + ), + description: 'Sets the default theme', + isHidden: settings.followSystemTheme, + title: 'Theme', + }, + { + control: ( + <Select + data={THEME_DATA} + defaultValue={settings.themeDark} + onChange={(e) => { + setSettings({ + general: { + ...settings, + themeDark: e as AppTheme, + }, + }); + }} + /> + ), + description: 'Sets the dark theme', + isHidden: !settings.followSystemTheme, + title: 'Theme (dark)', + }, + { + control: ( + <Select + data={THEME_DATA} + defaultValue={settings.themeLight} + onChange={(e) => { + setSettings({ + general: { + ...settings, + themeLight: e as AppTheme, + }, + }); + }} + /> + ), + description: 'Sets the light theme', + isHidden: !settings.followSystemTheme, + title: 'Theme (light)', + }, + ]; - return <SettingsSection options={themeOptions} />; + return <SettingsSection options={themeOptions} />; }; diff --git a/src/renderer/features/settings/components/hotkeys/hotkey-manager-settings.tsx b/src/renderer/features/settings/components/hotkeys/hotkey-manager-settings.tsx index 5c513b61..ed75dac2 100644 --- a/src/renderer/features/settings/components/hotkeys/hotkey-manager-settings.tsx +++ b/src/renderer/features/settings/components/hotkeys/hotkey-manager-settings.tsx @@ -11,222 +11,231 @@ import { SettingsOptions } from '/@/renderer/features/settings/components/settin const ipc = isElectron() ? window.electron.ipc : null; const BINDINGS_MAP: Record<BindingActions, string> = { - globalSearch: 'Global search', - localSearch: 'In-page search', - next: 'Next track', - pause: 'Pause', - play: 'Play', - playPause: 'Play / Pause', - previous: 'Previous track', - skipBackward: 'Skip backward', - skipForward: 'Skip forward', - stop: 'Stop', - toggleFullscreenPlayer: 'Toggle fullscreen player', - toggleQueue: 'Toggle queue', - toggleRepeat: 'Toggle repeat', - toggleShuffle: 'Toggle shuffle', - volumeDown: 'Volume down', - volumeMute: 'Volume mute', - volumeUp: 'Volume up', - zoomIn: 'Zoom in', - zoomOut: 'Zoom out', + globalSearch: 'Global search', + localSearch: 'In-page search', + next: 'Next track', + pause: 'Pause', + play: 'Play', + playPause: 'Play / Pause', + previous: 'Previous track', + skipBackward: 'Skip backward', + skipForward: 'Skip forward', + stop: 'Stop', + toggleFullscreenPlayer: 'Toggle fullscreen player', + toggleQueue: 'Toggle queue', + toggleRepeat: 'Toggle repeat', + toggleShuffle: 'Toggle shuffle', + volumeDown: 'Volume down', + volumeMute: 'Volume mute', + volumeUp: 'Volume up', + zoomIn: 'Zoom in', + zoomOut: 'Zoom out', }; const HotkeysContainer = styled.div` - display: flex; - flex-direction: column; - gap: 1rem; - justify-content: center; - width: 100%; + display: flex; + flex-direction: column; + gap: 1rem; + justify-content: center; + width: 100%; - button { - padding: 0 1rem; - } + button { + padding: 0 1rem; + } `; export const HotkeyManagerSettings = () => { - const { bindings, globalMediaHotkeys } = useHotkeySettings(); - const { setSettings } = useSettingsStoreActions(); - const [selected, setSelected] = useState<BindingActions | null>(null); + const { bindings, globalMediaHotkeys } = useHotkeySettings(); + const { setSettings } = useSettingsStoreActions(); + const [selected, setSelected] = useState<BindingActions | null>(null); - const debouncedSetHotkey = debounce( - (binding: BindingActions, e: React.KeyboardEvent<HTMLInputElement>) => { - e.preventDefault(); - const IGNORED_KEYS = ['Control', 'Alt', 'Shift', 'Meta', ' ', 'Escape']; - const keys = []; - if (e.ctrlKey) keys.push('mod'); - if (e.altKey) keys.push('alt'); - if (e.shiftKey) keys.push('shift'); - if (e.metaKey) keys.push('meta'); - if (e.key === ' ') keys.push('space'); - if (!IGNORED_KEYS.includes(e.key)) { - if (e.code.includes('Numpad')) { - if (e.key === '+') keys.push('numpadadd'); - else if (e.key === '-') keys.push('numpadsubtract'); - else if (e.key === '*') keys.push('numpadmultiply'); - else if (e.key === '/') keys.push('numpaddivide'); - else if (e.key === '.') keys.push('numpaddecimal'); - else keys.push(`numpad${e.key}`.toLowerCase()); - } else if (e.key === '+') { - keys.push('equal'); - } else { - keys.push(e.key?.toLowerCase()); - } - } + const debouncedSetHotkey = debounce( + (binding: BindingActions, e: React.KeyboardEvent<HTMLInputElement>) => { + e.preventDefault(); + const IGNORED_KEYS = ['Control', 'Alt', 'Shift', 'Meta', ' ', 'Escape']; + const keys = []; + if (e.ctrlKey) keys.push('mod'); + if (e.altKey) keys.push('alt'); + if (e.shiftKey) keys.push('shift'); + if (e.metaKey) keys.push('meta'); + if (e.key === ' ') keys.push('space'); + if (!IGNORED_KEYS.includes(e.key)) { + if (e.code.includes('Numpad')) { + if (e.key === '+') keys.push('numpadadd'); + else if (e.key === '-') keys.push('numpadsubtract'); + else if (e.key === '*') keys.push('numpadmultiply'); + else if (e.key === '/') keys.push('numpaddivide'); + else if (e.key === '.') keys.push('numpaddecimal'); + else keys.push(`numpad${e.key}`.toLowerCase()); + } else if (e.key === '+') { + keys.push('equal'); + } else { + keys.push(e.key?.toLowerCase()); + } + } - const bindingString = keys.join('+'); + const bindingString = keys.join('+'); - const updatedBindings = { - ...bindings, - [binding]: { ...bindings[binding], hotkey: bindingString }, - }; + const updatedBindings = { + ...bindings, + [binding]: { ...bindings[binding], hotkey: bindingString }, + }; - setSettings({ - hotkeys: { - bindings: updatedBindings, - globalMediaHotkeys, + setSettings({ + hotkeys: { + bindings: updatedBindings, + globalMediaHotkeys, + }, + }); + + ipc?.send('set-global-shortcuts', updatedBindings); }, - }); + 20, + ); - ipc?.send('set-global-shortcuts', updatedBindings); - }, - 20, - ); + const handleSetHotkey = useCallback(debouncedSetHotkey, [ + bindings, + globalMediaHotkeys, + setSettings, + debouncedSetHotkey, + ]); - const handleSetHotkey = useCallback(debouncedSetHotkey, [ - bindings, - globalMediaHotkeys, - setSettings, - debouncedSetHotkey, - ]); + const handleSetGlobalHotkey = useCallback( + (binding: BindingActions, e: React.ChangeEvent<HTMLInputElement>) => { + const updatedBindings = { + ...bindings, + [binding]: { ...bindings[binding], isGlobal: e.currentTarget.checked }, + }; - const handleSetGlobalHotkey = useCallback( - (binding: BindingActions, e: React.ChangeEvent<HTMLInputElement>) => { - const updatedBindings = { - ...bindings, - [binding]: { ...bindings[binding], isGlobal: e.currentTarget.checked }, - }; + setSettings({ + hotkeys: { + bindings: updatedBindings, + globalMediaHotkeys, + }, + }); - setSettings({ - hotkeys: { - bindings: updatedBindings, - globalMediaHotkeys, + ipc?.send('set-global-shortcuts', updatedBindings); }, - }); + [bindings, globalMediaHotkeys, setSettings], + ); - ipc?.send('set-global-shortcuts', updatedBindings); - }, - [bindings, globalMediaHotkeys, setSettings], - ); + const handleClearHotkey = useCallback( + (binding: BindingActions) => { + const updatedBindings = { + ...bindings, + [binding]: { ...bindings[binding], hotkey: '', isGlobal: false }, + }; - const handleClearHotkey = useCallback( - (binding: BindingActions) => { - const updatedBindings = { - ...bindings, - [binding]: { ...bindings[binding], hotkey: '', isGlobal: false }, - }; + setSettings({ + hotkeys: { + bindings: updatedBindings, + globalMediaHotkeys, + }, + }); - setSettings({ - hotkeys: { - bindings: updatedBindings, - globalMediaHotkeys, + ipc?.send('set-global-shortcuts', updatedBindings); }, - }); + [bindings, globalMediaHotkeys, setSettings], + ); - ipc?.send('set-global-shortcuts', updatedBindings); - }, - [bindings, globalMediaHotkeys, setSettings], - ); + const duplicateHotkeyMap = useMemo(() => { + const countPerHotkey = Object.values(bindings).reduce((acc, key) => { + const hotkey = key.hotkey; + if (!hotkey) return acc; - const duplicateHotkeyMap = useMemo(() => { - const countPerHotkey = Object.values(bindings).reduce((acc, key) => { - const hotkey = key.hotkey; - if (!hotkey) return acc; + if (acc[hotkey]) { + acc[hotkey] += 1; + } else { + acc[hotkey] = 1; + } - if (acc[hotkey]) { - acc[hotkey] += 1; - } else { - acc[hotkey] = 1; - } + return acc; + }, {} as Record<string, number>); - return acc; - }, {} as Record<string, number>); + const duplicateKeys = Object.keys(countPerHotkey).filter((key) => countPerHotkey[key] > 1); - const duplicateKeys = Object.keys(countPerHotkey).filter((key) => countPerHotkey[key] > 1); + return duplicateKeys; + }, [bindings]); - return duplicateKeys; - }, [bindings]); - - return ( - <> - <SettingsOptions - control={<></>} - description="Configure application hotkeys. Toggle the checkbox to set as a global hotkey (desktop only)" - title="Application hotkeys" - /> - <HotkeysContainer> - {Object.keys(bindings) - .filter((binding) => BINDINGS_MAP[binding as keyof typeof BINDINGS_MAP]) - .map((binding) => ( - <Group - key={`hotkey-${binding}`} - noWrap - > - <TextInput - readOnly - style={{ userSelect: 'none' }} - value={BINDINGS_MAP[binding as keyof typeof BINDINGS_MAP]} - /> - <TextInput - readOnly - icon={<RiKeyboardBoxLine />} - id={`hotkey-${binding}`} - style={{ - opacity: selected === (binding as BindingActions) ? 0.8 : 1, - outline: duplicateHotkeyMap.includes( - bindings[binding as keyof typeof BINDINGS_MAP].hotkey!, - ) - ? '1px dashed red' - : undefined, - }} - value={bindings[binding as keyof typeof BINDINGS_MAP].hotkey} - onBlur={() => setSelected(null)} - onChange={() => {}} - onKeyDownCapture={(e) => { - if (selected !== (binding as BindingActions)) return; - handleSetHotkey(binding as BindingActions, e); - }} - /> - {isElectron() && ( - <Checkbox - checked={bindings[binding as keyof typeof BINDINGS_MAP].isGlobal} - disabled={bindings[binding as keyof typeof BINDINGS_MAP].hotkey === ''} - size="xl" - style={{ - opacity: bindings[binding as keyof typeof BINDINGS_MAP].allowGlobal ? 1 : 0, - }} - onChange={(e) => handleSetGlobalHotkey(binding as BindingActions, e)} - /> - )} - <Button - variant="default" - w={100} - onClick={() => { - setSelected(binding as BindingActions); - document.getElementById(`hotkey-${binding}`)?.focus(); - }} - > - <RiEditLine /> - </Button> - <Button - variant="default" - onClick={() => handleClearHotkey(binding as BindingActions)} - > - <RiDeleteBinLine /> - </Button> - </Group> - ))} - </HotkeysContainer> - </> - ); + return ( + <> + <SettingsOptions + control={<></>} + description="Configure application hotkeys. Toggle the checkbox to set as a global hotkey (desktop only)" + title="Application hotkeys" + /> + <HotkeysContainer> + {Object.keys(bindings) + .filter((binding) => BINDINGS_MAP[binding as keyof typeof BINDINGS_MAP]) + .map((binding) => ( + <Group + key={`hotkey-${binding}`} + noWrap + > + <TextInput + readOnly + style={{ userSelect: 'none' }} + value={BINDINGS_MAP[binding as keyof typeof BINDINGS_MAP]} + /> + <TextInput + readOnly + icon={<RiKeyboardBoxLine />} + id={`hotkey-${binding}`} + style={{ + opacity: selected === (binding as BindingActions) ? 0.8 : 1, + outline: duplicateHotkeyMap.includes( + bindings[binding as keyof typeof BINDINGS_MAP].hotkey!, + ) + ? '1px dashed red' + : undefined, + }} + value={bindings[binding as keyof typeof BINDINGS_MAP].hotkey} + onBlur={() => setSelected(null)} + onChange={() => {}} + onKeyDownCapture={(e) => { + if (selected !== (binding as BindingActions)) return; + handleSetHotkey(binding as BindingActions, e); + }} + /> + {isElectron() && ( + <Checkbox + checked={ + bindings[binding as keyof typeof BINDINGS_MAP].isGlobal + } + disabled={ + bindings[binding as keyof typeof BINDINGS_MAP].hotkey === '' + } + size="xl" + style={{ + opacity: bindings[binding as keyof typeof BINDINGS_MAP] + .allowGlobal + ? 1 + : 0, + }} + onChange={(e) => + handleSetGlobalHotkey(binding as BindingActions, e) + } + /> + )} + <Button + variant="default" + w={100} + onClick={() => { + setSelected(binding as BindingActions); + document.getElementById(`hotkey-${binding}`)?.focus(); + }} + > + <RiEditLine /> + </Button> + <Button + variant="default" + onClick={() => handleClearHotkey(binding as BindingActions)} + > + <RiDeleteBinLine /> + </Button> + </Group> + ))} + </HotkeysContainer> + </> + ); }; diff --git a/src/renderer/features/settings/components/hotkeys/hotkeys-tab.tsx b/src/renderer/features/settings/components/hotkeys/hotkeys-tab.tsx index 9d426e7b..73869afc 100644 --- a/src/renderer/features/settings/components/hotkeys/hotkeys-tab.tsx +++ b/src/renderer/features/settings/components/hotkeys/hotkeys-tab.tsx @@ -3,11 +3,11 @@ import { WindowHotkeySettings } from './window-hotkey-settings'; import { HotkeyManagerSettings } from '/@/renderer/features/settings/components/hotkeys/hotkey-manager-settings'; export const HotkeysTab = () => { - return ( - <Stack spacing="md"> - <WindowHotkeySettings /> - <Divider /> - <HotkeyManagerSettings /> - </Stack> - ); + return ( + <Stack spacing="md"> + <WindowHotkeySettings /> + <Divider /> + <HotkeyManagerSettings /> + </Stack> + ); }; diff --git a/src/renderer/features/settings/components/hotkeys/window-hotkey-settings.tsx b/src/renderer/features/settings/components/hotkeys/window-hotkey-settings.tsx index dc120498..bda12292 100644 --- a/src/renderer/features/settings/components/hotkeys/window-hotkey-settings.tsx +++ b/src/renderer/features/settings/components/hotkeys/window-hotkey-settings.tsx @@ -6,39 +6,39 @@ import { useHotkeySettings, useSettingsStoreActions } from '/@/renderer/store'; const localSettings = isElectron() ? window.electron.localSettings : null; export const WindowHotkeySettings = () => { - const settings = useHotkeySettings(); - const { setSettings } = useSettingsStoreActions(); + const settings = useHotkeySettings(); + const { setSettings } = useSettingsStoreActions(); - const options: SettingOption[] = [ - { - control: ( - <Switch - aria-label="Toggle global media hotkeys" - defaultChecked={settings.globalMediaHotkeys} - disabled={!isElectron()} - onChange={(e) => { - setSettings({ - hotkeys: { - ...settings, - globalMediaHotkeys: e.currentTarget.checked, - }, - }); - localSettings.set('global_media_hotkeys', e.currentTarget.checked); + const options: SettingOption[] = [ + { + control: ( + <Switch + aria-label="Toggle global media hotkeys" + defaultChecked={settings.globalMediaHotkeys} + disabled={!isElectron()} + onChange={(e) => { + setSettings({ + hotkeys: { + ...settings, + globalMediaHotkeys: e.currentTarget.checked, + }, + }); + localSettings.set('global_media_hotkeys', e.currentTarget.checked); - if (e.currentTarget.checked) { - localSettings.enableMediaKeys(); - } else { - localSettings.disableMediaKeys(); - } - }} - /> - ), - description: - 'Enable or disable the usage of your system media hotkeys to control the audio player', - isHidden: !isElectron(), - title: 'Global media hotkeys', - }, - ]; + if (e.currentTarget.checked) { + localSettings.enableMediaKeys(); + } else { + localSettings.disableMediaKeys(); + } + }} + /> + ), + description: + 'Enable or disable the usage of your system media hotkeys to control the audio player', + isHidden: !isElectron(), + title: 'Global media hotkeys', + }, + ]; - return <SettingsSection options={options} />; + return <SettingsSection options={options} />; }; diff --git a/src/renderer/features/settings/components/playback/audio-settings.tsx b/src/renderer/features/settings/components/playback/audio-settings.tsx index 82c6b109..0bbd0605 100644 --- a/src/renderer/features/settings/components/playback/audio-settings.tsx +++ b/src/renderer/features/settings/components/playback/audio-settings.tsx @@ -3,8 +3,8 @@ import { SelectItem } from '@mantine/core'; import isElectron from 'is-electron'; import { Select, Slider, toast } from '/@/renderer/components'; import { - SettingsSection, - SettingOption, + SettingsSection, + SettingOption, } from '/@/renderer/features/settings/components/settings-section'; import { useCurrentStatus, usePlayerStore } from '/@/renderer/store'; import { usePlaybackSettings, useSettingsStoreActions } from '/@/renderer/store/settings.store'; @@ -13,146 +13,152 @@ import { PlaybackType, PlayerStatus, PlaybackStyle, CrossfadeStyle } from '/@/re const mpvPlayer = isElectron() ? window.electron.mpvPlayer : null; const getAudioDevice = async () => { - const devices = await navigator.mediaDevices.enumerateDevices(); - return (devices || []).filter((dev: MediaDeviceInfo) => dev.kind === 'audiooutput'); + const devices = await navigator.mediaDevices.enumerateDevices(); + return (devices || []).filter((dev: MediaDeviceInfo) => dev.kind === 'audiooutput'); }; export const AudioSettings = () => { - const settings = usePlaybackSettings(); - const { setSettings } = useSettingsStoreActions(); - const status = useCurrentStatus(); + const settings = usePlaybackSettings(); + const { setSettings } = useSettingsStoreActions(); + const status = useCurrentStatus(); - const [audioDevices, setAudioDevices] = useState<SelectItem[]>([]); + const [audioDevices, setAudioDevices] = useState<SelectItem[]>([]); - useEffect(() => { - const getAudioDevices = () => { - getAudioDevice() - .then((dev) => setAudioDevices(dev.map((d) => ({ label: d.label, value: d.deviceId })))) - .catch(() => toast.error({ message: 'Error fetching audio devices' })); - }; + useEffect(() => { + const getAudioDevices = () => { + getAudioDevice() + .then((dev) => + setAudioDevices(dev.map((d) => ({ label: d.label, value: d.deviceId }))), + ) + .catch(() => toast.error({ message: 'Error fetching audio devices' })); + }; - if (settings.type === PlaybackType.WEB) { - getAudioDevices(); - } - }, [settings.type]); + if (settings.type === PlaybackType.WEB) { + getAudioDevices(); + } + }, [settings.type]); - const audioOptions: SettingOption[] = [ - { - control: ( - <Select - data={[ - { - disabled: !isElectron(), - label: 'MPV', - value: PlaybackType.LOCAL, - }, - { label: 'Web', value: PlaybackType.WEB }, - ]} - defaultValue={settings.type} - disabled={status === PlayerStatus.PLAYING} - onChange={(e) => { - setSettings({ playback: { ...settings, type: e as PlaybackType } }); - if (isElectron() && e === PlaybackType.LOCAL) { - const queueData = usePlayerStore.getState().actions.getPlayerData(); - mpvPlayer.setQueue(queueData); - } - }} - /> - ), - description: 'The audio player to use for playback', - isHidden: !isElectron(), - note: status === PlayerStatus.PLAYING ? 'Player must be paused' : undefined, - title: 'Audio player', - }, - { - control: ( - <Select - clearable - data={audioDevices} - defaultValue={settings.audioDeviceId} - disabled={settings.type !== PlaybackType.WEB} - onChange={(e) => setSettings({ playback: { ...settings, audioDeviceId: e } })} - /> - ), - description: 'The audio device to use for playback (web player only)', - isHidden: !isElectron() || settings.type !== PlaybackType.WEB, - title: 'Audio device', - }, - { - control: ( - <Select - data={[ - { label: 'Normal', value: PlaybackStyle.GAPLESS }, - { label: 'Crossfade', value: PlaybackStyle.CROSSFADE }, - ]} - defaultValue={settings.style} - disabled={settings.type !== PlaybackType.WEB || status === PlayerStatus.PLAYING} - onChange={(e) => setSettings({ playback: { ...settings, style: e as PlaybackStyle } })} - /> - ), - description: 'Adjust the playback style (web player only)', - isHidden: settings.type !== PlaybackType.WEB, - note: status === PlayerStatus.PLAYING ? 'Player must be paused' : undefined, - title: 'Playback style', - }, - { - control: ( - <Slider - defaultValue={settings.crossfadeDuration} - disabled={ - settings.type !== PlaybackType.WEB || - settings.style !== PlaybackStyle.CROSSFADE || - status === PlayerStatus.PLAYING - } - max={15} - min={0} - w={100} - onChangeEnd={(e) => setSettings({ playback: { ...settings, crossfadeDuration: e } })} - /> - ), - description: 'Adjust the crossfade duration (web player only)', - isHidden: settings.type !== PlaybackType.WEB, - note: status === PlayerStatus.PLAYING ? 'Player must be paused' : undefined, - title: 'Crossfade Duration', - }, - { - control: ( - <Select - data={[ - { label: 'Linear', value: CrossfadeStyle.LINEAR }, - { label: 'Constant Power', value: CrossfadeStyle.CONSTANT_POWER }, - { - label: 'Constant Power (Slow cut)', - value: CrossfadeStyle.CONSTANT_POWER_SLOW_CUT, - }, - { - label: 'Constant Power (Slow fade)', - value: CrossfadeStyle.CONSTANT_POWER_SLOW_FADE, - }, - { label: 'Dipped', value: CrossfadeStyle.DIPPED }, - { label: 'Equal Power', value: CrossfadeStyle.EQUALPOWER }, - ]} - defaultValue={settings.crossfadeStyle} - disabled={ - settings.type !== PlaybackType.WEB || - settings.style !== PlaybackStyle.CROSSFADE || - status === PlayerStatus.PLAYING - } - width={200} - onChange={(e) => { - if (!e) return; - setSettings({ - playback: { ...settings, crossfadeStyle: e as CrossfadeStyle }, - }); - }} - /> - ), - description: 'Change the crossfade algorithm (web player only)', - isHidden: settings.type !== PlaybackType.WEB, - note: status === PlayerStatus.PLAYING ? 'Player must be paused' : undefined, - title: 'Crossfade Style', - }, - ]; + const audioOptions: SettingOption[] = [ + { + control: ( + <Select + data={[ + { + disabled: !isElectron(), + label: 'MPV', + value: PlaybackType.LOCAL, + }, + { label: 'Web', value: PlaybackType.WEB }, + ]} + defaultValue={settings.type} + disabled={status === PlayerStatus.PLAYING} + onChange={(e) => { + setSettings({ playback: { ...settings, type: e as PlaybackType } }); + if (isElectron() && e === PlaybackType.LOCAL) { + const queueData = usePlayerStore.getState().actions.getPlayerData(); + mpvPlayer.setQueue(queueData); + } + }} + /> + ), + description: 'The audio player to use for playback', + isHidden: !isElectron(), + note: status === PlayerStatus.PLAYING ? 'Player must be paused' : undefined, + title: 'Audio player', + }, + { + control: ( + <Select + clearable + data={audioDevices} + defaultValue={settings.audioDeviceId} + disabled={settings.type !== PlaybackType.WEB} + onChange={(e) => setSettings({ playback: { ...settings, audioDeviceId: e } })} + /> + ), + description: 'The audio device to use for playback (web player only)', + isHidden: !isElectron() || settings.type !== PlaybackType.WEB, + title: 'Audio device', + }, + { + control: ( + <Select + data={[ + { label: 'Normal', value: PlaybackStyle.GAPLESS }, + { label: 'Crossfade', value: PlaybackStyle.CROSSFADE }, + ]} + defaultValue={settings.style} + disabled={settings.type !== PlaybackType.WEB || status === PlayerStatus.PLAYING} + onChange={(e) => + setSettings({ playback: { ...settings, style: e as PlaybackStyle } }) + } + /> + ), + description: 'Adjust the playback style (web player only)', + isHidden: settings.type !== PlaybackType.WEB, + note: status === PlayerStatus.PLAYING ? 'Player must be paused' : undefined, + title: 'Playback style', + }, + { + control: ( + <Slider + defaultValue={settings.crossfadeDuration} + disabled={ + settings.type !== PlaybackType.WEB || + settings.style !== PlaybackStyle.CROSSFADE || + status === PlayerStatus.PLAYING + } + max={15} + min={0} + w={100} + onChangeEnd={(e) => + setSettings({ playback: { ...settings, crossfadeDuration: e } }) + } + /> + ), + description: 'Adjust the crossfade duration (web player only)', + isHidden: settings.type !== PlaybackType.WEB, + note: status === PlayerStatus.PLAYING ? 'Player must be paused' : undefined, + title: 'Crossfade Duration', + }, + { + control: ( + <Select + data={[ + { label: 'Linear', value: CrossfadeStyle.LINEAR }, + { label: 'Constant Power', value: CrossfadeStyle.CONSTANT_POWER }, + { + label: 'Constant Power (Slow cut)', + value: CrossfadeStyle.CONSTANT_POWER_SLOW_CUT, + }, + { + label: 'Constant Power (Slow fade)', + value: CrossfadeStyle.CONSTANT_POWER_SLOW_FADE, + }, + { label: 'Dipped', value: CrossfadeStyle.DIPPED }, + { label: 'Equal Power', value: CrossfadeStyle.EQUALPOWER }, + ]} + defaultValue={settings.crossfadeStyle} + disabled={ + settings.type !== PlaybackType.WEB || + settings.style !== PlaybackStyle.CROSSFADE || + status === PlayerStatus.PLAYING + } + width={200} + onChange={(e) => { + if (!e) return; + setSettings({ + playback: { ...settings, crossfadeStyle: e as CrossfadeStyle }, + }); + }} + /> + ), + description: 'Change the crossfade algorithm (web player only)', + isHidden: settings.type !== PlaybackType.WEB, + note: status === PlayerStatus.PLAYING ? 'Player must be paused' : undefined, + title: 'Crossfade Style', + }, + ]; - return <SettingsSection options={audioOptions} />; + return <SettingsSection options={audioOptions} />; }; diff --git a/src/renderer/features/settings/components/playback/lyric-settings.tsx b/src/renderer/features/settings/components/playback/lyric-settings.tsx index 84f6949a..c9c74d78 100644 --- a/src/renderer/features/settings/components/playback/lyric-settings.tsx +++ b/src/renderer/features/settings/components/playback/lyric-settings.tsx @@ -1,6 +1,6 @@ import { - SettingOption, - SettingsSection, + SettingOption, + SettingsSection, } from '/@/renderer/features/settings/components/settings-section'; import { useLyricsSettings, useSettingsStoreActions } from '/@/renderer/store'; import { MultiSelect, MultiSelectProps, NumberInput, Switch } from '/@/renderer/components'; @@ -11,99 +11,99 @@ import { LyricSource } from '/@/renderer/api/types'; const localSettings = isElectron() ? window.electron.localSettings : null; const WorkingButtonSelect = styled(MultiSelect)<MultiSelectProps>` - & button { - padding: 0; - } + & button { + padding: 0; + } `; export const LyricSettings = () => { - const settings = useLyricsSettings(); - const { setSettings } = useSettingsStoreActions(); + const settings = useLyricsSettings(); + const { setSettings } = useSettingsStoreActions(); - const lyricOptions: SettingOption[] = [ - { - control: ( - <Switch - aria-label="Follow lyrics" - defaultChecked={settings.follow} - onChange={(e) => { - setSettings({ - lyrics: { - ...settings, - follow: e.currentTarget.checked, - }, - }); - }} - /> - ), - description: 'Enable or disable following of current lyric', - title: 'Follow current lyric', - }, - { - control: ( - <Switch - aria-label="Enable fetching lyrics" - defaultChecked={settings.fetch} - onChange={(e) => { - setSettings({ - lyrics: { - ...settings, - fetch: e.currentTarget.checked, - }, - }); - }} - /> - ), - description: 'Enable or disable fetching lyrics for the current song', - isHidden: !isElectron(), - title: 'Fetch lyrics from the internet', - }, - { - control: ( - <WorkingButtonSelect - clearable - aria-label="Lyric providers" - data={Object.values(LyricSource)} - defaultValue={settings.sources} - width={300} - onChange={(e: LyricSource[]) => { - localSettings?.set('lyrics', e); - setSettings({ - lyrics: { - ...settings, - sources: e, - }, - }); - }} - /> - ), - description: 'List of lyric fetchers (in order of preference)', - isHidden: !isElectron(), - title: 'Providers to fetch music', - }, - { - control: ( - <NumberInput - defaultValue={settings.delayMs} - step={10} - width={100} - onBlur={(e) => { - const value = Number(e.currentTarget.value); - setSettings({ - lyrics: { - ...settings, - delayMs: value, - }, - }); - }} - /> - ), - description: - 'Lyric offset (in milliseconds). Positive values mean that lyrics are shown later, and negative mean that lyrics are shown earlier', - isHidden: !isElectron(), - title: 'Lyric offset', - }, - ]; + const lyricOptions: SettingOption[] = [ + { + control: ( + <Switch + aria-label="Follow lyrics" + defaultChecked={settings.follow} + onChange={(e) => { + setSettings({ + lyrics: { + ...settings, + follow: e.currentTarget.checked, + }, + }); + }} + /> + ), + description: 'Enable or disable following of current lyric', + title: 'Follow current lyric', + }, + { + control: ( + <Switch + aria-label="Enable fetching lyrics" + defaultChecked={settings.fetch} + onChange={(e) => { + setSettings({ + lyrics: { + ...settings, + fetch: e.currentTarget.checked, + }, + }); + }} + /> + ), + description: 'Enable or disable fetching lyrics for the current song', + isHidden: !isElectron(), + title: 'Fetch lyrics from the internet', + }, + { + control: ( + <WorkingButtonSelect + clearable + aria-label="Lyric providers" + data={Object.values(LyricSource)} + defaultValue={settings.sources} + width={300} + onChange={(e: LyricSource[]) => { + localSettings?.set('lyrics', e); + setSettings({ + lyrics: { + ...settings, + sources: e, + }, + }); + }} + /> + ), + description: 'List of lyric fetchers (in order of preference)', + isHidden: !isElectron(), + title: 'Providers to fetch music', + }, + { + control: ( + <NumberInput + defaultValue={settings.delayMs} + step={10} + width={100} + onBlur={(e) => { + const value = Number(e.currentTarget.value); + setSettings({ + lyrics: { + ...settings, + delayMs: value, + }, + }); + }} + /> + ), + description: + 'Lyric offset (in milliseconds). Positive values mean that lyrics are shown later, and negative mean that lyrics are shown earlier', + isHidden: !isElectron(), + title: 'Lyric offset', + }, + ]; - return <SettingsSection options={lyricOptions} />; + return <SettingsSection options={lyricOptions} />; }; diff --git a/src/renderer/features/settings/components/playback/mpv-settings.tsx b/src/renderer/features/settings/components/playback/mpv-settings.tsx index 4d8b1c6c..725d50f5 100644 --- a/src/renderer/features/settings/components/playback/mpv-settings.tsx +++ b/src/renderer/features/settings/components/playback/mpv-settings.tsx @@ -3,13 +3,13 @@ import { Divider, Stack } from '@mantine/core'; import isElectron from 'is-electron'; import { FileInput, Textarea, Text, Select, NumberInput, Switch } from '/@/renderer/components'; import { - SettingsSection, - SettingOption, + SettingsSection, + SettingOption, } from '/@/renderer/features/settings/components/settings-section'; import { - SettingsState, - usePlaybackSettings, - useSettingsStoreActions, + SettingsState, + usePlaybackSettings, + useSettingsStoreActions, } from '/@/renderer/store/settings.store'; import { PlaybackType } from '/@/renderer/types'; @@ -17,267 +17,275 @@ const localSettings = isElectron() ? window.electron.localSettings : null; const mpvPlayer = isElectron() ? window.electron.mpvPlayer : null; export const getMpvSetting = ( - key: keyof SettingsState['playback']['mpvProperties'], - value: any, + key: keyof SettingsState['playback']['mpvProperties'], + value: any, ) => { - switch (key) { - case 'audioExclusiveMode': - return { 'audio-exclusive': value || 'no' }; - case 'audioSampleRateHz': - return { 'audio-samplerate': value }; - case 'gaplessAudio': - return { 'gapless-audio': value || 'weak' }; - case 'replayGainMode': - return { replaygain: value || 'no' }; - case 'replayGainClip': - return { 'replaygain-clip': value || 'no' }; - case 'replayGainFallbackDB': - return { 'replaygain-fallback': value }; - case 'replayGainPreampDB': - return { 'replaygain-preamp': value || 0 }; - default: - return key; - } + switch (key) { + case 'audioExclusiveMode': + return { 'audio-exclusive': value || 'no' }; + case 'audioSampleRateHz': + return { 'audio-samplerate': value }; + case 'gaplessAudio': + return { 'gapless-audio': value || 'weak' }; + case 'replayGainMode': + return { replaygain: value || 'no' }; + case 'replayGainClip': + return { 'replaygain-clip': value || 'no' }; + case 'replayGainFallbackDB': + return { 'replaygain-fallback': value }; + case 'replayGainPreampDB': + return { 'replaygain-preamp': value || 0 }; + default: + return key; + } }; export const getMpvProperties = (settings: SettingsState['playback']['mpvProperties']) => { - const properties: Record<string, any> = { - 'audio-exclusive': settings.audioExclusiveMode || 'no', - 'audio-samplerate': settings.audioSampleRateHz === 0 ? undefined : settings.audioSampleRateHz, - 'gapless-audio': settings.gaplessAudio || 'weak', - replaygain: settings.replayGainMode || 'no', - 'replaygain-clip': settings.replayGainClip || 'no', - 'replaygain-fallback': settings.replayGainFallbackDB, - 'replaygain-preamp': settings.replayGainPreampDB || 0, - }; + const properties: Record<string, any> = { + 'audio-exclusive': settings.audioExclusiveMode || 'no', + 'audio-samplerate': + settings.audioSampleRateHz === 0 ? undefined : settings.audioSampleRateHz, + 'gapless-audio': settings.gaplessAudio || 'weak', + replaygain: settings.replayGainMode || 'no', + 'replaygain-clip': settings.replayGainClip || 'no', + 'replaygain-fallback': settings.replayGainFallbackDB, + 'replaygain-preamp': settings.replayGainPreampDB || 0, + }; - Object.keys(properties).forEach((key) => - properties[key] === undefined ? delete properties[key] : {}, - ); + Object.keys(properties).forEach((key) => + properties[key] === undefined ? delete properties[key] : {}, + ); - return properties; + return properties; }; export const MpvSettings = () => { - const settings = usePlaybackSettings(); - const { setSettings } = useSettingsStoreActions(); + const settings = usePlaybackSettings(); + const { setSettings } = useSettingsStoreActions(); - const [mpvPath, setMpvPath] = useState(''); + const [mpvPath, setMpvPath] = useState(''); - const handleSetMpvPath = (e: File) => { - localSettings.set('mpv_path', e.path); - }; - - useEffect(() => { - const getMpvPath = async () => { - if (!isElectron()) return setMpvPath(''); - const mpvPath = (await localSettings.get('mpv_path')) as string; - return setMpvPath(mpvPath); + const handleSetMpvPath = (e: File) => { + localSettings.set('mpv_path', e.path); }; - getMpvPath(); - }, []); + useEffect(() => { + const getMpvPath = async () => { + if (!isElectron()) return setMpvPath(''); + const mpvPath = (await localSettings.get('mpv_path')) as string; + return setMpvPath(mpvPath); + }; - const handleSetMpvProperty = ( - setting: keyof SettingsState['playback']['mpvProperties'], - value: any, - ) => { - setSettings({ - playback: { - ...settings, - mpvProperties: { - ...settings.mpvProperties, - [setting]: value, + getMpvPath(); + }, []); + + const handleSetMpvProperty = ( + setting: keyof SettingsState['playback']['mpvProperties'], + value: any, + ) => { + setSettings({ + playback: { + ...settings, + mpvProperties: { + ...settings.mpvProperties, + [setting]: value, + }, + }, + }); + + const mpvSetting = getMpvSetting(setting, value); + + mpvPlayer?.setProperties(mpvSetting); + }; + + const handleSetExtraParameters = (data: string[]) => { + setSettings({ + playback: { + ...settings, + mpvExtraParameters: data, + }, + }); + }; + + const options: SettingOption[] = [ + { + control: ( + <FileInput + placeholder={mpvPath} + width={225} + onChange={handleSetMpvPath} + /> + ), + description: 'The location of your mpv executable', + isHidden: settings.type !== PlaybackType.LOCAL, + note: 'Restart required', + title: 'MPV executable path', }, - }, - }); + { + control: ( + <Stack spacing="xs"> + <Textarea + autosize + defaultValue={settings.mpvExtraParameters.join('\n')} + minRows={4} + placeholder={ + '(Add one per line):\n--gapless-audio=weak\n--prefetch-playlist=yes' + } + width={225} + onBlur={(e) => { + handleSetExtraParameters(e.currentTarget.value.split('\n')); + }} + /> + </Stack> + ), + description: ( + <Stack spacing={0}> + <Text + $noSelect + $secondary + size="sm" + > + Options to pass to the player + </Text> + <Text size="sm"> + <a + href="https://mpv.io/manual/stable/#audio" + rel="noreferrer" + target="_blank" + > + https://mpv.io/manual/stable/#audio + </a> + </Text> + </Stack> + ), + isHidden: settings.type !== PlaybackType.LOCAL, + note: 'Restart required', + title: 'MPV parameters', + }, + ]; - const mpvSetting = getMpvSetting(setting, value); + const generalOptions: SettingOption[] = [ + { + control: ( + <Select + data={[ + { label: 'No', value: 'no' }, + { label: 'Yes', value: 'yes' }, + { label: 'Weak (recommended)', value: 'weak' }, + ]} + defaultValue={settings.mpvProperties.gaplessAudio} + onChange={(e) => handleSetMpvProperty('gaplessAudio', e)} + /> + ), + description: + 'Try to play consecutive audio files with no silence or disruption at the point of file change (--gapless-audio)', + isHidden: settings.type !== PlaybackType.LOCAL, + title: 'Gapless audio', + }, + { + control: ( + <NumberInput + defaultValue={settings.mpvProperties.audioSampleRateHz} + width={100} + onBlur={(e) => { + const value = Number(e.currentTarget.value); + handleSetMpvProperty('audioSampleRateHz', value > 0 ? value : undefined); + }} + /> + ), + description: + 'Select the output sample rate to be used if the sample frequency selected is different from that of the current media', + isHidden: settings.type !== PlaybackType.LOCAL, + title: 'Sample rate', + }, + { + control: ( + <Switch + defaultChecked={settings.mpvProperties.audioExclusiveMode === 'yes'} + onChange={(e) => + handleSetMpvProperty( + 'audioExclusiveMode', + e.currentTarget.checked ? 'yes' : 'no', + ) + } + /> + ), - mpvPlayer?.setProperties(mpvSetting); - }; + description: + 'Enable exclusive output mode. In this mode, the system is usually locked out, and only mpv will be able to output audio (--audio-exclusive)', + isHidden: settings.type !== PlaybackType.LOCAL, + title: 'Audio exclusive mode', + }, + ]; - const handleSetExtraParameters = (data: string[]) => { - setSettings({ - playback: { - ...settings, - mpvExtraParameters: data, - }, - }); - }; + const replayGainOptions: SettingOption[] = [ + { + control: ( + <Select + data={[ + { label: 'None', value: 'no' }, + { label: 'Track', value: 'track' }, + { label: 'Album', value: 'album' }, + ]} + defaultValue={settings.mpvProperties.replayGainMode} + onChange={(e) => handleSetMpvProperty('replayGainMode', e)} + /> + ), + description: + 'Adjust volume gain according to replaygain values stored in the file metadata (--replaygain)', + isHidden: settings.type !== PlaybackType.LOCAL, + note: 'Restart required', + title: 'ReplayGain mode', + }, + { + control: ( + <NumberInput + defaultValue={settings.mpvProperties.replayGainPreampDB} + width={75} + onChange={(e) => handleSetMpvProperty('replayGainPreampDB', e)} + /> + ), + description: + 'Pre-amplification gain in dB to apply to the selected replaygain gain (--replaygain-preamp)', + isHidden: settings.type !== PlaybackType.LOCAL, + title: 'ReplayGain preamp (dB)', + }, + { + control: ( + <Switch + defaultChecked={settings.mpvProperties.replayGainClip} + onChange={(e) => + handleSetMpvProperty('replayGainClip', e.currentTarget.checked) + } + /> + ), + description: + 'Prevent clipping caused by replaygain by automatically lowering the gain (--replaygain-clip)', + isHidden: settings.type !== PlaybackType.LOCAL, + title: 'ReplayGain clipping', + }, + { + control: ( + <NumberInput + defaultValue={settings.mpvProperties.replayGainFallbackDB} + width={75} + onBlur={(e) => handleSetMpvProperty('replayGainFallbackDB', e)} + /> + ), + description: + 'Gain in dB to apply if the file has no replay gain tags. This option is always applied if the replaygain logic is somehow inactive. If this is applied, no other replaygain options are applied', + isHidden: settings.type !== PlaybackType.LOCAL, + title: 'ReplayGain fallback (dB)', + }, + ]; - const options: SettingOption[] = [ - { - control: ( - <FileInput - placeholder={mpvPath} - width={225} - onChange={handleSetMpvPath} - /> - ), - description: 'The location of your mpv executable', - isHidden: settings.type !== PlaybackType.LOCAL, - note: 'Restart required', - title: 'MPV executable path', - }, - { - control: ( - <Stack spacing="xs"> - <Textarea - autosize - defaultValue={settings.mpvExtraParameters.join('\n')} - minRows={4} - placeholder={'(Add one per line):\n--gapless-audio=weak\n--prefetch-playlist=yes'} - width={225} - onBlur={(e) => { - handleSetExtraParameters(e.currentTarget.value.split('\n')); - }} - /> - </Stack> - ), - description: ( - <Stack spacing={0}> - <Text - $noSelect - $secondary - size="sm" - > - Options to pass to the player - </Text> - <Text size="sm"> - <a - href="https://mpv.io/manual/stable/#audio" - rel="noreferrer" - target="_blank" - > - https://mpv.io/manual/stable/#audio - </a> - </Text> - </Stack> - ), - isHidden: settings.type !== PlaybackType.LOCAL, - note: 'Restart required', - title: 'MPV parameters', - }, - ]; - - const generalOptions: SettingOption[] = [ - { - control: ( - <Select - data={[ - { label: 'No', value: 'no' }, - { label: 'Yes', value: 'yes' }, - { label: 'Weak (recommended)', value: 'weak' }, - ]} - defaultValue={settings.mpvProperties.gaplessAudio} - onChange={(e) => handleSetMpvProperty('gaplessAudio', e)} - /> - ), - description: - 'Try to play consecutive audio files with no silence or disruption at the point of file change (--gapless-audio)', - isHidden: settings.type !== PlaybackType.LOCAL, - title: 'Gapless audio', - }, - { - control: ( - <NumberInput - defaultValue={settings.mpvProperties.audioSampleRateHz} - width={100} - onBlur={(e) => { - const value = Number(e.currentTarget.value); - handleSetMpvProperty('audioSampleRateHz', value > 0 ? value : undefined); - }} - /> - ), - description: - 'Select the output sample rate to be used if the sample frequency selected is different from that of the current media', - isHidden: settings.type !== PlaybackType.LOCAL, - title: 'Sample rate', - }, - { - control: ( - <Switch - defaultChecked={settings.mpvProperties.audioExclusiveMode === 'yes'} - onChange={(e) => - handleSetMpvProperty('audioExclusiveMode', e.currentTarget.checked ? 'yes' : 'no') - } - /> - ), - - description: - 'Enable exclusive output mode. In this mode, the system is usually locked out, and only mpv will be able to output audio (--audio-exclusive)', - isHidden: settings.type !== PlaybackType.LOCAL, - title: 'Audio exclusive mode', - }, - ]; - - const replayGainOptions: SettingOption[] = [ - { - control: ( - <Select - data={[ - { label: 'None', value: 'no' }, - { label: 'Track', value: 'track' }, - { label: 'Album', value: 'album' }, - ]} - defaultValue={settings.mpvProperties.replayGainMode} - onChange={(e) => handleSetMpvProperty('replayGainMode', e)} - /> - ), - description: - 'Adjust volume gain according to replaygain values stored in the file metadata (--replaygain)', - isHidden: settings.type !== PlaybackType.LOCAL, - note: 'Restart required', - title: 'ReplayGain mode', - }, - { - control: ( - <NumberInput - defaultValue={settings.mpvProperties.replayGainPreampDB} - width={75} - onChange={(e) => handleSetMpvProperty('replayGainPreampDB', e)} - /> - ), - description: - 'Pre-amplification gain in dB to apply to the selected replaygain gain (--replaygain-preamp)', - isHidden: settings.type !== PlaybackType.LOCAL, - title: 'ReplayGain preamp (dB)', - }, - { - control: ( - <Switch - defaultChecked={settings.mpvProperties.replayGainClip} - onChange={(e) => handleSetMpvProperty('replayGainClip', e.currentTarget.checked)} - /> - ), - description: - 'Prevent clipping caused by replaygain by automatically lowering the gain (--replaygain-clip)', - isHidden: settings.type !== PlaybackType.LOCAL, - title: 'ReplayGain clipping', - }, - { - control: ( - <NumberInput - defaultValue={settings.mpvProperties.replayGainFallbackDB} - width={75} - onBlur={(e) => handleSetMpvProperty('replayGainFallbackDB', e)} - /> - ), - description: - 'Gain in dB to apply if the file has no replay gain tags. This option is always applied if the replaygain logic is somehow inactive. If this is applied, no other replaygain options are applied', - isHidden: settings.type !== PlaybackType.LOCAL, - title: 'ReplayGain fallback (dB)', - }, - ]; - - return ( - <> - <SettingsSection options={options} /> - <Divider /> - <SettingsSection options={generalOptions} /> - <Divider /> - <SettingsSection options={replayGainOptions} /> - </> - ); + return ( + <> + <SettingsSection options={options} /> + <Divider /> + <SettingsSection options={generalOptions} /> + <Divider /> + <SettingsSection options={replayGainOptions} /> + </> + ); }; diff --git a/src/renderer/features/settings/components/playback/playback-tab.tsx b/src/renderer/features/settings/components/playback/playback-tab.tsx index 7384aca2..3e2c8299 100644 --- a/src/renderer/features/settings/components/playback/playback-tab.tsx +++ b/src/renderer/features/settings/components/playback/playback-tab.tsx @@ -6,20 +6,20 @@ import isElectron from 'is-electron'; import { LyricSettings } from '/@/renderer/features/settings/components/playback/lyric-settings'; const MpvSettings = lazy(() => - import('/@/renderer/features/settings/components/playback/mpv-settings').then((module) => { - return { default: module.MpvSettings }; - }), + import('/@/renderer/features/settings/components/playback/mpv-settings').then((module) => { + return { default: module.MpvSettings }; + }), ); export const PlaybackTab = () => { - return ( - <Stack spacing="md"> - <AudioSettings /> - <Suspense fallback={<></>}>{isElectron() && <MpvSettings />}</Suspense> - <Divider /> - <ScrobbleSettings /> - <Divider /> - <LyricSettings /> - </Stack> - ); + return ( + <Stack spacing="md"> + <AudioSettings /> + <Suspense fallback={<></>}>{isElectron() && <MpvSettings />}</Suspense> + <Divider /> + <ScrobbleSettings /> + <Divider /> + <LyricSettings /> + </Stack> + ); }; diff --git a/src/renderer/features/settings/components/playback/scrobble-settings.tsx b/src/renderer/features/settings/components/playback/scrobble-settings.tsx index 54dc6942..764f29d6 100644 --- a/src/renderer/features/settings/components/playback/scrobble-settings.tsx +++ b/src/renderer/features/settings/components/playback/scrobble-settings.tsx @@ -4,96 +4,97 @@ import { usePlaybackSettings, useSettingsStoreActions } from '/@/renderer/store/ import { SettingOption, SettingsSection } from '../settings-section'; export const ScrobbleSettings = () => { - const settings = usePlaybackSettings(); - const { setSettings } = useSettingsStoreActions(); + const settings = usePlaybackSettings(); + const { setSettings } = useSettingsStoreActions(); - const scrobbleOptions: SettingOption[] = [ - { - control: ( - <Switch - aria-label="Toggle scrobble" - defaultChecked={settings.scrobble.enabled} - onChange={(e) => { - setSettings({ - playback: { - ...settings, - scrobble: { - ...settings.scrobble, - enabled: e.currentTarget.checked, - }, - }, - }); - }} - /> - ), - description: 'Enable or disable scrobbling to your media server', - isHidden: !isElectron(), - title: 'Scrobble', - }, - { - control: ( - <Slider - aria-label="Scrobble percentage" - defaultValue={settings.scrobble.scrobbleAtPercentage} - label={`${settings.scrobble.scrobbleAtPercentage}%`} - max={90} - min={25} - w={100} - onChange={(e) => { - setSettings({ - playback: { - ...settings, - scrobble: { - ...settings.scrobble, - scrobbleAtPercentage: e, - }, - }, - }); - }} - /> - ), - description: 'The percentage of the song that must be played before submitting a scrobble', - isHidden: !isElectron(), - title: 'Minimum scrobble percentage*', - }, - { - control: ( - <NumberInput - aria-label="Scrobble duration in seconds" - defaultValue={settings.scrobble.scrobbleAtDuration} - max={1200} - min={0} - width={75} - onChange={(e) => { - if (e === '') return; - setSettings({ - playback: { - ...settings, - scrobble: { - ...settings.scrobble, - scrobbleAtDuration: e, - }, - }, - }); - }} - /> - ), - description: - 'The duration in seconds of a song that must be played before submitting a scrobble', - isHidden: !isElectron(), - title: 'Minimum scrobble duration (seconds)*', - }, - ]; + const scrobbleOptions: SettingOption[] = [ + { + control: ( + <Switch + aria-label="Toggle scrobble" + defaultChecked={settings.scrobble.enabled} + onChange={(e) => { + setSettings({ + playback: { + ...settings, + scrobble: { + ...settings.scrobble, + enabled: e.currentTarget.checked, + }, + }, + }); + }} + /> + ), + description: 'Enable or disable scrobbling to your media server', + isHidden: !isElectron(), + title: 'Scrobble', + }, + { + control: ( + <Slider + aria-label="Scrobble percentage" + defaultValue={settings.scrobble.scrobbleAtPercentage} + label={`${settings.scrobble.scrobbleAtPercentage}%`} + max={90} + min={25} + w={100} + onChange={(e) => { + setSettings({ + playback: { + ...settings, + scrobble: { + ...settings.scrobble, + scrobbleAtPercentage: e, + }, + }, + }); + }} + /> + ), + description: + 'The percentage of the song that must be played before submitting a scrobble', + isHidden: !isElectron(), + title: 'Minimum scrobble percentage*', + }, + { + control: ( + <NumberInput + aria-label="Scrobble duration in seconds" + defaultValue={settings.scrobble.scrobbleAtDuration} + max={1200} + min={0} + width={75} + onChange={(e) => { + if (e === '') return; + setSettings({ + playback: { + ...settings, + scrobble: { + ...settings.scrobble, + scrobbleAtDuration: e, + }, + }, + }); + }} + /> + ), + description: + 'The duration in seconds of a song that must be played before submitting a scrobble', + isHidden: !isElectron(), + title: 'Minimum scrobble duration (seconds)*', + }, + ]; - return ( - <> - <SettingsSection options={scrobbleOptions} /> - <Text - $secondary - size="sm" - > - *The scrobble will be submitted if one or more of the above conditions is met - </Text> - </> - ); + return ( + <> + <SettingsSection options={scrobbleOptions} /> + <Text + $secondary + size="sm" + > + *The scrobble will be submitted if one or more of the above conditions is met + </Text> + </> + ); }; diff --git a/src/renderer/features/settings/components/settings-content.tsx b/src/renderer/features/settings/components/settings-content.tsx index cc554f71..7d4864e0 100644 --- a/src/renderer/features/settings/components/settings-content.tsx +++ b/src/renderer/features/settings/components/settings-content.tsx @@ -5,70 +5,70 @@ import isElectron from 'is-electron'; import styled from 'styled-components'; const GeneralTab = lazy(() => - import('/@/renderer/features/settings/components/general/general-tab').then((module) => ({ - default: module.GeneralTab, - })), + import('/@/renderer/features/settings/components/general/general-tab').then((module) => ({ + default: module.GeneralTab, + })), ); const PlaybackTab = lazy(() => - import('/@/renderer/features/settings/components/playback/playback-tab').then((module) => ({ - default: module.PlaybackTab, - })), + import('/@/renderer/features/settings/components/playback/playback-tab').then((module) => ({ + default: module.PlaybackTab, + })), ); const ApplicationTab = lazy(() => - import('/@/renderer/features/settings/components/window/window-tab').then((module) => ({ - default: module.WindowTab, - })), + import('/@/renderer/features/settings/components/window/window-tab').then((module) => ({ + default: module.WindowTab, + })), ); const HotkeysTab = lazy(() => - import('/@/renderer/features/settings/components/hotkeys/hotkeys-tab').then((module) => ({ - default: module.HotkeysTab, - })), + import('/@/renderer/features/settings/components/hotkeys/hotkeys-tab').then((module) => ({ + default: module.HotkeysTab, + })), ); const TabContainer = styled.div` - width: 100%; - height: 100%; - padding: 1rem; - overflow: scroll; + width: 100%; + height: 100%; + padding: 1rem; + overflow: scroll; `; export const SettingsContent = () => { - const currentTab = useSettingsStore((state) => state.tab); - const { setSettings } = useSettingsStoreActions(); + const currentTab = useSettingsStore((state) => state.tab); + const { setSettings } = useSettingsStoreActions(); - return ( - <TabContainer> - <Tabs - keepMounted={false} - orientation="horizontal" - value={currentTab} - variant="default" - onTabChange={(e) => e && setSettings({ tab: e })} - > - <Tabs.List> - <Tabs.Tab value="general">General</Tabs.Tab> - <Tabs.Tab value="playback">Playback</Tabs.Tab> - <Tabs.Tab value="hotkeys">Hotkeys</Tabs.Tab> - {isElectron() && <Tabs.Tab value="window">Window</Tabs.Tab>} - </Tabs.List> - <Tabs.Panel value="general"> - <GeneralTab /> - </Tabs.Panel> - <Tabs.Panel value="playback"> - <PlaybackTab /> - </Tabs.Panel> - <Tabs.Panel value="hotkeys"> - <HotkeysTab /> - </Tabs.Panel> - {isElectron() && ( - <Tabs.Panel value="window"> - <ApplicationTab /> - </Tabs.Panel> - )} - </Tabs> - </TabContainer> - ); + return ( + <TabContainer> + <Tabs + keepMounted={false} + orientation="horizontal" + value={currentTab} + variant="default" + onTabChange={(e) => e && setSettings({ tab: e })} + > + <Tabs.List> + <Tabs.Tab value="general">General</Tabs.Tab> + <Tabs.Tab value="playback">Playback</Tabs.Tab> + <Tabs.Tab value="hotkeys">Hotkeys</Tabs.Tab> + {isElectron() && <Tabs.Tab value="window">Window</Tabs.Tab>} + </Tabs.List> + <Tabs.Panel value="general"> + <GeneralTab /> + </Tabs.Panel> + <Tabs.Panel value="playback"> + <PlaybackTab /> + </Tabs.Panel> + <Tabs.Panel value="hotkeys"> + <HotkeysTab /> + </Tabs.Panel> + {isElectron() && ( + <Tabs.Panel value="window"> + <ApplicationTab /> + </Tabs.Panel> + )} + </Tabs> + </TabContainer> + ); }; diff --git a/src/renderer/features/settings/components/settings-header.tsx b/src/renderer/features/settings/components/settings-header.tsx index f6429800..4dba5a39 100644 --- a/src/renderer/features/settings/components/settings-header.tsx +++ b/src/renderer/features/settings/components/settings-header.tsx @@ -6,43 +6,43 @@ import { LibraryHeaderBar } from '/@/renderer/features/shared'; import { useSettingsStoreActions } from '../../../store/settings.store'; export const SettingsHeader = () => { - const { reset } = useSettingsStoreActions(); + const { reset } = useSettingsStoreActions(); - const handleResetToDefault = () => { - reset(); - closeAllModals(); - }; + const handleResetToDefault = () => { + reset(); + closeAllModals(); + }; - const openResetConfirmModal = () => { - openModal({ - children: <ConfirmModal onConfirm={handleResetToDefault}>Are you sure?</ConfirmModal>, - title: 'Reset settings to default', - }); - }; + const openResetConfirmModal = () => { + openModal({ + children: <ConfirmModal onConfirm={handleResetToDefault}>Are you sure?</ConfirmModal>, + title: 'Reset settings to default', + }); + }; - return ( - <Flex> - <PageHeader> - <LibraryHeaderBar> - <Flex - align="center" - justify="space-between" - w="100%" - > - <Group noWrap> - <RiSettings2Fill size="2rem" /> - <LibraryHeaderBar.Title>Settings</LibraryHeaderBar.Title> - </Group> - <Button - compact - variant="default" - onClick={openResetConfirmModal} - > - Reset to default - </Button> - </Flex> - </LibraryHeaderBar> - </PageHeader> - </Flex> - ); + return ( + <Flex> + <PageHeader> + <LibraryHeaderBar> + <Flex + align="center" + justify="space-between" + w="100%" + > + <Group noWrap> + <RiSettings2Fill size="2rem" /> + <LibraryHeaderBar.Title>Settings</LibraryHeaderBar.Title> + </Group> + <Button + compact + variant="default" + onClick={openResetConfirmModal} + > + Reset to default + </Button> + </Flex> + </LibraryHeaderBar> + </PageHeader> + </Flex> + ); }; diff --git a/src/renderer/features/settings/components/settings-option.tsx b/src/renderer/features/settings/components/settings-option.tsx index 2a3d6179..10bc3ac9 100644 --- a/src/renderer/features/settings/components/settings-option.tsx +++ b/src/renderer/features/settings/components/settings-option.tsx @@ -4,65 +4,65 @@ import { RiInformationLine } from 'react-icons/ri'; import { Text, Tooltip } from '/@/renderer/components'; interface SettingsOptionProps { - control: React.ReactNode; - description?: React.ReactNode | string; - note?: string; - title: React.ReactNode | string; + control: React.ReactNode; + description?: React.ReactNode | string; + note?: string; + title: React.ReactNode | string; } export const SettingsOptions = ({ title, description, control, note }: SettingsOptionProps) => { - return ( - <> - <Group - noWrap - position="apart" - sx={{ alignItems: 'center' }} - > - <Stack - spacing="xs" - sx={{ - alignSelf: 'flex-start', - display: 'flex', - maxWidth: '50%', - }} - > - <Group> - <Text - $noSelect - size="md" + return ( + <> + <Group + noWrap + position="apart" + sx={{ alignItems: 'center' }} > - {title} - </Text> - {note && ( - <Tooltip - label={note} - openDelay={0} - > - <Group> - <RiInformationLine size={15} /> - </Group> - </Tooltip> - )} - </Group> - {React.isValidElement(description) ? ( - description - ) : ( - <Text - $noSelect - $secondary - size="sm" - > - {description} - </Text> - )} - </Stack> - <Group position="right">{control}</Group> - </Group> - </> - ); + <Stack + spacing="xs" + sx={{ + alignSelf: 'flex-start', + display: 'flex', + maxWidth: '50%', + }} + > + <Group> + <Text + $noSelect + size="md" + > + {title} + </Text> + {note && ( + <Tooltip + label={note} + openDelay={0} + > + <Group> + <RiInformationLine size={15} /> + </Group> + </Tooltip> + )} + </Group> + {React.isValidElement(description) ? ( + description + ) : ( + <Text + $noSelect + $secondary + size="sm" + > + {description} + </Text> + )} + </Stack> + <Group position="right">{control}</Group> + </Group> + </> + ); }; SettingsOptions.defaultProps = { - description: undefined, - note: undefined, + description: undefined, + note: undefined, }; diff --git a/src/renderer/features/settings/components/settings-section.tsx b/src/renderer/features/settings/components/settings-section.tsx index cc988f41..7aefabf0 100644 --- a/src/renderer/features/settings/components/settings-section.tsx +++ b/src/renderer/features/settings/components/settings-section.tsx @@ -1,28 +1,28 @@ import { SettingsOptions } from '/@/renderer/features/settings/components/settings-option'; export type SettingOption = { - control: JSX.Element; - description: string | JSX.Element; - isHidden?: boolean; - note?: string; - title: string; + control: JSX.Element; + description: string | JSX.Element; + isHidden?: boolean; + note?: string; + title: string; }; interface SettingsSectionProps { - options: SettingOption[]; + options: SettingOption[]; } export const SettingsSection = ({ options }: SettingsSectionProps) => { - return ( - <> - {options - .filter((o) => !o.isHidden) - .map((option) => ( - <SettingsOptions - key={`general-${option.title}`} - {...option} - /> - ))} - </> - ); + return ( + <> + {options + .filter((o) => !o.isHidden) + .map((option) => ( + <SettingsOptions + key={`general-${option.title}`} + {...option} + /> + ))} + </> + ); }; diff --git a/src/renderer/features/settings/components/window/update-settings.tsx b/src/renderer/features/settings/components/window/update-settings.tsx index f02bd0ab..a5b34333 100644 --- a/src/renderer/features/settings/components/window/update-settings.tsx +++ b/src/renderer/features/settings/components/window/update-settings.tsx @@ -1,41 +1,41 @@ import isElectron from 'is-electron'; import { useWindowSettings, useSettingsStoreActions } from '../../../../store/settings.store'; import { - SettingsSection, - SettingOption, + SettingsSection, + SettingOption, } from '/@/renderer/features/settings/components/settings-section'; import { Switch } from '/@/renderer/components'; const localSettings = isElectron() ? window.electron.localSettings : null; export const UpdateSettings = () => { - const settings = useWindowSettings(); - const { setSettings } = useSettingsStoreActions(); + const settings = useWindowSettings(); + const { setSettings } = useSettingsStoreActions(); - const updateOptions: SettingOption[] = [ - { - control: ( - <Switch - aria-label="Disable automatic updates" - defaultChecked={settings.disableAutoUpdate} - disabled={!isElectron()} - onChange={(e) => { - if (!e) return; - localSettings?.set('disable_auto_updates', e.currentTarget.checked); - setSettings({ - window: { - ...settings, - disableAutoUpdate: e.currentTarget.checked, - }, - }); - }} - /> - ), - description: 'Enabling this option will disable checking for new versions on startup', - isHidden: !isElectron(), - title: 'Disable automatic updates', - }, - ]; + const updateOptions: SettingOption[] = [ + { + control: ( + <Switch + aria-label="Disable automatic updates" + defaultChecked={settings.disableAutoUpdate} + disabled={!isElectron()} + onChange={(e) => { + if (!e) return; + localSettings?.set('disable_auto_updates', e.currentTarget.checked); + setSettings({ + window: { + ...settings, + disableAutoUpdate: e.currentTarget.checked, + }, + }); + }} + /> + ), + description: 'Enabling this option will disable checking for new versions on startup', + isHidden: !isElectron(), + title: 'Disable automatic updates', + }, + ]; - return <SettingsSection options={updateOptions} />; + return <SettingsSection options={updateOptions} />; }; diff --git a/src/renderer/features/settings/components/window/window-settings.tsx b/src/renderer/features/settings/components/window/window-settings.tsx index 9d6bc64f..9a71109a 100644 --- a/src/renderer/features/settings/components/window/window-settings.tsx +++ b/src/renderer/features/settings/components/window/window-settings.tsx @@ -2,114 +2,122 @@ import isElectron from 'is-electron'; import { Platform } from '/@/renderer/types'; import { useWindowSettings, useSettingsStoreActions } from '../../../../store/settings.store'; import { - SettingsSection, - SettingOption, + SettingsSection, + SettingOption, } from '/@/renderer/features/settings/components/settings-section'; import { Select, Switch, toast } from '/@/renderer/components'; const WINDOW_BAR_OPTIONS = [ - { label: 'Web (hidden)', value: Platform.WEB }, - { label: 'Windows', value: Platform.WINDOWS }, - { label: 'macOS', value: Platform.MACOS }, - { label: 'Native', value: Platform.LINUX }, + { label: 'Web (hidden)', value: Platform.WEB }, + { label: 'Windows', value: Platform.WINDOWS }, + { label: 'macOS', value: Platform.MACOS }, + { label: 'Native', value: Platform.LINUX }, ]; const localSettings = isElectron() ? window.electron.localSettings : null; export const WindowSettings = () => { - const settings = useWindowSettings(); - const { setSettings } = useSettingsStoreActions(); + const settings = useWindowSettings(); + const { setSettings } = useSettingsStoreActions(); - const windowOptions: SettingOption[] = [ - { - control: ( - <Select - data={WINDOW_BAR_OPTIONS} - disabled={!isElectron()} - value={settings.windowBarStyle} - onChange={(e) => { - if (!e) return; + const windowOptions: SettingOption[] = [ + { + control: ( + <Select + data={WINDOW_BAR_OPTIONS} + disabled={!isElectron()} + value={settings.windowBarStyle} + onChange={(e) => { + if (!e) return; - // Platform.LINUX is used as the native frame option regardless of the actual platform - const hasFrame = localSettings?.get('window_has_frame') as boolean | undefined; - const isSwitchingToFrame = !hasFrame && e === Platform.LINUX; - const isSwitchingToNoFrame = hasFrame && e !== Platform.LINUX; + // Platform.LINUX is used as the native frame option regardless of the actual platform + const hasFrame = localSettings?.get('window_has_frame') as + | boolean + | undefined; + const isSwitchingToFrame = !hasFrame && e === Platform.LINUX; + const isSwitchingToNoFrame = hasFrame && e !== Platform.LINUX; - const requireRestart = isSwitchingToFrame || isSwitchingToNoFrame; + const requireRestart = isSwitchingToFrame || isSwitchingToNoFrame; - if (requireRestart) { - toast.info({ - autoClose: false, - id: 'restart-toast', - message: 'Restart to apply changes... close the notification to restart Feishin', - onClose: () => { - window.electron.ipc.send('app-restart'); - }, - title: 'Restart required', - }); - } else { - toast.update({ autoClose: 0, id: 'restart-toast', message: '', onClose: () => {} }); // clean old toasts - } + if (requireRestart) { + toast.info({ + autoClose: false, + id: 'restart-toast', + message: + 'Restart to apply changes... close the notification to restart Feishin', + onClose: () => { + window.electron.ipc.send('app-restart'); + }, + title: 'Restart required', + }); + } else { + toast.update({ + autoClose: 0, + id: 'restart-toast', + message: '', + onClose: () => {}, + }); // clean old toasts + } - localSettings?.set('window_window_bar_style', e as Platform); - setSettings({ - window: { - ...settings, - windowBarStyle: e as Platform, - }, - }); - }} - /> - ), - description: 'Adjust the style of the application window bar', - isHidden: !isElectron(), - title: 'Window bar style', - }, - { - control: ( - <Switch - aria-label="Toggle minimize to tray" - defaultChecked={settings.exitToTray} - disabled={!isElectron()} - onChange={(e) => { - if (!e) return; - localSettings?.set('window_minimize_to_tray', e.currentTarget.checked); - setSettings({ - window: { - ...settings, - minimizeToTray: e.currentTarget.checked, - }, - }); - }} - /> - ), - description: 'Minimize the application to the system tray', - isHidden: !isElectron(), - title: 'Minimize to tray', - }, - { - control: ( - <Switch - aria-label="Toggle exit to tray" - defaultChecked={settings.exitToTray} - disabled={!isElectron()} - onChange={(e) => { - if (!e) return; - localSettings?.set('window_exit_to_tray', e.currentTarget.checked); - setSettings({ - window: { - ...settings, - exitToTray: e.currentTarget.checked, - }, - }); - }} - /> - ), - description: 'Exit the application to the system tray', - isHidden: !isElectron(), - title: 'Exit to tray', - }, - ]; + localSettings?.set('window_window_bar_style', e as Platform); + setSettings({ + window: { + ...settings, + windowBarStyle: e as Platform, + }, + }); + }} + /> + ), + description: 'Adjust the style of the application window bar', + isHidden: !isElectron(), + title: 'Window bar style', + }, + { + control: ( + <Switch + aria-label="Toggle minimize to tray" + defaultChecked={settings.exitToTray} + disabled={!isElectron()} + onChange={(e) => { + if (!e) return; + localSettings?.set('window_minimize_to_tray', e.currentTarget.checked); + setSettings({ + window: { + ...settings, + minimizeToTray: e.currentTarget.checked, + }, + }); + }} + /> + ), + description: 'Minimize the application to the system tray', + isHidden: !isElectron(), + title: 'Minimize to tray', + }, + { + control: ( + <Switch + aria-label="Toggle exit to tray" + defaultChecked={settings.exitToTray} + disabled={!isElectron()} + onChange={(e) => { + if (!e) return; + localSettings?.set('window_exit_to_tray', e.currentTarget.checked); + setSettings({ + window: { + ...settings, + exitToTray: e.currentTarget.checked, + }, + }); + }} + /> + ), + description: 'Exit the application to the system tray', + isHidden: !isElectron(), + title: 'Exit to tray', + }, + ]; - return <SettingsSection options={windowOptions} />; + return <SettingsSection options={windowOptions} />; }; diff --git a/src/renderer/features/settings/components/window/window-tab.tsx b/src/renderer/features/settings/components/window/window-tab.tsx index c191842c..101ed9f6 100644 --- a/src/renderer/features/settings/components/window/window-tab.tsx +++ b/src/renderer/features/settings/components/window/window-tab.tsx @@ -3,11 +3,11 @@ import { UpdateSettings } from '/@/renderer/features/settings/components/window/ import { WindowSettings } from '/@/renderer/features/settings/components/window/window-settings'; export const WindowTab = () => { - return ( - <Stack spacing="md"> - <WindowSettings /> - <Divider /> - <UpdateSettings /> - </Stack> - ); + return ( + <Stack spacing="md"> + <WindowSettings /> + <Divider /> + <UpdateSettings /> + </Stack> + ); }; diff --git a/src/renderer/features/settings/routes/settings-route.tsx b/src/renderer/features/settings/routes/settings-route.tsx index cba6e6f2..ca633c77 100644 --- a/src/renderer/features/settings/routes/settings-route.tsx +++ b/src/renderer/features/settings/routes/settings-route.tsx @@ -4,18 +4,18 @@ import { SettingsHeader } from '/@/renderer/features/settings/components/setting import { AnimatedPage } from '/@/renderer/features/shared'; const SettingsRoute = () => { - return ( - <AnimatedPage> - <Flex - direction="column" - h="100%" - w="100%" - > - <SettingsHeader /> - <SettingsContent /> - </Flex> - </AnimatedPage> - ); + return ( + <AnimatedPage> + <Flex + direction="column" + h="100%" + w="100%" + > + <SettingsHeader /> + <SettingsContent /> + </Flex> + </AnimatedPage> + ); }; export default SettingsRoute; diff --git a/src/renderer/features/shared/components/animated-page.tsx b/src/renderer/features/shared/components/animated-page.tsx index 9a98bf07..21cca82f 100644 --- a/src/renderer/features/shared/components/animated-page.tsx +++ b/src/renderer/features/shared/components/animated-page.tsx @@ -4,37 +4,37 @@ import { motion } from 'framer-motion'; import styled from 'styled-components'; interface AnimatedPageProps { - children: ReactNode; + children: ReactNode; } const StyledAnimatedPage = styled(motion.main)` - position: relative; - display: flex; - flex-direction: column; - width: 100%; - height: 100%; - overflow: hidden; + position: relative; + display: flex; + flex-direction: column; + width: 100%; + height: 100%; + overflow: hidden; `; const variants = { - animate: { opacity: 1 }, - exit: { opacity: 0 }, - initial: { opacity: 0 }, + animate: { opacity: 1 }, + exit: { opacity: 0 }, + initial: { opacity: 0 }, }; export const AnimatedPage = forwardRef( - ({ children }: AnimatedPageProps, ref: Ref<HTMLDivElement>) => { - return ( - <StyledAnimatedPage - ref={ref} - animate="animate" - exit="exit" - initial="initial" - transition={{ duration: 0.5, ease: 'anticipate' }} - variants={variants} - > - {children} - </StyledAnimatedPage> - ); - }, + ({ children }: AnimatedPageProps, ref: Ref<HTMLDivElement>) => { + return ( + <StyledAnimatedPage + ref={ref} + animate="animate" + exit="exit" + initial="initial" + transition={{ duration: 0.5, ease: 'anticipate' }} + variants={variants} + > + {children} + </StyledAnimatedPage> + ); + }, ); diff --git a/src/renderer/features/shared/components/filter-bar.tsx b/src/renderer/features/shared/components/filter-bar.tsx index 89d5d6c5..681f44ee 100644 --- a/src/renderer/features/shared/components/filter-bar.tsx +++ b/src/renderer/features/shared/components/filter-bar.tsx @@ -3,11 +3,11 @@ import styled from 'styled-components'; import { Paper } from '/@/renderer/components'; const StyledFilterBar = styled(Paper)` - z-index: 1; - padding: 1rem; - box-shadow: 0 5px 15px rgba(0, 0, 0, 65%); + z-index: 1; + padding: 1rem; + box-shadow: 0 5px 15px rgba(0, 0, 0, 65%); `; export const FilterBar = ({ children, ...props }: PaperProps) => { - return <StyledFilterBar {...props}>{children}</StyledFilterBar>; + return <StyledFilterBar {...props}>{children}</StyledFilterBar>; }; diff --git a/src/renderer/features/shared/components/library-header-bar.tsx b/src/renderer/features/shared/components/library-header-bar.tsx index b0828bba..e5b639e1 100644 --- a/src/renderer/features/shared/components/library-header-bar.tsx +++ b/src/renderer/features/shared/components/library-header-bar.tsx @@ -5,67 +5,67 @@ import { PlayButton as PlayBtn } from '/@/renderer/features/shared/components/pl import styled from 'styled-components'; interface LibraryHeaderBarProps { - children: ReactNode; + children: ReactNode; } const HeaderContainer = styled.div` - display: flex; - flex-wrap: nowrap; - gap: 1rem; - align-items: center; - width: 100%; - height: 100%; - padding: 0 1rem; + display: flex; + flex-wrap: nowrap; + gap: 1rem; + align-items: center; + width: 100%; + height: 100%; + padding: 0 1rem; `; export const LibraryHeaderBar = ({ children }: LibraryHeaderBarProps) => { - return <HeaderContainer>{children}</HeaderContainer>; + return <HeaderContainer>{children}</HeaderContainer>; }; interface TitleProps { - children: ReactNode; + children: ReactNode; } const Title = ({ children }: TitleProps) => { - return ( - <TextTitle - order={1} - overflow="hidden" - weight={700} - > - {children} - </TextTitle> - ); + return ( + <TextTitle + order={1} + overflow="hidden" + weight={700} + > + {children} + </TextTitle> + ); }; interface PlayButtonProps { - onClick: () => void; + onClick: () => void; } const PlayButton = ({ onClick }: PlayButtonProps) => { - return ( - <Box> - <PlayBtn - h="45px" - w="45px" - onClick={onClick} - /> - </Box> - ); + return ( + <Box> + <PlayBtn + h="45px" + w="45px" + onClick={onClick} + /> + </Box> + ); }; const Badge = styled(Paper)` - padding: 0.3rem 1rem; - font-weight: 600; - border-radius: 0.3rem; + padding: 0.3rem 1rem; + font-weight: 600; + border-radius: 0.3rem; `; interface HeaderBadgeProps extends PaperProps { - isLoading?: boolean; + isLoading?: boolean; } const HeaderBadge = ({ children, isLoading, ...props }: HeaderBadgeProps) => { - return <Badge {...props}>{isLoading ? <SpinnerIcon /> : children}</Badge>; + return <Badge {...props}>{isLoading ? <SpinnerIcon /> : children}</Badge>; }; LibraryHeaderBar.Title = Title; diff --git a/src/renderer/features/shared/components/library-header.tsx b/src/renderer/features/shared/components/library-header.tsx index cc52503d..608e710a 100644 --- a/src/renderer/features/shared/components/library-header.tsx +++ b/src/renderer/features/shared/components/library-header.tsx @@ -10,150 +10,151 @@ import { Text, TextTitle } from '/@/renderer/components'; import { useContainerQuery } from '/@/renderer/hooks'; const HeaderContainer = styled.div<{ imageSize: number }>` - position: relative; - display: grid; - grid-auto-columns: 1fr; - grid-template-areas: 'image info'; - grid-template-rows: 1fr; - grid-template-columns: ${(props) => props.imageSize + 25}px minmax(0, 1fr); - gap: 0.5rem; - width: 100%; - max-width: 100%; - height: 30vh; - min-height: 340px; - max-height: 500px; - padding: 5rem 2rem 2rem; + position: relative; + display: grid; + grid-auto-columns: 1fr; + grid-template-areas: 'image info'; + grid-template-rows: 1fr; + grid-template-columns: ${(props) => props.imageSize + 25}px minmax(0, 1fr); + gap: 0.5rem; + width: 100%; + max-width: 100%; + height: 30vh; + min-height: 340px; + max-height: 500px; + padding: 5rem 2rem 2rem; `; const CoverImageWrapper = styled.div` - z-index: 15; - display: flex; - grid-area: image; - align-items: flex-end; - justify-content: center; - height: 100%; - filter: drop-shadow(0 0 8px rgb(0, 0, 0, 50%)); + z-index: 15; + display: flex; + grid-area: image; + align-items: flex-end; + justify-content: center; + height: 100%; + filter: drop-shadow(0 0 8px rgb(0, 0, 0, 50%)); `; const MetadataWrapper = styled.div` - z-index: 15; - display: flex; - flex-direction: column; - grid-area: info; - justify-content: flex-end; - width: 100%; + z-index: 15; + display: flex; + flex-direction: column; + grid-area: info; + justify-content: flex-end; + width: 100%; `; const StyledImage = styled(SimpleImg)` - img { - object-fit: cover; - } + img { + object-fit: cover; + } `; const BackgroundImage = styled.div<{ background: string }>` - position: absolute; - top: 0; - z-index: 0; - width: 100%; - height: 100%; - background: ${(props) => props.background}; + position: absolute; + top: 0; + z-index: 0; + width: 100%; + height: 100%; + background: ${(props) => props.background}; `; const BackgroundImageOverlay = styled.div` - position: absolute; - top: 0; - left: 0; - z-index: 0; - width: 100%; - height: 100%; - background: linear-gradient(180deg, rgba(25, 26, 28, 5%), var(--main-bg)), var(--background-noise); + position: absolute; + top: 0; + left: 0; + z-index: 0; + width: 100%; + height: 100%; + background: linear-gradient(180deg, rgba(25, 26, 28, 5%), var(--main-bg)), + var(--background-noise); `; interface LibraryHeaderProps { - background: string; - children?: ReactNode; - imagePlaceholderUrl?: string | null; - imageUrl?: string | null; - item: { route: string; type: LibraryItem }; - title: string; + background: string; + children?: ReactNode; + imagePlaceholderUrl?: string | null; + imageUrl?: string | null; + item: { route: string; type: LibraryItem }; + title: string; } export const LibraryHeader = forwardRef( - ( - { imageUrl, imagePlaceholderUrl, background, title, item, children }: LibraryHeaderProps, - ref: Ref<HTMLDivElement>, - ) => { - const cq = useContainerQuery(); - const mergedRef = useMergedRef(ref, cq.ref); - const titleSize = cq.isXl - ? '6rem' - : cq.isLg - ? '5.5rem' - : cq.isMd - ? '5rem' - : cq.isSm - ? '4.5rem' - : '3rem'; + ( + { imageUrl, imagePlaceholderUrl, background, title, item, children }: LibraryHeaderProps, + ref: Ref<HTMLDivElement>, + ) => { + const cq = useContainerQuery(); + const mergedRef = useMergedRef(ref, cq.ref); + const titleSize = cq.isXl + ? '6rem' + : cq.isLg + ? '5.5rem' + : cq.isMd + ? '5rem' + : cq.isSm + ? '4.5rem' + : '3rem'; - const imageSize = cq.isLg ? 250 : cq.isMd ? 225 : cq.isSm ? 200 : 175; + const imageSize = cq.isLg ? 250 : cq.isMd ? 225 : cq.isSm ? 200 : 175; - return ( - <HeaderContainer - ref={mergedRef} - imageSize={imageSize} - > - <BackgroundImage background={background} /> - <BackgroundImageOverlay /> - <CoverImageWrapper> - {imageUrl ? ( - <StyledImage - alt="cover" - height={imageSize} - placeholder={imagePlaceholderUrl || 'var(--placeholder-bg)'} - src={imageUrl} - width={imageSize} - /> - ) : ( - <Center - sx={{ - background: 'var(--placeholder-bg)', - borderRadius: 'var(--card-default-radius)', - height: `${imageSize}px`, - width: `${imageSize}px`, - }} + return ( + <HeaderContainer + ref={mergedRef} + imageSize={imageSize} > - <RiAlbumFill - color="var(--placeholder-fg)" - size={35} - /> - </Center> - )} - </CoverImageWrapper> - <MetadataWrapper> - <Group> - <Text - $link - component={Link} - to={item.route} - tt="uppercase" - weight={600} - > - {item.type} - </Text> - </Group> - <TextTitle - lh={1.15} - lineClamp={2} - overflow="hidden" - pb={cq.isXs ? '0' : cq.isSm ? '0.2rem' : '0.36rem'} - sx={{ fontSize: titleSize, overflow: 'hidden' }} - weight={900} - > - {title} - </TextTitle> - {children} - </MetadataWrapper> - </HeaderContainer> - ); - }, + <BackgroundImage background={background} /> + <BackgroundImageOverlay /> + <CoverImageWrapper> + {imageUrl ? ( + <StyledImage + alt="cover" + height={imageSize} + placeholder={imagePlaceholderUrl || 'var(--placeholder-bg)'} + src={imageUrl} + width={imageSize} + /> + ) : ( + <Center + sx={{ + background: 'var(--placeholder-bg)', + borderRadius: 'var(--card-default-radius)', + height: `${imageSize}px`, + width: `${imageSize}px`, + }} + > + <RiAlbumFill + color="var(--placeholder-fg)" + size={35} + /> + </Center> + )} + </CoverImageWrapper> + <MetadataWrapper> + <Group> + <Text + $link + component={Link} + to={item.route} + tt="uppercase" + weight={600} + > + {item.type} + </Text> + </Group> + <TextTitle + lh={1.15} + lineClamp={2} + overflow="hidden" + pb={cq.isXs ? '0' : cq.isSm ? '0.2rem' : '0.36rem'} + sx={{ fontSize: titleSize, overflow: 'hidden' }} + weight={900} + > + {title} + </TextTitle> + {children} + </MetadataWrapper> + </HeaderContainer> + ); + }, ); diff --git a/src/renderer/features/shared/components/play-button.tsx b/src/renderer/features/shared/components/play-button.tsx index 31beda68..cc4114b7 100644 --- a/src/renderer/features/shared/components/play-button.tsx +++ b/src/renderer/features/shared/components/play-button.tsx @@ -3,43 +3,43 @@ import { RiPlayFill } from 'react-icons/ri'; import styled from 'styled-components'; const MotionButton = styled(UnstyledButton)` - display: flex; - align-items: center; - justify-content: center; - background-color: var(--btn-filled-bg); - border: none; - border-radius: 50%; - opacity: 0.8; - - svg { - fill: var(--btn-filled-fg); - } - - &:hover { - background-color: var(--btn-filled-bg-hover); - transform: scale(1.1); + display: flex; + align-items: center; + justify-content: center; + background-color: var(--btn-filled-bg); + border: none; + border-radius: 50%; + opacity: 0.8; svg { - fill: var(--btn-filled-fg-hover); + fill: var(--btn-filled-fg); } - } - &:active { - transform: scale(0.95); - } + &:hover { + background-color: var(--btn-filled-bg-hover); + transform: scale(1.1); - transition: background-color 0.2s ease-in-out; - transition: transform 0.2s ease-in-out; + svg { + fill: var(--btn-filled-fg-hover); + } + } + + &:active { + transform: scale(0.95); + } + + transition: background-color 0.2s ease-in-out; + transition: transform 0.2s ease-in-out; `; export const PlayButton = ({ ...props }: any) => { - return ( - <MotionButton - {...props} - h="45px" - w="45px" - > - <RiPlayFill size={20} /> - </MotionButton> - ); + return ( + <MotionButton + {...props} + h="45px" + w="45px" + > + <RiPlayFill size={20} /> + </MotionButton> + ); }; diff --git a/src/renderer/features/shared/components/resize-handle.tsx b/src/renderer/features/shared/components/resize-handle.tsx index de1cd6fc..6d88d219 100644 --- a/src/renderer/features/shared/components/resize-handle.tsx +++ b/src/renderer/features/shared/components/resize-handle.tsx @@ -1,33 +1,33 @@ import styled from 'styled-components'; export const ResizeHandle = styled.div<{ - isResizing: boolean; - placement: 'top' | 'left' | 'bottom' | 'right'; + isResizing: boolean; + placement: 'top' | 'left' | 'bottom' | 'right'; }>` - position: absolute; - top: ${(props) => props.placement === 'top' && 0}; - right: ${(props) => props.placement === 'right' && 0}; - bottom: ${(props) => props.placement === 'bottom' && 0}; - left: ${(props) => props.placement === 'left' && 0}; - z-index: 90; - width: 4px; - height: 100%; - cursor: ew-resize; - opacity: ${(props) => (props.isResizing ? 1 : 0)}; - - &:hover { - opacity: 0.7; - } - - &::before { position: absolute; top: ${(props) => props.placement === 'top' && 0}; right: ${(props) => props.placement === 'right' && 0}; bottom: ${(props) => props.placement === 'bottom' && 0}; left: ${(props) => props.placement === 'left' && 0}; - width: 1px; + z-index: 90; + width: 4px; height: 100%; - background-color: var(--sidebar-handle-bg); - content: ''; - } + cursor: ew-resize; + opacity: ${(props) => (props.isResizing ? 1 : 0)}; + + &:hover { + opacity: 0.7; + } + + &::before { + position: absolute; + top: ${(props) => props.placement === 'top' && 0}; + right: ${(props) => props.placement === 'right' && 0}; + bottom: ${(props) => props.placement === 'bottom' && 0}; + left: ${(props) => props.placement === 'left' && 0}; + width: 1px; + height: 100%; + background-color: var(--sidebar-handle-bg); + content: ''; + } `; diff --git a/src/renderer/features/shared/mutations/create-favorite-mutation.ts b/src/renderer/features/shared/mutations/create-favorite-mutation.ts index 91b139c1..a518f6dd 100644 --- a/src/renderer/features/shared/mutations/create-favorite-mutation.ts +++ b/src/renderer/features/shared/mutations/create-favorite-mutation.ts @@ -3,77 +3,80 @@ import { AxiosError } from 'axios'; import { api } from '/@/renderer/api'; import { queryKeys } from '/@/renderer/api/query-keys'; import { - AlbumArtistDetailResponse, - AlbumDetailResponse, - FavoriteArgs, - FavoriteResponse, - LibraryItem, + AlbumArtistDetailResponse, + AlbumDetailResponse, + FavoriteArgs, + FavoriteResponse, + LibraryItem, } from '/@/renderer/api/types'; import { MutationHookArgs } from '/@/renderer/lib/react-query'; import { getServerById, useSetAlbumListItemDataById, useSetQueueFavorite } from '/@/renderer/store'; export const useCreateFavorite = (args: MutationHookArgs) => { - const { options } = args || {}; - const queryClient = useQueryClient(); - const setAlbumListData = useSetAlbumListItemDataById(); - const setQueueFavorite = useSetQueueFavorite(); + const { options } = args || {}; + const queryClient = useQueryClient(); + const setAlbumListData = useSetAlbumListItemDataById(); + const setQueueFavorite = useSetQueueFavorite(); - return useMutation< - FavoriteResponse, - AxiosError, - Omit<FavoriteArgs, 'server' | 'apiClientProps'>, - null - >({ - mutationFn: (args) => { - const server = getServerById(args.serverId); - if (!server) throw new Error('Server not found'); - return api.controller.createFavorite({ ...args, apiClientProps: { server } }); - }, - onSuccess: (_data, variables) => { - const { serverId } = variables; + return useMutation< + FavoriteResponse, + AxiosError, + Omit<FavoriteArgs, 'server' | 'apiClientProps'>, + null + >({ + mutationFn: (args) => { + const server = getServerById(args.serverId); + if (!server) throw new Error('Server not found'); + return api.controller.createFavorite({ ...args, apiClientProps: { server } }); + }, + onSuccess: (_data, variables) => { + const { serverId } = variables; - if (!serverId) return; + if (!serverId) return; - for (const id of variables.query.id) { - // Set the userFavorite property to true for the album in the album list data store - if (variables.query.type === LibraryItem.ALBUM) { - setAlbumListData(id, { userFavorite: true }); - } - } + for (const id of variables.query.id) { + // Set the userFavorite property to true for the album in the album list data store + if (variables.query.type === LibraryItem.ALBUM) { + setAlbumListData(id, { userFavorite: true }); + } + } - if (variables.query.type === LibraryItem.SONG) { - setQueueFavorite(variables.query.id, true); - } + if (variables.query.type === LibraryItem.SONG) { + setQueueFavorite(variables.query.id, true); + } - // We only need to set if we're already on the album detail page - if (variables.query.type === LibraryItem.ALBUM && variables.query.id.length === 1) { - const queryKey = queryKeys.albums.detail(serverId, { id: variables.query.id[0] }); - const previous = queryClient.getQueryData<AlbumDetailResponse>(queryKey); + // We only need to set if we're already on the album detail page + if (variables.query.type === LibraryItem.ALBUM && variables.query.id.length === 1) { + const queryKey = queryKeys.albums.detail(serverId, { id: variables.query.id[0] }); + const previous = queryClient.getQueryData<AlbumDetailResponse>(queryKey); - if (previous) { - queryClient.setQueryData<AlbumDetailResponse>(queryKey, { - ...previous, - userFavorite: true, - }); - } - } + if (previous) { + queryClient.setQueryData<AlbumDetailResponse>(queryKey, { + ...previous, + userFavorite: true, + }); + } + } - // We only need to set if we're already on the album detail page - if (variables.query.type === LibraryItem.ALBUM_ARTIST && variables.query.id.length === 1) { - const queryKey = queryKeys.albumArtists.detail(serverId, { - id: variables.query.id[0], - }); + // We only need to set if we're already on the album detail page + if ( + variables.query.type === LibraryItem.ALBUM_ARTIST && + variables.query.id.length === 1 + ) { + const queryKey = queryKeys.albumArtists.detail(serverId, { + id: variables.query.id[0], + }); - const previous = queryClient.getQueryData<AlbumArtistDetailResponse>(queryKey); + const previous = queryClient.getQueryData<AlbumArtistDetailResponse>(queryKey); - if (previous) { - queryClient.setQueryData<AlbumArtistDetailResponse>(queryKey, { - ...previous, - userFavorite: true, - }); - } - } - }, - ...options, - }); + if (previous) { + queryClient.setQueryData<AlbumArtistDetailResponse>(queryKey, { + ...previous, + userFavorite: true, + }); + } + } + }, + ...options, + }); }; diff --git a/src/renderer/features/shared/mutations/delete-favorite-mutation.ts b/src/renderer/features/shared/mutations/delete-favorite-mutation.ts index f4874e0d..5f44fa1d 100644 --- a/src/renderer/features/shared/mutations/delete-favorite-mutation.ts +++ b/src/renderer/features/shared/mutations/delete-favorite-mutation.ts @@ -3,76 +3,79 @@ import { AxiosError } from 'axios'; import { api } from '/@/renderer/api'; import { queryKeys } from '/@/renderer/api/query-keys'; import { - AlbumArtistDetailResponse, - AlbumDetailResponse, - FavoriteArgs, - FavoriteResponse, - LibraryItem, + AlbumArtistDetailResponse, + AlbumDetailResponse, + FavoriteArgs, + FavoriteResponse, + LibraryItem, } from '/@/renderer/api/types'; import { MutationHookArgs } from '/@/renderer/lib/react-query'; import { getServerById, useSetAlbumListItemDataById, useSetQueueFavorite } from '/@/renderer/store'; export const useDeleteFavorite = (args: MutationHookArgs) => { - const { options } = args || {}; - const queryClient = useQueryClient(); - const setAlbumListData = useSetAlbumListItemDataById(); - const setQueueFavorite = useSetQueueFavorite(); + const { options } = args || {}; + const queryClient = useQueryClient(); + const setAlbumListData = useSetAlbumListItemDataById(); + const setQueueFavorite = useSetQueueFavorite(); - return useMutation< - FavoriteResponse, - AxiosError, - Omit<FavoriteArgs, 'server' | 'apiClientProps'>, - null - >({ - mutationFn: (args) => { - const server = getServerById(args.serverId); - if (!server) throw new Error('Server not found'); - return api.controller.deleteFavorite({ ...args, apiClientProps: { server } }); - }, - onSuccess: (_data, variables) => { - const { serverId } = variables; + return useMutation< + FavoriteResponse, + AxiosError, + Omit<FavoriteArgs, 'server' | 'apiClientProps'>, + null + >({ + mutationFn: (args) => { + const server = getServerById(args.serverId); + if (!server) throw new Error('Server not found'); + return api.controller.deleteFavorite({ ...args, apiClientProps: { server } }); + }, + onSuccess: (_data, variables) => { + const { serverId } = variables; - if (!serverId) return; + if (!serverId) return; - for (const id of variables.query.id) { - // Set the userFavorite property to false for the album in the album list data store - if (variables.query.type === LibraryItem.ALBUM) { - setAlbumListData(id, { userFavorite: false }); - } - } + for (const id of variables.query.id) { + // Set the userFavorite property to false for the album in the album list data store + if (variables.query.type === LibraryItem.ALBUM) { + setAlbumListData(id, { userFavorite: false }); + } + } - if (variables.query.type === LibraryItem.SONG) { - setQueueFavorite(variables.query.id, false); - } + if (variables.query.type === LibraryItem.SONG) { + setQueueFavorite(variables.query.id, false); + } - // We only need to set if we're already on the album detail page - if (variables.query.type === LibraryItem.ALBUM && variables.query.id.length === 1) { - const queryKey = queryKeys.albums.detail(serverId, { id: variables.query.id[0] }); - const previous = queryClient.getQueryData<AlbumDetailResponse>(queryKey); + // We only need to set if we're already on the album detail page + if (variables.query.type === LibraryItem.ALBUM && variables.query.id.length === 1) { + const queryKey = queryKeys.albums.detail(serverId, { id: variables.query.id[0] }); + const previous = queryClient.getQueryData<AlbumDetailResponse>(queryKey); - if (previous) { - queryClient.setQueryData<AlbumDetailResponse>(queryKey, { - ...previous, - userFavorite: false, - }); - } - } + if (previous) { + queryClient.setQueryData<AlbumDetailResponse>(queryKey, { + ...previous, + userFavorite: false, + }); + } + } - // We only need to set if we're already on the album artist detail page - if (variables.query.type === LibraryItem.ALBUM_ARTIST && variables.query.id.length === 1) { - const queryKey = queryKeys.albumArtists.detail(serverId, { - id: variables.query.id[0], - }); - const previous = queryClient.getQueryData<AlbumArtistDetailResponse>(queryKey); + // We only need to set if we're already on the album artist detail page + if ( + variables.query.type === LibraryItem.ALBUM_ARTIST && + variables.query.id.length === 1 + ) { + const queryKey = queryKeys.albumArtists.detail(serverId, { + id: variables.query.id[0], + }); + const previous = queryClient.getQueryData<AlbumArtistDetailResponse>(queryKey); - if (previous) { - queryClient.setQueryData<AlbumArtistDetailResponse>(queryKey, { - ...previous, - userFavorite: false, - }); - } - } - }, - ...options, - }); + if (previous) { + queryClient.setQueryData<AlbumArtistDetailResponse>(queryKey, { + ...previous, + userFavorite: false, + }); + } + } + }, + ...options, + }); }; diff --git a/src/renderer/features/shared/mutations/set-rating-mutation.ts b/src/renderer/features/shared/mutations/set-rating-mutation.ts index bf7b8f99..c83d494c 100644 --- a/src/renderer/features/shared/mutations/set-rating-mutation.ts +++ b/src/renderer/features/shared/mutations/set-rating-mutation.ts @@ -3,99 +3,100 @@ import { AxiosError } from 'axios'; import { api } from '/@/renderer/api'; import { queryKeys } from '/@/renderer/api/query-keys'; import { - Album, - AlbumArtist, - AnyLibraryItems, - LibraryItem, - SetRatingArgs, - RatingResponse, - AlbumDetailResponse, - AlbumArtistDetailResponse, + Album, + AlbumArtist, + AnyLibraryItems, + LibraryItem, + SetRatingArgs, + RatingResponse, + AlbumDetailResponse, + AlbumArtistDetailResponse, } from '/@/renderer/api/types'; import { MutationHookArgs } from '/@/renderer/lib/react-query'; import { getServerById, useSetAlbumListItemDataById, useSetQueueRating } from '/@/renderer/store'; export const useSetRating = (args: MutationHookArgs) => { - const { options } = args || {}; - const queryClient = useQueryClient(); - const setAlbumListData = useSetAlbumListItemDataById(); - const setQueueRating = useSetQueueRating(); + const { options } = args || {}; + const queryClient = useQueryClient(); + const setAlbumListData = useSetAlbumListItemDataById(); + const setQueueRating = useSetQueueRating(); - return useMutation< - RatingResponse, - AxiosError, - Omit<SetRatingArgs, 'server' | 'apiClientProps'>, - { previous: { items: AnyLibraryItems } | undefined } - >({ - mutationFn: (args) => { - const server = getServerById(args.serverId); - if (!server) throw new Error('Server not found'); - return api.controller.updateRating({ ...args, apiClientProps: { server } }); - }, - onError: (_error, _variables, context) => { - for (const item of context?.previous?.items || []) { - switch (item.itemType) { - case LibraryItem.ALBUM: - setAlbumListData(item.id, { userRating: item.userRating }); - break; - case LibraryItem.SONG: - setQueueRating([item.id], item.userRating); - break; - } - } - }, - onMutate: (variables) => { - for (const item of variables.query.item) { - switch (item.itemType) { - case LibraryItem.ALBUM: - setAlbumListData(item.id, { userRating: variables.query.rating }); - break; - case LibraryItem.SONG: - setQueueRating([item.id], variables.query.rating); - break; - } - } + return useMutation< + RatingResponse, + AxiosError, + Omit<SetRatingArgs, 'server' | 'apiClientProps'>, + { previous: { items: AnyLibraryItems } | undefined } + >({ + mutationFn: (args) => { + const server = getServerById(args.serverId); + if (!server) throw new Error('Server not found'); + return api.controller.updateRating({ ...args, apiClientProps: { server } }); + }, + onError: (_error, _variables, context) => { + for (const item of context?.previous?.items || []) { + switch (item.itemType) { + case LibraryItem.ALBUM: + setAlbumListData(item.id, { userRating: item.userRating }); + break; + case LibraryItem.SONG: + setQueueRating([item.id], item.userRating); + break; + } + } + }, + onMutate: (variables) => { + for (const item of variables.query.item) { + switch (item.itemType) { + case LibraryItem.ALBUM: + setAlbumListData(item.id, { userRating: variables.query.rating }); + break; + case LibraryItem.SONG: + setQueueRating([item.id], variables.query.rating); + break; + } + } - return { previous: { items: variables.query.item } }; - }, - onSuccess: (_data, variables) => { - // We only need to set if we're already on the album detail page - const isAlbumDetailPage = - variables.query.item.length === 1 && variables.query.item[0].itemType === LibraryItem.ALBUM; + return { previous: { items: variables.query.item } }; + }, + onSuccess: (_data, variables) => { + // We only need to set if we're already on the album detail page + const isAlbumDetailPage = + variables.query.item.length === 1 && + variables.query.item[0].itemType === LibraryItem.ALBUM; - if (isAlbumDetailPage) { - const { id: albumId, serverId } = variables.query.item[0] as Album; + if (isAlbumDetailPage) { + const { id: albumId, serverId } = variables.query.item[0] as Album; - const queryKey = queryKeys.albums.detail(serverId || '', { id: albumId }); - const previous = queryClient.getQueryData<AlbumDetailResponse>(queryKey); - if (previous) { - queryClient.setQueryData<AlbumDetailResponse>(queryKey, { - ...previous, - userRating: variables.query.rating, - }); - } - } + const queryKey = queryKeys.albums.detail(serverId || '', { id: albumId }); + const previous = queryClient.getQueryData<AlbumDetailResponse>(queryKey); + if (previous) { + queryClient.setQueryData<AlbumDetailResponse>(queryKey, { + ...previous, + userRating: variables.query.rating, + }); + } + } - // We only need to set if we're already on the album artist detail page - const isAlbumArtistDetailPage = - variables.query.item.length === 1 && - variables.query.item[0].itemType === LibraryItem.ALBUM_ARTIST; + // We only need to set if we're already on the album artist detail page + const isAlbumArtistDetailPage = + variables.query.item.length === 1 && + variables.query.item[0].itemType === LibraryItem.ALBUM_ARTIST; - if (isAlbumArtistDetailPage) { - const { id: albumArtistId, serverId } = variables.query.item[0] as AlbumArtist; + if (isAlbumArtistDetailPage) { + const { id: albumArtistId, serverId } = variables.query.item[0] as AlbumArtist; - const queryKey = queryKeys.albumArtists.detail(serverId || '', { - id: albumArtistId, - }); - const previous = queryClient.getQueryData<AlbumArtistDetailResponse>(queryKey); - if (previous) { - queryClient.setQueryData<AlbumArtistDetailResponse>(queryKey, { - ...previous, - userRating: variables.query.rating, - }); - } - } - }, - ...options, - }); + const queryKey = queryKeys.albumArtists.detail(serverId || '', { + id: albumArtistId, + }); + const previous = queryClient.getQueryData<AlbumArtistDetailResponse>(queryKey); + if (previous) { + queryClient.setQueryData<AlbumArtistDetailResponse>(queryKey, { + ...previous, + userRating: variables.query.rating, + }); + } + } + }, + ...options, + }); }; diff --git a/src/renderer/features/shared/queries/music-folders-query.ts b/src/renderer/features/shared/queries/music-folders-query.ts index dff73a0e..97042a42 100644 --- a/src/renderer/features/shared/queries/music-folders-query.ts +++ b/src/renderer/features/shared/queries/music-folders-query.ts @@ -6,18 +6,18 @@ import { MusicFolderListQuery } from '../../../api/types'; import { QueryHookArgs } from '../../../lib/react-query'; export const useMusicFolders = (args: QueryHookArgs<MusicFolderListQuery>) => { - const { options, serverId } = args || {}; - const server = getServerById(serverId); + const { options, serverId } = args || {}; + const server = getServerById(serverId); - const query = useQuery({ - enabled: !!server, - queryFn: ({ signal }) => { - if (!server) throw new Error('Server not found'); - return api.controller.getMusicFolderList({ apiClientProps: { server, signal } }); - }, - queryKey: queryKeys.musicFolders.list(server?.id || ''), - ...options, - }); + const query = useQuery({ + enabled: !!server, + queryFn: ({ signal }) => { + if (!server) throw new Error('Server not found'); + return api.controller.getMusicFolderList({ apiClientProps: { server, signal } }); + }, + queryKey: queryKeys.musicFolders.list(server?.id || ''), + ...options, + }); - return query; + return query; }; diff --git a/src/renderer/features/shared/utils.ts b/src/renderer/features/shared/utils.ts index 0240eef8..5240ce00 100644 --- a/src/renderer/features/shared/utils.ts +++ b/src/renderer/features/shared/utils.ts @@ -1,16 +1,16 @@ import { Play } from '/@/renderer/types'; export const PLAY_TYPES = [ - { - label: 'Play', - play: Play.NOW, - }, - { - label: 'Add to queue', - play: Play.LAST, - }, - { - label: 'Add to queue next', - play: Play.NEXT, - }, + { + label: 'Play', + play: Play.NOW, + }, + { + label: 'Add to queue', + play: Play.LAST, + }, + { + label: 'Add to queue next', + play: Play.NEXT, + }, ]; diff --git a/src/renderer/features/sidebar/components/action-bar.tsx b/src/renderer/features/sidebar/components/action-bar.tsx index 519d0312..c3d3bebb 100644 --- a/src/renderer/features/sidebar/components/action-bar.tsx +++ b/src/renderer/features/sidebar/components/action-bar.tsx @@ -8,130 +8,130 @@ import { useContainerQuery } from '/@/renderer/hooks'; import { useCommandPalette } from '/@/renderer/store'; const ActionsContainer = styled.div` - display: flex; - align-items: center; - height: 70px; - -webkit-app-region: drag; + display: flex; + align-items: center; + height: 70px; + -webkit-app-region: drag; - input { - -webkit-app-region: no-drag; - } + input { + -webkit-app-region: no-drag; + } `; export const ActionBar = () => { - const cq = useContainerQuery({ md: 300 }); - const navigate = useNavigate(); - const { open } = useCommandPalette(); + const cq = useContainerQuery({ md: 300 }); + const navigate = useNavigate(); + const { open } = useCommandPalette(); - return ( - <ActionsContainer ref={cq.ref}> - {cq.isMd ? ( - <Grid - display="flex" - gutter="sm" - px="1rem" - w="100%" - > - <Grid.Col span={6}> - <TextInput - readOnly - icon={<RiSearchLine />} - placeholder="Search" - size="md" - onClick={open} - onKeyDown={(e) => { - if (e.key === 'Enter' || e.key === ' ') { - open(); - } - }} - /> - </Grid.Col> - <Grid.Col span={6}> - <Group - grow - noWrap - spacing="sm" - > - <DropdownMenu position="bottom-start"> - <DropdownMenu.Target> - <Button - p="0.5rem" - size="md" - variant="default" - > - <RiMenuFill size="1rem" /> - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - <AppMenu /> - </DropdownMenu.Dropdown> - </DropdownMenu> - <Button - p="0.5rem" - size="md" - variant="default" - onClick={() => navigate(-1)} - > - <RiArrowLeftSLine size="1.5rem" /> - </Button> - <Button - p="0.5rem" - size="md" - variant="default" - onClick={() => navigate(1)} - > - <RiArrowRightSLine size="1.5rem" /> - </Button> - </Group> - </Grid.Col> - </Grid> - ) : ( - <Group - grow - px="1rem" - spacing="sm" - w="100%" - > - <Button - p="0.5rem" - size="md" - variant="default" - onClick={open} - > - <RiSearchLine size="1rem" /> - </Button> - <DropdownMenu position="bottom-start"> - <DropdownMenu.Target> - <Button - p="0.5rem" - size="md" - variant="default" - > - <RiMenuFill size="1rem" /> - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - <AppMenu /> - </DropdownMenu.Dropdown> - </DropdownMenu> - <Button - p="0.5rem" - size="md" - variant="default" - onClick={() => navigate(-1)} - > - <RiArrowLeftSLine size="1.5rem" /> - </Button> - <Button - p="0.5rem" - size="md" - variant="default" - onClick={() => navigate(1)} - > - <RiArrowRightSLine size="1.5rem" /> - </Button> - </Group> - )} - </ActionsContainer> - ); + return ( + <ActionsContainer ref={cq.ref}> + {cq.isMd ? ( + <Grid + display="flex" + gutter="sm" + px="1rem" + w="100%" + > + <Grid.Col span={6}> + <TextInput + readOnly + icon={<RiSearchLine />} + placeholder="Search" + size="md" + onClick={open} + onKeyDown={(e) => { + if (e.key === 'Enter' || e.key === ' ') { + open(); + } + }} + /> + </Grid.Col> + <Grid.Col span={6}> + <Group + grow + noWrap + spacing="sm" + > + <DropdownMenu position="bottom-start"> + <DropdownMenu.Target> + <Button + p="0.5rem" + size="md" + variant="default" + > + <RiMenuFill size="1rem" /> + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + <AppMenu /> + </DropdownMenu.Dropdown> + </DropdownMenu> + <Button + p="0.5rem" + size="md" + variant="default" + onClick={() => navigate(-1)} + > + <RiArrowLeftSLine size="1.5rem" /> + </Button> + <Button + p="0.5rem" + size="md" + variant="default" + onClick={() => navigate(1)} + > + <RiArrowRightSLine size="1.5rem" /> + </Button> + </Group> + </Grid.Col> + </Grid> + ) : ( + <Group + grow + px="1rem" + spacing="sm" + w="100%" + > + <Button + p="0.5rem" + size="md" + variant="default" + onClick={open} + > + <RiSearchLine size="1rem" /> + </Button> + <DropdownMenu position="bottom-start"> + <DropdownMenu.Target> + <Button + p="0.5rem" + size="md" + variant="default" + > + <RiMenuFill size="1rem" /> + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + <AppMenu /> + </DropdownMenu.Dropdown> + </DropdownMenu> + <Button + p="0.5rem" + size="md" + variant="default" + onClick={() => navigate(-1)} + > + <RiArrowLeftSLine size="1.5rem" /> + </Button> + <Button + p="0.5rem" + size="md" + variant="default" + onClick={() => navigate(1)} + > + <RiArrowRightSLine size="1.5rem" /> + </Button> + </Group> + )} + </ActionsContainer> + ); }; diff --git a/src/renderer/features/sidebar/components/collapsed-sidebar-item.tsx b/src/renderer/features/sidebar/components/collapsed-sidebar-item.tsx index 4f2b9995..32232087 100644 --- a/src/renderer/features/sidebar/components/collapsed-sidebar-item.tsx +++ b/src/renderer/features/sidebar/components/collapsed-sidebar-item.tsx @@ -6,27 +6,27 @@ import styled from 'styled-components'; import { Text } from '/@/renderer/components'; const Container = styled(Flex)<{ $active?: boolean; $disabled?: boolean }>` - position: relative; - width: 100%; - padding: 0.9rem 0.3rem; - border-right: var(--sidebar-border); - cursor: ${(props) => (props.$disabled ? 'default' : 'pointer')}; - opacity: ${(props) => props.$disabled && 0.6}; - user-select: ${(props) => (props.$disabled ? 'none' : 'initial')}; - pointer-events: ${(props) => (props.$disabled ? 'none' : 'all')}; + position: relative; + width: 100%; + padding: 0.9rem 0.3rem; + border-right: var(--sidebar-border); + cursor: ${(props) => (props.$disabled ? 'default' : 'pointer')}; + opacity: ${(props) => props.$disabled && 0.6}; + user-select: ${(props) => (props.$disabled ? 'none' : 'initial')}; + pointer-events: ${(props) => (props.$disabled ? 'none' : 'all')}; - svg { - fill: ${(props) => (props.$active ? 'var(--primary-color)' : 'var(--sidebar-fg)')}; - } + svg { + fill: ${(props) => (props.$active ? 'var(--primary-color)' : 'var(--sidebar-fg)')}; + } - &:focus-visible { - background-color: var(--sidebar-bg-hover); - outline: none; - } + &:focus-visible { + background-color: var(--sidebar-bg-hover); + outline: none; + } - ${(props) => - !props.$disabled && - ` + ${(props) => + !props.$disabled && + ` &:hover { background-color: var(--sidebar-bg-hover); @@ -42,65 +42,65 @@ const Container = styled(Flex)<{ $active?: boolean; $disabled?: boolean }>` `; const TextWrapper = styled.div` - width: 100%; - overflow: hidden; - white-space: nowrap; - text-align: center; - text-overflow: ellipsis; + width: 100%; + overflow: hidden; + white-space: nowrap; + text-align: center; + text-overflow: ellipsis; `; const ActiveTabIndicator = styled(motion.div)` - position: absolute; - top: 0; - right: 0; - bottom: 0; - left: 3px; - width: 2px; - height: 80%; - margin-top: auto; - margin-bottom: auto; - background: var(--primary-color); + position: absolute; + top: 0; + right: 0; + bottom: 0; + left: 3px; + width: 2px; + height: 80%; + margin-top: auto; + margin-bottom: auto; + background: var(--primary-color); `; interface CollapsedSidebarItemProps { - activeIcon: React.ReactNode; - disabled?: boolean; - icon: React.ReactNode; - label: string; - route?: string; + activeIcon: React.ReactNode; + disabled?: boolean; + icon: React.ReactNode; + label: string; + route?: string; } const _CollapsedSidebarItem = forwardRef<HTMLDivElement, CollapsedSidebarItemProps>( - ({ route, activeIcon, icon, label, disabled, ...props }: CollapsedSidebarItemProps, ref) => { - const match = useMatch(route || '/null'); - const isMatch = Boolean(match); + ({ route, activeIcon, icon, label, disabled, ...props }: CollapsedSidebarItemProps, ref) => { + const match = useMatch(route || '/null'); + const isMatch = Boolean(match); - return ( - <Container - ref={ref} - $active={Boolean(match)} - $disabled={disabled} - align="center" - direction="column" - {...props} - > - {isMatch ? <ActiveTabIndicator /> : null} - {isMatch ? activeIcon : icon} - <TextWrapper> - <Text - $secondary={!isMatch} - fw="600" - overflow="hidden" - size="xs" - > - {label} - </Text> - </TextWrapper> - </Container> - ); - }, + return ( + <Container + ref={ref} + $active={Boolean(match)} + $disabled={disabled} + align="center" + direction="column" + {...props} + > + {isMatch ? <ActiveTabIndicator /> : null} + {isMatch ? activeIcon : icon} + <TextWrapper> + <Text + $secondary={!isMatch} + fw="600" + overflow="hidden" + size="xs" + > + {label} + </Text> + </TextWrapper> + </Container> + ); + }, ); export const CollapsedSidebarItem = createPolymorphicComponent<'button', CollapsedSidebarItemProps>( - _CollapsedSidebarItem, + _CollapsedSidebarItem, ); diff --git a/src/renderer/features/sidebar/components/collapsed-sidebar.tsx b/src/renderer/features/sidebar/components/collapsed-sidebar.tsx index 54b661e5..653f510d 100644 --- a/src/renderer/features/sidebar/components/collapsed-sidebar.tsx +++ b/src/renderer/features/sidebar/components/collapsed-sidebar.tsx @@ -3,27 +3,27 @@ import { motion } from 'framer-motion'; import { useMemo } from 'react'; import { IconType } from 'react-icons'; import { - RiUserVoiceLine, - RiMenuFill, - RiFolder3Line, - RiPlayListLine, - RiAlbumLine, - RiHome6Line, - RiMusic2Line, - RiHome6Fill, - RiAlbumFill, - RiMusic2Fill, - RiUserVoiceFill, - RiFlag2Fill, - RiFolder3Fill, - RiPlayListFill, - RiSearchLine, - RiSearchFill, - RiPlayFill, - RiPlayLine, - RiSettings2Fill, - RiSettings2Line, - RiFlag2Line, + RiUserVoiceLine, + RiMenuFill, + RiFolder3Line, + RiPlayListLine, + RiAlbumLine, + RiHome6Line, + RiMusic2Line, + RiHome6Fill, + RiAlbumFill, + RiMusic2Fill, + RiUserVoiceFill, + RiFlag2Fill, + RiFolder3Fill, + RiPlayListFill, + RiSearchLine, + RiSearchFill, + RiPlayFill, + RiPlayLine, + RiSettings2Fill, + RiSettings2Line, + RiFlag2Line, } from 'react-icons/ri'; import { generatePath, NavLink } from 'react-router-dom'; import styled from 'styled-components'; @@ -36,110 +36,110 @@ import { SidebarItemType, useGeneralSettings, useWindowSettings } from '/@/rende import { Platform } from '/@/renderer/types'; const SidebarContainer = styled(motion.div)<{ windowBarStyle: Platform }>` - display: flex; - flex-direction: column; - height: 100%; - max-height: ${(props) => - props.windowBarStyle === Platform.WEB || props.windowBarStyle === Platform.LINUX - ? 'calc(100vh - 149px)' - : 'calc(100vh - 119px)'}; // Playerbar (90px), titlebar (65px), windowbar (30px) - user-select: none; + display: flex; + flex-direction: column; + height: 100%; + max-height: ${(props) => + props.windowBarStyle === Platform.WEB || props.windowBarStyle === Platform.LINUX + ? 'calc(100vh - 149px)' + : 'calc(100vh - 119px)'}; // Playerbar (90px), titlebar (65px), windowbar (30px) + user-select: none; `; const sidebarItemMap = { - [AppRoute.HOME]: { - activeIcon: RiHome6Fill, - icon: RiHome6Line, - }, - [AppRoute.LIBRARY_ALBUMS]: { - activeIcon: RiAlbumFill, - icon: RiAlbumLine, - }, - [AppRoute.LIBRARY_ALBUM_ARTISTS]: { - activeIcon: RiUserVoiceFill, - icon: RiUserVoiceLine, - }, - [AppRoute.PLAYLISTS]: { - activeIcon: RiPlayListFill, - icon: RiPlayListLine, - }, - [AppRoute.LIBRARY_SONGS]: { - activeIcon: RiMusic2Fill, - icon: RiMusic2Line, - }, - [AppRoute.LIBRARY_FOLDERS]: { - activeIcon: RiFolder3Fill, - icon: RiFolder3Line, - }, - [AppRoute.LIBRARY_GENRES]: { - activeIcon: RiFlag2Fill, - icon: RiFlag2Line, - }, - [generatePath(AppRoute.SEARCH, { itemType: LibraryItem.SONG })]: { - activeIcon: RiSearchFill, - icon: RiSearchLine, - }, - [AppRoute.SETTINGS]: { - activeIcon: RiSettings2Fill, - icon: RiSettings2Line, - }, - [AppRoute.NOW_PLAYING]: { - activeIcon: RiPlayFill, - icon: RiPlayLine, - }, + [AppRoute.HOME]: { + activeIcon: RiHome6Fill, + icon: RiHome6Line, + }, + [AppRoute.LIBRARY_ALBUMS]: { + activeIcon: RiAlbumFill, + icon: RiAlbumLine, + }, + [AppRoute.LIBRARY_ALBUM_ARTISTS]: { + activeIcon: RiUserVoiceFill, + icon: RiUserVoiceLine, + }, + [AppRoute.PLAYLISTS]: { + activeIcon: RiPlayListFill, + icon: RiPlayListLine, + }, + [AppRoute.LIBRARY_SONGS]: { + activeIcon: RiMusic2Fill, + icon: RiMusic2Line, + }, + [AppRoute.LIBRARY_FOLDERS]: { + activeIcon: RiFolder3Fill, + icon: RiFolder3Line, + }, + [AppRoute.LIBRARY_GENRES]: { + activeIcon: RiFlag2Fill, + icon: RiFlag2Line, + }, + [generatePath(AppRoute.SEARCH, { itemType: LibraryItem.SONG })]: { + activeIcon: RiSearchFill, + icon: RiSearchLine, + }, + [AppRoute.SETTINGS]: { + activeIcon: RiSettings2Fill, + icon: RiSettings2Line, + }, + [AppRoute.NOW_PLAYING]: { + activeIcon: RiPlayFill, + icon: RiPlayLine, + }, }; export const CollapsedSidebar = () => { - const { windowBarStyle } = useWindowSettings(); - const { sidebarItems } = useGeneralSettings(); + const { windowBarStyle } = useWindowSettings(); + const { sidebarItems } = useGeneralSettings(); - const sidebarItemsWithRoute: (SidebarItemType & { - activeIcon: IconType; - icon: IconType; - })[] = useMemo(() => { - if (!sidebarItems) return []; + const sidebarItemsWithRoute: (SidebarItemType & { + activeIcon: IconType; + icon: IconType; + })[] = useMemo(() => { + if (!sidebarItems) return []; - const items = sidebarItems - .filter((item) => !item.disabled) - .map((item) => ({ - ...item, - ...sidebarItemMap[item.route as keyof typeof sidebarItemMap], - })); + const items = sidebarItems + .filter((item) => !item.disabled) + .map((item) => ({ + ...item, + ...sidebarItemMap[item.route as keyof typeof sidebarItemMap], + })); - return items; - }, [sidebarItems]); + return items; + }, [sidebarItems]); - return ( - <SidebarContainer windowBarStyle={windowBarStyle}> - <ScrollArea - scrollHideDelay={0} - scrollbarSize={8} - > - <DropdownMenu position="right-start"> - <DropdownMenu.Target> - <CollapsedSidebarItem - activeIcon={<RiMenuFill size="25" />} - component={UnstyledButton} - icon={<RiMenuFill size="25" />} - label="Menu" - /> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - <AppMenu /> - </DropdownMenu.Dropdown> - </DropdownMenu> - {sidebarItemsWithRoute.map((item) => ( - <CollapsedSidebarItem - key={item.id} - activeIcon={<item.activeIcon size="25" />} - component={NavLink} - icon={<item.icon size="25" />} - label={item.label} - route={item.route} - to={item.route} - /> - ))} - </ScrollArea> - </SidebarContainer> - ); + return ( + <SidebarContainer windowBarStyle={windowBarStyle}> + <ScrollArea + scrollHideDelay={0} + scrollbarSize={8} + > + <DropdownMenu position="right-start"> + <DropdownMenu.Target> + <CollapsedSidebarItem + activeIcon={<RiMenuFill size="25" />} + component={UnstyledButton} + icon={<RiMenuFill size="25" />} + label="Menu" + /> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + <AppMenu /> + </DropdownMenu.Dropdown> + </DropdownMenu> + {sidebarItemsWithRoute.map((item) => ( + <CollapsedSidebarItem + key={item.id} + activeIcon={<item.activeIcon size="25" />} + component={NavLink} + icon={<item.icon size="25" />} + label={item.label} + route={item.route} + to={item.route} + /> + ))} + </ScrollArea> + </SidebarContainer> + ); }; diff --git a/src/renderer/features/sidebar/components/sidebar-item.tsx b/src/renderer/features/sidebar/components/sidebar-item.tsx index c1686434..dff53ac8 100644 --- a/src/renderer/features/sidebar/components/sidebar-item.tsx +++ b/src/renderer/features/sidebar/components/sidebar-item.tsx @@ -5,73 +5,73 @@ import { Link } from 'react-router-dom'; import styled, { css } from 'styled-components'; interface ListItemProps extends FlexProps { - children: ReactNode; - disabled?: boolean; - to?: string; + children: ReactNode; + disabled?: boolean; + to?: string; } const StyledItem = styled(Flex)` - width: 100%; - font-weight: 600; - font-size: 1.1rem; - font-family: var(--content-font-family); + width: 100%; + font-weight: 600; + font-size: 1.1rem; + font-family: var(--content-font-family); - &:focus-visible { - border: 1px solid var(--primary-color); - } + &:focus-visible { + border: 1px solid var(--primary-color); + } `; const ItemStyle = css` - display: flex; - width: 100%; - padding: 0.5rem 1rem; - color: var(--sidebar-fg); - border: 1px transparent solid; - transition: color 0.2s ease-in-out; + display: flex; + width: 100%; + padding: 0.5rem 1rem; + color: var(--sidebar-fg); + border: 1px transparent solid; + transition: color 0.2s ease-in-out; - &:hover { - color: var(--sidebar-fg-hover); - } + &:hover { + color: var(--sidebar-fg-hover); + } `; const _ItemLink = styled(StyledItem)<LinkProps & { disabled?: boolean }>` - opacity: ${(props) => props.disabled && 0.6}; - pointer-events: ${(props) => props.disabled && 'none'}; + opacity: ${(props) => props.disabled && 0.6}; + pointer-events: ${(props) => props.disabled && 'none'}; - &:focus-visible { - border: 1px solid var(--primary-color); - } + &:focus-visible { + border: 1px solid var(--primary-color); + } - ${ItemStyle} + ${ItemStyle} `; const ItemLink = createPolymorphicComponent<'a', ListItemProps>(_ItemLink); export const SidebarItem = ({ to, children, ...props }: ListItemProps) => { - if (to) { + if (to) { + return ( + <ItemLink + component={Link} + to={to} + {...props} + > + {children} + </ItemLink> + ); + } return ( - <ItemLink - component={Link} - to={to} - {...props} - > - {children} - </ItemLink> + <StyledItem + tabIndex={0} + {...props} + > + {children} + </StyledItem> ); - } - return ( - <StyledItem - tabIndex={0} - {...props} - > - {children} - </StyledItem> - ); }; SidebarItem.Link = ItemLink; SidebarItem.defaultProps = { - disabled: false, - to: undefined, + disabled: false, + to: undefined, }; diff --git a/src/renderer/features/sidebar/components/sidebar-playlist-list.tsx b/src/renderer/features/sidebar/components/sidebar-playlist-list.tsx index b527b3ed..f554b4be 100644 --- a/src/renderer/features/sidebar/components/sidebar-playlist-list.tsx +++ b/src/renderer/features/sidebar/components/sidebar-playlist-list.tsx @@ -15,149 +15,153 @@ import { FixedSizeList, ListChildComponentProps } from 'react-window'; import { useHideScrollbar } from '/@/renderer/hooks'; interface SidebarPlaylistListProps { - data: ReturnType<typeof usePlaylistList>['data']; + data: ReturnType<typeof usePlaylistList>['data']; } const PlaylistRow = ({ index, data, style }: ListChildComponentProps) => { - return ( - <div style={{ margin: '0.5rem 0', padding: '0 1.5rem', ...style }}> - <Group - noWrap - className="sidebar-playlist-item" - pos="relative" - position="apart" - sx={{ - '&:hover': { - '.sidebar-playlist-controls': { - display: 'flex', - }, - '.sidebar-playlist-name': { - color: 'var(--sidebar-fg-hover) !important', - }, - }, - }} - > - <Text - className="sidebar-playlist-name" - component={Link} - overflow="hidden" - size="md" - sx={{ - color: 'var(--sidebar-fg) !important', - cursor: 'default', - width: '100%', - }} - to={ - data?.items[index].id - ? generatePath(AppRoute.PLAYLISTS_DETAIL, { - playlistId: data?.items[index].id, - }) - : undefined - } - > - {data?.items[index].name} - </Text> - <Group - noWrap - className="sidebar-playlist-controls" - display="none" - pos="absolute" - right="0" - spacing="sm" - > - <Button - compact - size="md" - tooltip={{ label: 'Play', openDelay: 500 }} - variant="default" - onClick={() => { - if (!data?.items?.[index].id) return; - data.handlePlay(data?.items[index].id, Play.NOW); - }} - > - <RiPlayFill /> - </Button> - <Button - compact - size="md" - tooltip={{ label: 'Add to queue', openDelay: 500 }} - variant="default" - onClick={() => { - if (!data?.items?.[index].id) return; - data.handlePlay(data?.items[index].id, Play.LAST); - }} - > - <RiAddBoxFill /> - </Button> - <Button - compact - size="md" - tooltip={{ label: 'Add to queue next', openDelay: 500 }} - variant="default" - onClick={() => { - if (!data?.items?.[index].id) return; - data.handlePlay(data?.items[index].id, Play.NEXT); - }} - > - <RiAddCircleFill /> - </Button> - </Group> - </Group> - </div> - ); + return ( + <div style={{ margin: '0.5rem 0', padding: '0 1.5rem', ...style }}> + <Group + noWrap + className="sidebar-playlist-item" + pos="relative" + position="apart" + sx={{ + '&:hover': { + '.sidebar-playlist-controls': { + display: 'flex', + }, + '.sidebar-playlist-name': { + color: 'var(--sidebar-fg-hover) !important', + }, + }, + }} + > + <Text + className="sidebar-playlist-name" + component={Link} + overflow="hidden" + size="md" + sx={{ + color: 'var(--sidebar-fg) !important', + cursor: 'default', + width: '100%', + }} + to={ + data?.items[index].id + ? generatePath(AppRoute.PLAYLISTS_DETAIL, { + playlistId: data?.items[index].id, + }) + : undefined + } + > + {data?.items[index].name} + </Text> + <Group + noWrap + className="sidebar-playlist-controls" + display="none" + pos="absolute" + right="0" + spacing="sm" + > + <Button + compact + size="md" + tooltip={{ label: 'Play', openDelay: 500 }} + variant="default" + onClick={() => { + if (!data?.items?.[index].id) return; + data.handlePlay(data?.items[index].id, Play.NOW); + }} + > + <RiPlayFill /> + </Button> + <Button + compact + size="md" + tooltip={{ label: 'Add to queue', openDelay: 500 }} + variant="default" + onClick={() => { + if (!data?.items?.[index].id) return; + data.handlePlay(data?.items[index].id, Play.LAST); + }} + > + <RiAddBoxFill /> + </Button> + <Button + compact + size="md" + tooltip={{ label: 'Add to queue next', openDelay: 500 }} + variant="default" + onClick={() => { + if (!data?.items?.[index].id) return; + data.handlePlay(data?.items[index].id, Play.NEXT); + }} + > + <RiAddCircleFill /> + </Button> + </Group> + </Group> + </div> + ); }; export const SidebarPlaylistList = ({ data }: SidebarPlaylistListProps) => { - const { isScrollbarHidden, hideScrollbarElementProps } = useHideScrollbar(0); - const handlePlayQueueAdd = usePlayQueueAdd(); + const { isScrollbarHidden, hideScrollbarElementProps } = useHideScrollbar(0); + const handlePlayQueueAdd = usePlayQueueAdd(); - const [rect, setRect] = useState({ - height: 0, - width: 0, - }); + const [rect, setRect] = useState({ + height: 0, + width: 0, + }); - const [debounced] = useDebouncedValue(rect, 25); + const [debounced] = useDebouncedValue(rect, 25); - const handlePlayPlaylist = useCallback( - (id: string, playType: Play) => { - handlePlayQueueAdd?.({ - byItemType: { - id: [id], - type: LibraryItem.PLAYLIST, + const handlePlayPlaylist = useCallback( + (id: string, playType: Play) => { + handlePlayQueueAdd?.({ + byItemType: { + id: [id], + type: LibraryItem.PLAYLIST, + }, + playType, + }); }, - playType, - }); - }, - [handlePlayQueueAdd], - ); + [handlePlayQueueAdd], + ); - const memoizedItemData = useMemo(() => { - return { - handlePlay: handlePlayPlaylist, - items: data?.items, - }; - }, [data?.items, handlePlayPlaylist]); + const memoizedItemData = useMemo(() => { + return { + handlePlay: handlePlayPlaylist, + items: data?.items, + }; + }, [data?.items, handlePlayPlaylist]); - return ( - <Flex - h="100%" - {...hideScrollbarElementProps} - > - <AutoSizer onResize={(e) => setRect(e as { height: number; width: number })}> - {() => ( - <FixedSizeList - className={isScrollbarHidden ? 'hide-scrollbar overlay-scrollbar' : 'overlay-scrollbar'} - height={debounced.height} - itemCount={data?.items?.length || 0} - itemData={memoizedItemData} - itemSize={25} - overscanCount={20} - width={debounced.width} - > - {PlaylistRow} - </FixedSizeList> - )} - </AutoSizer> - </Flex> - ); + return ( + <Flex + h="100%" + {...hideScrollbarElementProps} + > + <AutoSizer onResize={(e) => setRect(e as { height: number; width: number })}> + {() => ( + <FixedSizeList + className={ + isScrollbarHidden + ? 'hide-scrollbar overlay-scrollbar' + : 'overlay-scrollbar' + } + height={debounced.height} + itemCount={data?.items?.length || 0} + itemData={memoizedItemData} + itemSize={25} + overscanCount={20} + width={debounced.width} + > + {PlaylistRow} + </FixedSizeList> + )} + </AutoSizer> + </Flex> + ); }; diff --git a/src/renderer/features/sidebar/components/sidebar.tsx b/src/renderer/features/sidebar/components/sidebar.tsx index c4cf1962..d5e5cce2 100644 --- a/src/renderer/features/sidebar/components/sidebar.tsx +++ b/src/renderer/features/sidebar/components/sidebar.tsx @@ -4,37 +4,37 @@ import { closeAllModals, openModal } from '@mantine/modals'; import { AnimatePresence, motion } from 'framer-motion'; import { IconType } from 'react-icons'; import { - RiAddFill, - RiAlbumFill, - RiAlbumLine, - RiArrowDownSLine, - RiDiscLine, - RiFlag2Fill, - RiFlagLine, - RiFolder3Fill, - RiFolder3Line, - RiHome6Fill, - RiHome6Line, - RiListUnordered, - RiMusic2Fill, - RiMusic2Line, - RiPlayLine, - RiSearchFill, - RiUserVoiceFill, - RiUserVoiceLine, - RiSearchLine, - RiPlayFill, - RiSettings2Line, - RiSettings2Fill, - RiPlayListLine, - RiPlayListFill, + RiAddFill, + RiAlbumFill, + RiAlbumLine, + RiArrowDownSLine, + RiDiscLine, + RiFlag2Fill, + RiFlagLine, + RiFolder3Fill, + RiFolder3Line, + RiHome6Fill, + RiHome6Line, + RiListUnordered, + RiMusic2Fill, + RiMusic2Line, + RiPlayLine, + RiSearchFill, + RiUserVoiceFill, + RiUserVoiceLine, + RiSearchLine, + RiPlayFill, + RiSettings2Line, + RiSettings2Fill, + RiPlayListLine, + RiPlayListFill, } from 'react-icons/ri'; import { generatePath, Link, useLocation } from 'react-router-dom'; import styled from 'styled-components'; import { - SidebarItemType, - useGeneralSettings, - useWindowSettings, + SidebarItemType, + useGeneralSettings, + useWindowSettings, } from '../../../store/settings.store'; import { LibraryItem, PlaylistListSort, ServerType, SortOrder } from '/@/renderer/api/types'; import { Button, MotionStack, Spinner, Tooltip } from '/@/renderer/components'; @@ -45,289 +45,291 @@ import { SidebarPlaylistList } from '/@/renderer/features/sidebar/components/sid import { useContainerQuery } from '/@/renderer/hooks'; import { AppRoute } from '/@/renderer/router/routes'; import { - useAppStoreActions, - useCurrentServer, - useCurrentSong, - useFullScreenPlayerStore, - useSetFullScreenPlayerStore, - useSidebarStore, + useAppStoreActions, + useCurrentServer, + useCurrentSong, + useFullScreenPlayerStore, + useSetFullScreenPlayerStore, + useSidebarStore, } from '/@/renderer/store'; import { fadeIn } from '/@/renderer/styles'; import { Platform } from '/@/renderer/types'; const SidebarContainer = styled.div<{ windowBarStyle: Platform }>` - height: 100%; - max-height: ${(props) => - props.windowBarStyle === Platform.WEB || props.windowBarStyle === Platform.LINUX - ? 'calc(100vh - 149px)' - : 'calc(100vh - 179px)'}; // Playerbar (90px), titlebar (65px), windowbar (30px) - user-select: none; + height: 100%; + max-height: ${(props) => + props.windowBarStyle === Platform.WEB || props.windowBarStyle === Platform.LINUX + ? 'calc(100vh - 149px)' + : 'calc(100vh - 179px)'}; // Playerbar (90px), titlebar (65px), windowbar (30px) + user-select: none; `; const ImageContainer = styled(motion.div)<{ height: string }>` - position: relative; - height: ${(props) => props.height}; - cursor: pointer; + position: relative; + height: ${(props) => props.height}; + cursor: pointer; - ${fadeIn}; - animation: fadein 0.2s ease-in-out; + ${fadeIn}; + animation: fadein 0.2s ease-in-out; - button { - display: none; - } + button { + display: none; + } - &:hover button { - display: block; - } + &:hover button { + display: block; + } `; const SidebarImage = styled.img` - width: 100%; - height: 100%; - object-fit: cover; - background: var(--placeholder-bg); + width: 100%; + height: 100%; + object-fit: cover; + background: var(--placeholder-bg); `; const sidebarItemMap = { - [AppRoute.HOME]: { - activeIcon: RiHome6Fill, - icon: RiHome6Line, - }, - [AppRoute.LIBRARY_ALBUMS]: { - activeIcon: RiAlbumFill, - icon: RiAlbumLine, - }, - [AppRoute.LIBRARY_ALBUM_ARTISTS]: { - activeIcon: RiUserVoiceFill, - icon: RiUserVoiceLine, - }, - [AppRoute.PLAYLISTS]: { - activeIcon: RiPlayListFill, - icon: RiPlayListLine, - }, - [AppRoute.LIBRARY_SONGS]: { - activeIcon: RiMusic2Fill, - icon: RiMusic2Line, - }, - [AppRoute.LIBRARY_FOLDERS]: { - activeIcon: RiFolder3Fill, - icon: RiFolder3Line, - }, - [AppRoute.LIBRARY_GENRES]: { - activeIcon: RiFlag2Fill, - icon: RiFlagLine, - }, - [generatePath(AppRoute.SEARCH, { itemType: LibraryItem.SONG })]: { - activeIcon: RiSearchFill, - icon: RiSearchLine, - }, - [AppRoute.SETTINGS]: { - activeIcon: RiSettings2Fill, - icon: RiSettings2Line, - }, - [AppRoute.NOW_PLAYING]: { - activeIcon: RiPlayFill, - icon: RiPlayLine, - }, + [AppRoute.HOME]: { + activeIcon: RiHome6Fill, + icon: RiHome6Line, + }, + [AppRoute.LIBRARY_ALBUMS]: { + activeIcon: RiAlbumFill, + icon: RiAlbumLine, + }, + [AppRoute.LIBRARY_ALBUM_ARTISTS]: { + activeIcon: RiUserVoiceFill, + icon: RiUserVoiceLine, + }, + [AppRoute.PLAYLISTS]: { + activeIcon: RiPlayListFill, + icon: RiPlayListLine, + }, + [AppRoute.LIBRARY_SONGS]: { + activeIcon: RiMusic2Fill, + icon: RiMusic2Line, + }, + [AppRoute.LIBRARY_FOLDERS]: { + activeIcon: RiFolder3Fill, + icon: RiFolder3Line, + }, + [AppRoute.LIBRARY_GENRES]: { + activeIcon: RiFlag2Fill, + icon: RiFlagLine, + }, + [generatePath(AppRoute.SEARCH, { itemType: LibraryItem.SONG })]: { + activeIcon: RiSearchFill, + icon: RiSearchLine, + }, + [AppRoute.SETTINGS]: { + activeIcon: RiSettings2Fill, + icon: RiSettings2Line, + }, + [AppRoute.NOW_PLAYING]: { + activeIcon: RiPlayFill, + icon: RiPlayLine, + }, }; export const Sidebar = () => { - const location = useLocation(); - const sidebar = useSidebarStore(); - const { setSideBar } = useAppStoreActions(); - const { windowBarStyle } = useWindowSettings(); - const { sidebarPlaylistList } = useGeneralSettings(); - const imageUrl = useCurrentSong()?.imageUrl; - const server = useCurrentServer(); + const location = useLocation(); + const sidebar = useSidebarStore(); + const { setSideBar } = useAppStoreActions(); + const { windowBarStyle } = useWindowSettings(); + const { sidebarPlaylistList } = useGeneralSettings(); + const imageUrl = useCurrentSong()?.imageUrl; + const server = useCurrentServer(); - const upsizedImageUrl = imageUrl - ?.replace(/size=\d+/, 'size=300') - .replace(/width=\d+/, 'width=300') - .replace(/height=\d+/, 'height=300'); + const upsizedImageUrl = imageUrl + ?.replace(/size=\d+/, 'size=300') + .replace(/width=\d+/, 'width=300') + .replace(/height=\d+/, 'height=300'); - const showImage = sidebar.image; + const showImage = sidebar.image; - const handleCreatePlaylistModal = (e: MouseEvent<HTMLButtonElement>) => { - e.stopPropagation(); + const handleCreatePlaylistModal = (e: MouseEvent<HTMLButtonElement>) => { + e.stopPropagation(); - openModal({ - children: <CreatePlaylistForm onCancel={() => closeAllModals()} />, - size: server?.type === ServerType?.NAVIDROME ? 'xl' : 'sm', - title: 'Create Playlist', + openModal({ + children: <CreatePlaylistForm onCancel={() => closeAllModals()} />, + size: server?.type === ServerType?.NAVIDROME ? 'xl' : 'sm', + title: 'Create Playlist', + }); + }; + + const playlistsQuery = usePlaylistList({ + query: { + sortBy: PlaylistListSort.NAME, + sortOrder: SortOrder.ASC, + startIndex: 0, + }, + serverId: server?.id, }); - }; - const playlistsQuery = usePlaylistList({ - query: { - sortBy: PlaylistListSort.NAME, - sortOrder: SortOrder.ASC, - startIndex: 0, - }, - serverId: server?.id, - }); + const setFullScreenPlayerStore = useSetFullScreenPlayerStore(); + const { expanded: isFullScreenPlayerExpanded } = useFullScreenPlayerStore(); + const expandFullScreenPlayer = () => { + setFullScreenPlayerStore({ expanded: !isFullScreenPlayerExpanded }); + }; - const setFullScreenPlayerStore = useSetFullScreenPlayerStore(); - const { expanded: isFullScreenPlayerExpanded } = useFullScreenPlayerStore(); - const expandFullScreenPlayer = () => { - setFullScreenPlayerStore({ expanded: !isFullScreenPlayerExpanded }); - }; + const cq = useContainerQuery({ sm: 300 }); - const cq = useContainerQuery({ sm: 300 }); + const { sidebarItems } = useGeneralSettings(); - const { sidebarItems } = useGeneralSettings(); + const sidebarItemsWithRoute: (SidebarItemType & { + activeIcon: IconType; + icon: IconType; + })[] = useMemo(() => { + if (!sidebarItems) return []; - const sidebarItemsWithRoute: (SidebarItemType & { - activeIcon: IconType; - icon: IconType; - })[] = useMemo(() => { - if (!sidebarItems) return []; + const items = sidebarItems + .filter((item) => !item.disabled) + .map((item) => ({ + ...item, + ...sidebarItemMap[item.route as keyof typeof sidebarItemMap], + })); - const items = sidebarItems - .filter((item) => !item.disabled) - .map((item) => ({ - ...item, - ...sidebarItemMap[item.route as keyof typeof sidebarItemMap], - })); + return items; + }, [sidebarItems]); - return items; - }, [sidebarItems]); - - return ( - <SidebarContainer - ref={cq.ref} - windowBarStyle={windowBarStyle} - > - <ActionBar /> - <Stack - h="100%" - justify="space-between" - spacing={0} - > - <MotionStack - h="100%" - layout="position" - spacing={0} - sx={{ maxHeight: showImage ? `calc(100% - ${sidebar.leftWidth})` : '100%' }} + return ( + <SidebarContainer + ref={cq.ref} + windowBarStyle={windowBarStyle} > - <Stack spacing={0}> - {sidebarItemsWithRoute.map((item) => ( - <SidebarItem - key={`sidebar-${item.route}`} - to={item.route} - > - <Group spacing="sm"> - {location.pathname === item.route ? ( - <item.activeIcon size="1.1em" /> - ) : ( - <item.icon size="1.1em" /> - )} - {item.label} - </Group> - </SidebarItem> - ))} - </Stack> - <Divider - mx="1rem" - my="0.5rem" - /> - {sidebarPlaylistList && ( - <> - <Group - position="apart" - pt="1rem" - px="1.5rem" - > - <Group> - <Box - fw="600" - sx={{ fontSize: '1.2rem' }} - > - Playlists - </Box> - {playlistsQuery.isLoading && <Spinner />} - </Group> - <Group spacing="sm"> - <Button - compact - size="md" - tooltip={{ label: 'Create playlist', openDelay: 500 }} - variant="default" - onClick={handleCreatePlaylistModal} - > - <RiAddFill size="1em" /> - </Button> - <Button - compact - component={Link} - size="md" - to={AppRoute.PLAYLISTS} - tooltip={{ label: 'Playlist list', openDelay: 500 }} - variant="default" - onClick={(e) => e.stopPropagation()} - > - <RiListUnordered size="1em" /> - </Button> - </Group> - </Group> - <SidebarPlaylistList data={playlistsQuery.data} /> - </> - )} - </MotionStack> - <AnimatePresence - initial={false} - mode="popLayout" - > - {showImage && ( - <ImageContainer - key="sidebar-image" - animate={{ opacity: 1, y: 0 }} - exit={{ opacity: 0, y: 200 }} - height={sidebar.leftWidth} - initial={{ opacity: 0, y: 200 }} - role="button" - transition={{ duration: 0.3, ease: 'easeInOut' }} - onClick={expandFullScreenPlayer} + <ActionBar /> + <Stack + h="100%" + justify="space-between" + spacing={0} > - <Tooltip - label="Toggle fullscreen player" - openDelay={500} - > - {upsizedImageUrl ? ( - <SidebarImage - loading="eager" - src={upsizedImageUrl} - /> - ) : ( - <Center sx={{ background: 'var(--placeholder-bg)', height: '100%' }}> - <RiDiscLine - color="var(--placeholder-fg)" - size={50} + <MotionStack + h="100%" + layout="position" + spacing={0} + sx={{ maxHeight: showImage ? `calc(100% - ${sidebar.leftWidth})` : '100%' }} + > + <Stack spacing={0}> + {sidebarItemsWithRoute.map((item) => ( + <SidebarItem + key={`sidebar-${item.route}`} + to={item.route} + > + <Group spacing="sm"> + {location.pathname === item.route ? ( + <item.activeIcon size="1.1em" /> + ) : ( + <item.icon size="1.1em" /> + )} + {item.label} + </Group> + </SidebarItem> + ))} + </Stack> + <Divider + mx="1rem" + my="0.5rem" /> - </Center> - )} - </Tooltip> - <Button - compact - opacity={0.8} - radius={100} - size="md" - sx={{ cursor: 'default', position: 'absolute', right: 5, top: 5 }} - tooltip={{ label: 'Collapse', openDelay: 500 }} - variant="default" - onClick={(e) => { - e.stopPropagation(); - setSideBar({ image: false }); - }} - > - <RiArrowDownSLine - color="white" - size={20} - /> - </Button> - </ImageContainer> - )} - </AnimatePresence> - </Stack> - </SidebarContainer> - ); + {sidebarPlaylistList && ( + <> + <Group + position="apart" + pt="1rem" + px="1.5rem" + > + <Group> + <Box + fw="600" + sx={{ fontSize: '1.2rem' }} + > + Playlists + </Box> + {playlistsQuery.isLoading && <Spinner />} + </Group> + <Group spacing="sm"> + <Button + compact + size="md" + tooltip={{ label: 'Create playlist', openDelay: 500 }} + variant="default" + onClick={handleCreatePlaylistModal} + > + <RiAddFill size="1em" /> + </Button> + <Button + compact + component={Link} + size="md" + to={AppRoute.PLAYLISTS} + tooltip={{ label: 'Playlist list', openDelay: 500 }} + variant="default" + onClick={(e) => e.stopPropagation()} + > + <RiListUnordered size="1em" /> + </Button> + </Group> + </Group> + <SidebarPlaylistList data={playlistsQuery.data} /> + </> + )} + </MotionStack> + <AnimatePresence + initial={false} + mode="popLayout" + > + {showImage && ( + <ImageContainer + key="sidebar-image" + animate={{ opacity: 1, y: 0 }} + exit={{ opacity: 0, y: 200 }} + height={sidebar.leftWidth} + initial={{ opacity: 0, y: 200 }} + role="button" + transition={{ duration: 0.3, ease: 'easeInOut' }} + onClick={expandFullScreenPlayer} + > + <Tooltip + label="Toggle fullscreen player" + openDelay={500} + > + {upsizedImageUrl ? ( + <SidebarImage + loading="eager" + src={upsizedImageUrl} + /> + ) : ( + <Center + sx={{ background: 'var(--placeholder-bg)', height: '100%' }} + > + <RiDiscLine + color="var(--placeholder-fg)" + size={50} + /> + </Center> + )} + </Tooltip> + <Button + compact + opacity={0.8} + radius={100} + size="md" + sx={{ cursor: 'default', position: 'absolute', right: 5, top: 5 }} + tooltip={{ label: 'Collapse', openDelay: 500 }} + variant="default" + onClick={(e) => { + e.stopPropagation(); + setSideBar({ image: false }); + }} + > + <RiArrowDownSLine + color="white" + size={20} + /> + </Button> + </ImageContainer> + )} + </AnimatePresence> + </Stack> + </SidebarContainer> + ); }; diff --git a/src/renderer/features/songs/components/jellyfin-song-filters.tsx b/src/renderer/features/songs/components/jellyfin-song-filters.tsx index 3a75f274..f0f3e0dd 100644 --- a/src/renderer/features/songs/components/jellyfin-song-filters.tsx +++ b/src/renderer/features/songs/components/jellyfin-song-filters.tsx @@ -7,160 +7,160 @@ import { useGenreList } from '/@/renderer/features/genres'; import { LibraryItem } from '/@/renderer/api/types'; interface JellyfinSongFiltersProps { - handleFilterChange: (filters: SongListFilter) => void; - id?: string; - pageKey: string; - serverId?: string; + handleFilterChange: (filters: SongListFilter) => void; + id?: string; + pageKey: string; + serverId?: string; } export const JellyfinSongFilters = ({ - id, - pageKey, - handleFilterChange, - serverId, + id, + pageKey, + handleFilterChange, + serverId, }: JellyfinSongFiltersProps) => { - const { setFilter } = useListStoreActions(); - const filter = useSongListFilter({ id, key: pageKey }); + const { setFilter } = useListStoreActions(); + const filter = useSongListFilter({ id, key: pageKey }); - // TODO - eventually replace with /items/filters endpoint to fetch genres and tags specific to the selected library - const genreListQuery = useGenreList({ query: null, serverId }); + // TODO - eventually replace with /items/filters endpoint to fetch genres and tags specific to the selected library + const genreListQuery = useGenreList({ query: null, serverId }); - const genreList = useMemo(() => { - if (!genreListQuery?.data) return []; - return genreListQuery.data.items.map((genre) => ({ - label: genre.name, - value: genre.id, - })); - }, [genreListQuery.data]); + const genreList = useMemo(() => { + if (!genreListQuery?.data) return []; + return genreListQuery.data.items.map((genre) => ({ + label: genre.name, + value: genre.id, + })); + }, [genreListQuery.data]); - const selectedGenres = useMemo(() => { - return filter._custom?.jellyfin?.GenreIds?.split(','); - }, [filter._custom?.jellyfin?.GenreIds]); + const selectedGenres = useMemo(() => { + return filter._custom?.jellyfin?.GenreIds?.split(','); + }, [filter._custom?.jellyfin?.GenreIds]); - const toggleFilters = [ - { - label: 'Is favorited', - onChange: (e: ChangeEvent<HTMLInputElement>) => { - const updatedFilters = setFilter({ - data: { - _custom: { - ...filter._custom, - jellyfin: { - ...filter._custom?.jellyfin, - IncludeItemTypes: 'Audio', - IsFavorite: e.currentTarget.checked ? true : undefined, - }, + const toggleFilters = [ + { + label: 'Is favorited', + onChange: (e: ChangeEvent<HTMLInputElement>) => { + const updatedFilters = setFilter({ + data: { + _custom: { + ...filter._custom, + jellyfin: { + ...filter._custom?.jellyfin, + IncludeItemTypes: 'Audio', + IsFavorite: e.currentTarget.checked ? true : undefined, + }, + }, + }, + itemType: LibraryItem.SONG, + key: pageKey, + }) as SongListFilter; + handleFilterChange(updatedFilters); }, - }, - itemType: LibraryItem.SONG, - key: pageKey, + value: filter._custom?.jellyfin?.IsFavorite, + }, + ]; + + const handleMinYearFilter = debounce((e: number | string) => { + if (typeof e === 'number' && (e < 1700 || e > 2300)) return; + const updatedFilters = setFilter({ + data: { + _custom: { + ...filter._custom, + jellyfin: { + ...filter._custom?.jellyfin, + IncludeItemTypes: 'Audio', + minYear: e === '' ? undefined : (e as number), + }, + }, + }, + itemType: LibraryItem.SONG, + key: pageKey, }) as SongListFilter; handleFilterChange(updatedFilters); - }, - value: filter._custom?.jellyfin?.IsFavorite, - }, - ]; + }, 500); - const handleMinYearFilter = debounce((e: number | string) => { - if (typeof e === 'number' && (e < 1700 || e > 2300)) return; - const updatedFilters = setFilter({ - data: { - _custom: { - ...filter._custom, - jellyfin: { - ...filter._custom?.jellyfin, - IncludeItemTypes: 'Audio', - minYear: e === '' ? undefined : (e as number), - }, - }, - }, - itemType: LibraryItem.SONG, - key: pageKey, - }) as SongListFilter; - handleFilterChange(updatedFilters); - }, 500); + const handleMaxYearFilter = debounce((e: number | string) => { + if (typeof e === 'number' && (e < 1700 || e > 2300)) return; + const updatedFilters = setFilter({ + data: { + _custom: { + ...filter._custom, + jellyfin: { + ...filter._custom?.jellyfin, + IncludeItemTypes: 'Audio', + maxYear: e === '' ? undefined : (e as number), + }, + }, + }, + itemType: LibraryItem.SONG, + key: pageKey, + }) as SongListFilter; + handleFilterChange(updatedFilters); + }, 500); - const handleMaxYearFilter = debounce((e: number | string) => { - if (typeof e === 'number' && (e < 1700 || e > 2300)) return; - const updatedFilters = setFilter({ - data: { - _custom: { - ...filter._custom, - jellyfin: { - ...filter._custom?.jellyfin, - IncludeItemTypes: 'Audio', - maxYear: e === '' ? undefined : (e as number), - }, - }, - }, - itemType: LibraryItem.SONG, - key: pageKey, - }) as SongListFilter; - handleFilterChange(updatedFilters); - }, 500); + const handleGenresFilter = debounce((e: string[] | undefined) => { + const genreFilterString = e?.length ? e.join(',') : undefined; + const updatedFilters = setFilter({ + data: { + _custom: { + ...filter._custom, + jellyfin: { + ...filter._custom?.jellyfin, + GenreIds: genreFilterString, + IncludeItemTypes: 'Audio', + }, + }, + }, + itemType: LibraryItem.SONG, + key: pageKey, + }) as SongListFilter; + handleFilterChange(updatedFilters); + }, 250); - const handleGenresFilter = debounce((e: string[] | undefined) => { - const genreFilterString = e?.length ? e.join(',') : undefined; - const updatedFilters = setFilter({ - data: { - _custom: { - ...filter._custom, - jellyfin: { - ...filter._custom?.jellyfin, - GenreIds: genreFilterString, - IncludeItemTypes: 'Audio', - }, - }, - }, - itemType: LibraryItem.SONG, - key: pageKey, - }) as SongListFilter; - handleFilterChange(updatedFilters); - }, 250); - - return ( - <Stack p="0.8rem"> - {toggleFilters.map((filter) => ( - <Group - key={`nd-filter-${filter.label}`} - position="apart" - > - <Text>{filter.label}</Text> - <Switch - checked={filter?.value || false} - onChange={filter.onChange} - /> - </Group> - ))} - <Divider my="0.5rem" /> - <Group grow> - <NumberInput - required - defaultValue={filter._custom?.jellyfin?.minYear} - label="From year" - max={2300} - min={1700} - onChange={handleMinYearFilter} - /> - <NumberInput - defaultValue={filter._custom?.jellyfin?.maxYear} - label="To year" - max={2300} - min={1700} - onChange={handleMaxYearFilter} - /> - </Group> - <Group grow> - <MultiSelect - clearable - searchable - data={genreList} - defaultValue={selectedGenres} - label="Genres" - width={250} - onChange={handleGenresFilter} - /> - </Group> - </Stack> - ); + return ( + <Stack p="0.8rem"> + {toggleFilters.map((filter) => ( + <Group + key={`nd-filter-${filter.label}`} + position="apart" + > + <Text>{filter.label}</Text> + <Switch + checked={filter?.value || false} + onChange={filter.onChange} + /> + </Group> + ))} + <Divider my="0.5rem" /> + <Group grow> + <NumberInput + required + defaultValue={filter._custom?.jellyfin?.minYear} + label="From year" + max={2300} + min={1700} + onChange={handleMinYearFilter} + /> + <NumberInput + defaultValue={filter._custom?.jellyfin?.maxYear} + label="To year" + max={2300} + min={1700} + onChange={handleMaxYearFilter} + /> + </Group> + <Group grow> + <MultiSelect + clearable + searchable + data={genreList} + defaultValue={selectedGenres} + label="Genres" + width={250} + onChange={handleGenresFilter} + /> + </Group> + </Stack> + ); }; diff --git a/src/renderer/features/songs/components/navidrome-song-filters.tsx b/src/renderer/features/songs/components/navidrome-song-filters.tsx index 619b459f..5dd83649 100644 --- a/src/renderer/features/songs/components/navidrome-song-filters.tsx +++ b/src/renderer/features/songs/components/navidrome-song-filters.tsx @@ -7,122 +7,122 @@ import { useGenreList } from '/@/renderer/features/genres'; import { LibraryItem } from '/@/renderer/api/types'; interface NavidromeSongFiltersProps { - handleFilterChange: (filters: SongListFilter) => void; - id?: string; - pageKey: string; - serverId?: string; + handleFilterChange: (filters: SongListFilter) => void; + id?: string; + pageKey: string; + serverId?: string; } export const NavidromeSongFilters = ({ - handleFilterChange, - pageKey, - id, - serverId, + handleFilterChange, + pageKey, + id, + serverId, }: NavidromeSongFiltersProps) => { - const { setFilter } = useListStoreActions(); - const filter = useSongListFilter({ id, key: pageKey }); + const { setFilter } = useListStoreActions(); + const filter = useSongListFilter({ id, key: pageKey }); - const genreListQuery = useGenreList({ query: null, serverId }); + const genreListQuery = useGenreList({ query: null, serverId }); - const genreList = useMemo(() => { - if (!genreListQuery?.data) return []; - return genreListQuery.data.items.map((genre) => ({ - label: genre.name, - value: genre.id, - })); - }, [genreListQuery.data]); + const genreList = useMemo(() => { + if (!genreListQuery?.data) return []; + return genreListQuery.data.items.map((genre) => ({ + label: genre.name, + value: genre.id, + })); + }, [genreListQuery.data]); - const handleGenresFilter = debounce((e: string | null) => { - const updatedFilters = setFilter({ - data: { - _custom: { - ...filter._custom, - navidrome: { - genre_id: e || undefined, - }, - }, - }, - itemType: LibraryItem.SONG, - key: pageKey, - }) as SongListFilter; - handleFilterChange(updatedFilters); - }, 250); - - const toggleFilters = [ - { - label: 'Is favorited', - onChange: (e: ChangeEvent<HTMLInputElement>) => { + const handleGenresFilter = debounce((e: string | null) => { const updatedFilters = setFilter({ - data: { - _custom: { - ...filter._custom, - navidrome: { - starred: e.currentTarget.checked ? true : undefined, - }, + data: { + _custom: { + ...filter._custom, + navidrome: { + genre_id: e || undefined, + }, + }, }, - }, - itemType: LibraryItem.SONG, - key: pageKey, + itemType: LibraryItem.SONG, + key: pageKey, + }) as SongListFilter; + handleFilterChange(updatedFilters); + }, 250); + + const toggleFilters = [ + { + label: 'Is favorited', + onChange: (e: ChangeEvent<HTMLInputElement>) => { + const updatedFilters = setFilter({ + data: { + _custom: { + ...filter._custom, + navidrome: { + starred: e.currentTarget.checked ? true : undefined, + }, + }, + }, + itemType: LibraryItem.SONG, + key: pageKey, + }) as SongListFilter; + + handleFilterChange(updatedFilters); + }, + value: filter._custom?.navidrome?.starred, + }, + ]; + + const handleYearFilter = debounce((e: number | string) => { + const updatedFilters = setFilter({ + data: { + _custom: { + ...filter._custom, + navidrome: { + year: e === '' ? undefined : (e as number), + }, + }, + }, + itemType: LibraryItem.SONG, + key: pageKey, }) as SongListFilter; handleFilterChange(updatedFilters); - }, - value: filter._custom?.navidrome?.starred, - }, - ]; + }, 500); - const handleYearFilter = debounce((e: number | string) => { - const updatedFilters = setFilter({ - data: { - _custom: { - ...filter._custom, - navidrome: { - year: e === '' ? undefined : (e as number), - }, - }, - }, - itemType: LibraryItem.SONG, - key: pageKey, - }) as SongListFilter; - - handleFilterChange(updatedFilters); - }, 500); - - return ( - <Stack p="0.8rem"> - {toggleFilters.map((filter) => ( - <Group - key={`nd-filter-${filter.label}`} - position="apart" - > - <Text>{filter.label}</Text> - <Switch - checked={filter?.value || false} - size="xs" - onChange={filter.onChange} - /> - </Group> - ))} - <Divider my="0.5rem" /> - <Group grow> - <NumberInput - label="Year" - max={5000} - min={0} - value={filter._custom?.navidrome?.year} - width={50} - onChange={(e) => handleYearFilter(e)} - /> - <Select - clearable - searchable - data={genreList} - defaultValue={filter._custom?.navidrome?.genre_id} - label="Genre" - width={150} - onChange={handleGenresFilter} - /> - </Group> - </Stack> - ); + return ( + <Stack p="0.8rem"> + {toggleFilters.map((filter) => ( + <Group + key={`nd-filter-${filter.label}`} + position="apart" + > + <Text>{filter.label}</Text> + <Switch + checked={filter?.value || false} + size="xs" + onChange={filter.onChange} + /> + </Group> + ))} + <Divider my="0.5rem" /> + <Group grow> + <NumberInput + label="Year" + max={5000} + min={0} + value={filter._custom?.navidrome?.year} + width={50} + onChange={(e) => handleYearFilter(e)} + /> + <Select + clearable + searchable + data={genreList} + defaultValue={filter._custom?.navidrome?.genre_id} + label="Genre" + width={150} + onChange={handleGenresFilter} + /> + </Group> + </Stack> + ); }; diff --git a/src/renderer/features/songs/components/song-list-content.tsx b/src/renderer/features/songs/components/song-list-content.tsx index 6135a282..8ec5a5f5 100644 --- a/src/renderer/features/songs/components/song-list-content.tsx +++ b/src/renderer/features/songs/components/song-list-content.tsx @@ -1,11 +1,11 @@ import { MutableRefObject, useCallback, useMemo } from 'react'; import type { - BodyScrollEvent, - ColDef, - GridReadyEvent, - IDatasource, - PaginationChangedEvent, - RowDoubleClickedEvent, + BodyScrollEvent, + ColDef, + GridReadyEvent, + IDatasource, + PaginationChangedEvent, + RowDoubleClickedEvent, } from '@ag-grid-community/core'; import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact'; import { Stack } from '@mantine/core'; @@ -13,10 +13,10 @@ import { useQueryClient } from '@tanstack/react-query'; import { api } from '/@/renderer/api'; import { queryKeys } from '/@/renderer/api/query-keys'; import { - useCurrentServer, - useListStoreActions, - useSongListFilter, - useSongListStore, + useCurrentServer, + useListStoreActions, + useSongListFilter, + useSongListStore, } from '/@/renderer/store'; import { ListDisplayType } from '/@/renderer/types'; import { AnimatePresence } from 'framer-motion'; @@ -30,186 +30,189 @@ import { VirtualGridAutoSizerContainer } from '/@/renderer/components/virtual-gr import { getColumnDefs, VirtualTable, TablePagination } from '/@/renderer/components/virtual-table'; interface SongListContentProps { - itemCount?: number; - tableRef: MutableRefObject<AgGridReactType | null>; + itemCount?: number; + tableRef: MutableRefObject<AgGridReactType | null>; } export const SongListContent = ({ itemCount, tableRef }: SongListContentProps) => { - const queryClient = useQueryClient(); - const server = useCurrentServer(); + const queryClient = useQueryClient(); + const server = useCurrentServer(); - const { id, pageKey, handlePlay } = useSongListContext(); - const filter = useSongListFilter({ id, key: pageKey }); - const { display, table } = useSongListStore({ id, key: pageKey }); + const { id, pageKey, handlePlay } = useSongListContext(); + const filter = useSongListFilter({ id, key: pageKey }); + const { display, table } = useSongListStore({ id, key: pageKey }); - const { setTable, setTablePagination } = useListStoreActions(); - const playButtonBehavior = usePlayButtonBehavior(); + const { setTable, setTablePagination } = useListStoreActions(); + const playButtonBehavior = usePlayButtonBehavior(); - const isPaginationEnabled = display === ListDisplayType.TABLE_PAGINATED; + const isPaginationEnabled = display === ListDisplayType.TABLE_PAGINATED; - const columnDefs: ColDef[] = useMemo(() => getColumnDefs(table.columns), [table.columns]); + const columnDefs: ColDef[] = useMemo(() => getColumnDefs(table.columns), [table.columns]); - const onGridReady = useCallback( - (params: GridReadyEvent) => { - const dataSource: IDatasource = { - getRows: async (params) => { - const limit = params.endRow - params.startRow; - const startIndex = params.startRow; + const onGridReady = useCallback( + (params: GridReadyEvent) => { + const dataSource: IDatasource = { + getRows: async (params) => { + const limit = params.endRow - params.startRow; + const startIndex = params.startRow; - const query: SongListQuery = { - limit, - startIndex, - ...filter, - }; + const query: SongListQuery = { + limit, + startIndex, + ...filter, + }; - const queryKey = queryKeys.songs.list(server?.id || '', query); + const queryKey = queryKeys.songs.list(server?.id || '', query); - const songsRes = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.getSongList({ - apiClientProps: { - server, - signal, + const songsRes = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.getSongList({ + apiClientProps: { + server, + signal, + }, + query, + }), + { cacheTime: 1000 * 60 * 1 }, + ); + + params.successCallback(songsRes?.items || [], songsRes?.totalRecordCount || 0); }, - query, - }), - { cacheTime: 1000 * 60 * 1 }, - ); + rowCount: undefined, + }; + params.api.setDatasource(dataSource); - params.successCallback(songsRes?.items || [], songsRes?.totalRecordCount || 0); + params.api.ensureIndexVisible(table.scrollOffset, 'top'); }, - rowCount: undefined, - }; - params.api.setDatasource(dataSource); + [filter, table.scrollOffset, queryClient, server], + ); - params.api.ensureIndexVisible(table.scrollOffset, 'top'); - }, - [filter, table.scrollOffset, queryClient, server], - ); + const onPaginationChanged = useCallback( + (event: PaginationChangedEvent) => { + if (!isPaginationEnabled || !event.api) return; - const onPaginationChanged = useCallback( - (event: PaginationChangedEvent) => { - if (!isPaginationEnabled || !event.api) return; - - try { - // Scroll to top of page on pagination change - const currentPageStartIndex = table.pagination.currentPage * table.pagination.itemsPerPage; - event.api?.ensureIndexVisible(currentPageStartIndex, 'top'); - } catch (err) { - console.log(err); - } - setTablePagination({ - data: { - itemsPerPage: event.api.paginationGetPageSize(), - totalItems: event.api.paginationGetRowCount(), - totalPages: event.api.paginationGetTotalPages() + 1, + try { + // Scroll to top of page on pagination change + const currentPageStartIndex = + table.pagination.currentPage * table.pagination.itemsPerPage; + event.api?.ensureIndexVisible(currentPageStartIndex, 'top'); + } catch (err) { + console.log(err); + } + setTablePagination({ + data: { + itemsPerPage: event.api.paginationGetPageSize(), + totalItems: event.api.paginationGetRowCount(), + totalPages: event.api.paginationGetTotalPages() + 1, + }, + key: pageKey, + }); }, - key: pageKey, - }); - }, - [ - isPaginationEnabled, - pageKey, - setTablePagination, - table.pagination.currentPage, - table.pagination.itemsPerPage, - ], - ); + [ + isPaginationEnabled, + pageKey, + setTablePagination, + table.pagination.currentPage, + table.pagination.itemsPerPage, + ], + ); - const handleGridSizeChange = () => { - if (table.autoFit) { - tableRef?.current?.api.sizeColumnsToFit(); - } - }; + const handleGridSizeChange = () => { + if (table.autoFit) { + tableRef?.current?.api.sizeColumnsToFit(); + } + }; - const handleColumnChange = useCallback(() => { - const { columnApi } = tableRef?.current || {}; - const columnsOrder = columnApi?.getAllGridColumns(); + const handleColumnChange = useCallback(() => { + const { columnApi } = tableRef?.current || {}; + const columnsOrder = columnApi?.getAllGridColumns(); - if (!columnsOrder) return; + if (!columnsOrder) return; - const columnsInSettings = table.columns; - const updatedColumns = []; - for (const column of columnsOrder) { - const columnInSettings = columnsInSettings.find((c) => c.column === column.getColDef().colId); + const columnsInSettings = table.columns; + const updatedColumns = []; + for (const column of columnsOrder) { + const columnInSettings = columnsInSettings.find( + (c) => c.column === column.getColDef().colId, + ); - if (columnInSettings) { - updatedColumns.push({ - ...columnInSettings, - ...(!table.autoFit && { - width: column.getActualWidth(), - }), - }); - } - } + if (columnInSettings) { + updatedColumns.push({ + ...columnInSettings, + ...(!table.autoFit && { + width: column.getActualWidth(), + }), + }); + } + } - setTable({ data: { columns: updatedColumns }, key: pageKey }); - }, [tableRef, table.columns, table.autoFit, setTable, pageKey]); + setTable({ data: { columns: updatedColumns }, key: pageKey }); + }, [tableRef, table.columns, table.autoFit, setTable, pageKey]); - const debouncedColumnChange = debounce(handleColumnChange, 200); + const debouncedColumnChange = debounce(handleColumnChange, 200); - const handleScroll = (e: BodyScrollEvent) => { - const scrollOffset = Number((e.top / table.rowHeight).toFixed(0)); - setTable({ data: { scrollOffset }, key: pageKey }); - }; + const handleScroll = (e: BodyScrollEvent) => { + const scrollOffset = Number((e.top / table.rowHeight).toFixed(0)); + setTable({ data: { scrollOffset }, key: pageKey }); + }; - const handleContextMenu = useHandleTableContextMenu(LibraryItem.SONG, SONG_CONTEXT_MENU_ITEMS); + const handleContextMenu = useHandleTableContextMenu(LibraryItem.SONG, SONG_CONTEXT_MENU_ITEMS); - const handleRowDoubleClick = (e: RowDoubleClickedEvent<QueueSong>) => { - if (!e.data) return; - handlePlay?.({ initialSongId: e.data.id, playType: playButtonBehavior }); - }; + const handleRowDoubleClick = (e: RowDoubleClickedEvent<QueueSong>) => { + if (!e.data) return; + handlePlay?.({ initialSongId: e.data.id, playType: playButtonBehavior }); + }; - return ( - <Stack - h="100%" - spacing={0} - > - <VirtualGridAutoSizerContainer> - <VirtualTable - // https://github.com/ag-grid/ag-grid/issues/5284 - // Key is used to force remount of table when display, rowHeight, or server changes - key={`table-${display}-${table.rowHeight}-${server?.id}`} - ref={tableRef} - alwaysShowHorizontalScroll - suppressRowDrag - autoFitColumns={table.autoFit} - blockLoadDebounceMillis={200} - columnDefs={columnDefs} - getRowId={(data) => data.data.id} - infiniteInitialRowCount={itemCount || 100} - pagination={isPaginationEnabled} - paginationAutoPageSize={isPaginationEnabled} - paginationPageSize={table.pagination.itemsPerPage || 100} - rowBuffer={20} - rowHeight={table.rowHeight || 40} - rowModelType="infinite" - rowSelection="multiple" - onBodyScrollEnd={handleScroll} - onCellContextMenu={handleContextMenu} - onColumnMoved={handleColumnChange} - onColumnResized={debouncedColumnChange} - onGridReady={onGridReady} - onGridSizeChanged={handleGridSizeChange} - onPaginationChanged={onPaginationChanged} - onRowDoubleClicked={handleRowDoubleClick} - /> - </VirtualGridAutoSizerContainer> - <AnimatePresence - presenceAffectsLayout - initial={false} - mode="wait" - > - {display === ListDisplayType.TABLE_PAGINATED && ( - <TablePagination - pageKey={pageKey} - pagination={table.pagination} - setPagination={setTablePagination} - tableRef={tableRef} - /> - )} - </AnimatePresence> - </Stack> - ); + return ( + <Stack + h="100%" + spacing={0} + > + <VirtualGridAutoSizerContainer> + <VirtualTable + // https://github.com/ag-grid/ag-grid/issues/5284 + // Key is used to force remount of table when display, rowHeight, or server changes + key={`table-${display}-${table.rowHeight}-${server?.id}`} + ref={tableRef} + alwaysShowHorizontalScroll + suppressRowDrag + autoFitColumns={table.autoFit} + blockLoadDebounceMillis={200} + columnDefs={columnDefs} + getRowId={(data) => data.data.id} + infiniteInitialRowCount={itemCount || 100} + pagination={isPaginationEnabled} + paginationAutoPageSize={isPaginationEnabled} + paginationPageSize={table.pagination.itemsPerPage || 100} + rowBuffer={20} + rowHeight={table.rowHeight || 40} + rowModelType="infinite" + rowSelection="multiple" + onBodyScrollEnd={handleScroll} + onCellContextMenu={handleContextMenu} + onColumnMoved={handleColumnChange} + onColumnResized={debouncedColumnChange} + onGridReady={onGridReady} + onGridSizeChanged={handleGridSizeChange} + onPaginationChanged={onPaginationChanged} + onRowDoubleClicked={handleRowDoubleClick} + /> + </VirtualGridAutoSizerContainer> + <AnimatePresence + presenceAffectsLayout + initial={false} + mode="wait" + > + {display === ListDisplayType.TABLE_PAGINATED && ( + <TablePagination + pageKey={pageKey} + pagination={table.pagination} + setPagination={setTablePagination} + tableRef={tableRef} + /> + )} + </AnimatePresence> + </Stack> + ); }; diff --git a/src/renderer/features/songs/components/song-list-header-filters.tsx b/src/renderer/features/songs/components/song-list-header-filters.tsx index 51f91b6d..7ac3ce4e 100644 --- a/src/renderer/features/songs/components/song-list-header-filters.tsx +++ b/src/renderer/features/songs/components/song-list-header-filters.tsx @@ -4,16 +4,16 @@ import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/li import { Flex, Group, Stack } from '@mantine/core'; import { openModal } from '@mantine/modals'; import { - RiSortAsc, - RiSortDesc, - RiFolder2Line, - RiMoreFill, - RiSettings3Fill, - RiPlayFill, - RiAddBoxFill, - RiAddCircleFill, - RiRefreshLine, - RiFilterFill, + RiSortAsc, + RiSortDesc, + RiFolder2Line, + RiMoreFill, + RiSettings3Fill, + RiPlayFill, + RiAddBoxFill, + RiAddCircleFill, + RiRefreshLine, + RiFilterFill, } from 'react-icons/ri'; import { api } from '/@/renderer/api'; import { queryKeys } from '/@/renderer/api/query-keys'; @@ -25,469 +25,487 @@ import { NavidromeSongFilters } from '/@/renderer/features/songs/components/navi import { useContainerQuery } from '/@/renderer/hooks'; import { queryClient } from '/@/renderer/lib/react-query'; import { - SongListFilter, - useCurrentServer, - useListStoreActions, - useSongListFilter, - useSongListStore, + SongListFilter, + useCurrentServer, + useListStoreActions, + useSongListFilter, + useSongListStore, } from '/@/renderer/store'; import { ListDisplayType, ServerType, Play, TableColumn } from '/@/renderer/types'; import { useSongListContext } from '/@/renderer/features/songs/context/song-list-context'; import { SONG_TABLE_COLUMNS } from '/@/renderer/components/virtual-table'; const FILTERS = { - jellyfin: [ - { defaultOrder: SortOrder.ASC, name: 'Album', value: SongListSort.ALBUM }, - { defaultOrder: SortOrder.ASC, name: 'Album Artist', value: SongListSort.ALBUM_ARTIST }, - { defaultOrder: SortOrder.ASC, name: 'Artist', value: SongListSort.ARTIST }, - { defaultOrder: SortOrder.ASC, name: 'Duration', value: SongListSort.DURATION }, - { defaultOrder: SortOrder.ASC, name: 'Most Played', value: SongListSort.PLAY_COUNT }, - { defaultOrder: SortOrder.ASC, name: 'Name', value: SongListSort.NAME }, - { defaultOrder: SortOrder.ASC, name: 'Random', value: SongListSort.RANDOM }, - { defaultOrder: SortOrder.ASC, name: 'Recently Added', value: SongListSort.RECENTLY_ADDED }, - { defaultOrder: SortOrder.ASC, name: 'Recently Played', value: SongListSort.RECENTLY_PLAYED }, - { defaultOrder: SortOrder.ASC, name: 'Release Date', value: SongListSort.RELEASE_DATE }, - ], - navidrome: [ - { defaultOrder: SortOrder.ASC, name: 'Album', value: SongListSort.ALBUM }, - { defaultOrder: SortOrder.ASC, name: 'Album Artist', value: SongListSort.ALBUM_ARTIST }, - { defaultOrder: SortOrder.ASC, name: 'Artist', value: SongListSort.ARTIST }, - { defaultOrder: SortOrder.DESC, name: 'BPM', value: SongListSort.BPM }, - { defaultOrder: SortOrder.ASC, name: 'Channels', value: SongListSort.CHANNELS }, - { defaultOrder: SortOrder.ASC, name: 'Comment', value: SongListSort.COMMENT }, - { defaultOrder: SortOrder.DESC, name: 'Duration', value: SongListSort.DURATION }, - { defaultOrder: SortOrder.DESC, name: 'Favorited', value: SongListSort.FAVORITED }, - { defaultOrder: SortOrder.ASC, name: 'Genre', value: SongListSort.GENRE }, - { defaultOrder: SortOrder.ASC, name: 'Name', value: SongListSort.NAME }, - { defaultOrder: SortOrder.DESC, name: 'Play Count', value: SongListSort.PLAY_COUNT }, - { defaultOrder: SortOrder.DESC, name: 'Rating', value: SongListSort.RATING }, - { defaultOrder: SortOrder.DESC, name: 'Recently Added', value: SongListSort.RECENTLY_ADDED }, - { defaultOrder: SortOrder.DESC, name: 'Recently Played', value: SongListSort.RECENTLY_PLAYED }, - { defaultOrder: SortOrder.DESC, name: 'Year', value: SongListSort.YEAR }, - ], + jellyfin: [ + { defaultOrder: SortOrder.ASC, name: 'Album', value: SongListSort.ALBUM }, + { defaultOrder: SortOrder.ASC, name: 'Album Artist', value: SongListSort.ALBUM_ARTIST }, + { defaultOrder: SortOrder.ASC, name: 'Artist', value: SongListSort.ARTIST }, + { defaultOrder: SortOrder.ASC, name: 'Duration', value: SongListSort.DURATION }, + { defaultOrder: SortOrder.ASC, name: 'Most Played', value: SongListSort.PLAY_COUNT }, + { defaultOrder: SortOrder.ASC, name: 'Name', value: SongListSort.NAME }, + { defaultOrder: SortOrder.ASC, name: 'Random', value: SongListSort.RANDOM }, + { defaultOrder: SortOrder.ASC, name: 'Recently Added', value: SongListSort.RECENTLY_ADDED }, + { + defaultOrder: SortOrder.ASC, + name: 'Recently Played', + value: SongListSort.RECENTLY_PLAYED, + }, + { defaultOrder: SortOrder.ASC, name: 'Release Date', value: SongListSort.RELEASE_DATE }, + ], + navidrome: [ + { defaultOrder: SortOrder.ASC, name: 'Album', value: SongListSort.ALBUM }, + { defaultOrder: SortOrder.ASC, name: 'Album Artist', value: SongListSort.ALBUM_ARTIST }, + { defaultOrder: SortOrder.ASC, name: 'Artist', value: SongListSort.ARTIST }, + { defaultOrder: SortOrder.DESC, name: 'BPM', value: SongListSort.BPM }, + { defaultOrder: SortOrder.ASC, name: 'Channels', value: SongListSort.CHANNELS }, + { defaultOrder: SortOrder.ASC, name: 'Comment', value: SongListSort.COMMENT }, + { defaultOrder: SortOrder.DESC, name: 'Duration', value: SongListSort.DURATION }, + { defaultOrder: SortOrder.DESC, name: 'Favorited', value: SongListSort.FAVORITED }, + { defaultOrder: SortOrder.ASC, name: 'Genre', value: SongListSort.GENRE }, + { defaultOrder: SortOrder.ASC, name: 'Name', value: SongListSort.NAME }, + { defaultOrder: SortOrder.DESC, name: 'Play Count', value: SongListSort.PLAY_COUNT }, + { defaultOrder: SortOrder.DESC, name: 'Rating', value: SongListSort.RATING }, + { + defaultOrder: SortOrder.DESC, + name: 'Recently Added', + value: SongListSort.RECENTLY_ADDED, + }, + { + defaultOrder: SortOrder.DESC, + name: 'Recently Played', + value: SongListSort.RECENTLY_PLAYED, + }, + { defaultOrder: SortOrder.DESC, name: 'Year', value: SongListSort.YEAR }, + ], }; const ORDER = [ - { name: 'Ascending', value: SortOrder.ASC }, - { name: 'Descending', value: SortOrder.DESC }, + { name: 'Ascending', value: SortOrder.ASC }, + { name: 'Descending', value: SortOrder.DESC }, ]; interface SongListHeaderFiltersProps { - tableRef: MutableRefObject<AgGridReactType | null>; + tableRef: MutableRefObject<AgGridReactType | null>; } export const SongListHeaderFilters = ({ tableRef }: SongListHeaderFiltersProps) => { - const server = useCurrentServer(); - const { id, pageKey, handlePlay } = useSongListContext(); - const { display, table } = useSongListStore({ id, key: pageKey }); - const { setFilter, setTable, setTablePagination, setDisplayType } = useListStoreActions(); - const filter = useSongListFilter({ id, key: pageKey }); + const server = useCurrentServer(); + const { id, pageKey, handlePlay } = useSongListContext(); + const { display, table } = useSongListStore({ id, key: pageKey }); + const { setFilter, setTable, setTablePagination, setDisplayType } = useListStoreActions(); + const filter = useSongListFilter({ id, key: pageKey }); - const cq = useContainerQuery(); + const cq = useContainerQuery(); - const musicFoldersQuery = useMusicFolders({ query: null, serverId: server?.id }); + const musicFoldersQuery = useMusicFolders({ query: null, serverId: server?.id }); - const sortByLabel = - (server?.type && - (FILTERS[server.type as keyof typeof FILTERS] as { name: string; value: string }[]).find( - (f) => f.value === filter.sortBy, - )?.name) || - 'Unknown'; + const sortByLabel = + (server?.type && + ( + FILTERS[server.type as keyof typeof FILTERS] as { name: string; value: string }[] + ).find((f) => f.value === filter.sortBy)?.name) || + 'Unknown'; - const sortOrderLabel = ORDER.find((s) => s.value === filter.sortOrder)?.name; + const sortOrderLabel = ORDER.find((s) => s.value === filter.sortOrder)?.name; - const handleFilterChange = useCallback( - async (filters?: SongListFilter) => { - const dataSource: IDatasource = { - getRows: async (params) => { - const limit = params.endRow - params.startRow; - const startIndex = params.startRow; + const handleFilterChange = useCallback( + async (filters?: SongListFilter) => { + const dataSource: IDatasource = { + getRows: async (params) => { + const limit = params.endRow - params.startRow; + const startIndex = params.startRow; - const pageFilters = filters || filter; + const pageFilters = filters || filter; - const query: SongListQuery = { - limit, - startIndex, - ...pageFilters, - }; + const query: SongListQuery = { + limit, + startIndex, + ...pageFilters, + }; - const queryKey = queryKeys.songs.list(server?.id || '', query); + const queryKey = queryKeys.songs.list(server?.id || '', query); - const songsRes = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.getSongList({ - apiClientProps: { - server, - signal, + const songsRes = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.getSongList({ + apiClientProps: { + server, + signal, + }, + query, + }), + { cacheTime: 1000 * 60 * 1 }, + ); + + params.successCallback(songsRes?.items || [], songsRes?.totalRecordCount || 0); }, - query, - }), - { cacheTime: 1000 * 60 * 1 }, - ); - - params.successCallback(songsRes?.items || [], songsRes?.totalRecordCount || 0); + rowCount: undefined, + }; + tableRef.current?.api.setDatasource(dataSource); + tableRef.current?.api.purgeInfiniteCache(); + tableRef.current?.api.ensureIndexVisible(0, 'top'); + setTablePagination({ data: { currentPage: 0 }, key: pageKey }); }, - rowCount: undefined, - }; - tableRef.current?.api.setDatasource(dataSource); - tableRef.current?.api.purgeInfiniteCache(); - tableRef.current?.api.ensureIndexVisible(0, 'top'); - setTablePagination({ data: { currentPage: 0 }, key: pageKey }); - }, - [filter, pageKey, server, setTablePagination, tableRef], - ); + [filter, pageKey, server, setTablePagination, tableRef], + ); - const handleSetSortBy = useCallback( - (e: MouseEvent<HTMLButtonElement>) => { - if (!e.currentTarget?.value || !server?.type) return; + const handleSetSortBy = useCallback( + (e: MouseEvent<HTMLButtonElement>) => { + if (!e.currentTarget?.value || !server?.type) return; - const sortOrder = FILTERS[server.type as keyof typeof FILTERS].find( - (f) => f.value === e.currentTarget.value, - )?.defaultOrder; + const sortOrder = FILTERS[server.type as keyof typeof FILTERS].find( + (f) => f.value === e.currentTarget.value, + )?.defaultOrder; - const updatedFilters = setFilter({ - data: { - sortBy: e.currentTarget.value as SongListSort, - sortOrder: sortOrder || SortOrder.ASC, + const updatedFilters = setFilter({ + data: { + sortBy: e.currentTarget.value as SongListSort, + sortOrder: sortOrder || SortOrder.ASC, + }, + itemType: LibraryItem.SONG, + key: pageKey, + }) as SongListFilter; + + handleFilterChange(updatedFilters); }, - itemType: LibraryItem.SONG, - key: pageKey, - }) as SongListFilter; + [handleFilterChange, pageKey, server?.type, setFilter], + ); - handleFilterChange(updatedFilters); - }, - [handleFilterChange, pageKey, server?.type, setFilter], - ); + const handleSetMusicFolder = useCallback( + (e: MouseEvent<HTMLButtonElement>) => { + if (!e.currentTarget?.value) return; - const handleSetMusicFolder = useCallback( - (e: MouseEvent<HTMLButtonElement>) => { - if (!e.currentTarget?.value) return; + let updatedFilters = null; + if (e.currentTarget.value === String(filter.musicFolderId)) { + updatedFilters = setFilter({ + data: { musicFolderId: undefined }, + itemType: LibraryItem.SONG, + key: pageKey, + }) as SongListFilter; + } else { + updatedFilters = setFilter({ + data: { musicFolderId: e.currentTarget.value }, + itemType: LibraryItem.SONG, + key: pageKey, + }) as SongListFilter; + } - let updatedFilters = null; - if (e.currentTarget.value === String(filter.musicFolderId)) { - updatedFilters = setFilter({ - data: { musicFolderId: undefined }, - itemType: LibraryItem.SONG, - key: pageKey, + handleFilterChange(updatedFilters); + }, + [filter.musicFolderId, handleFilterChange, setFilter, pageKey], + ); + + const handleToggleSortOrder = useCallback(() => { + const newSortOrder = filter.sortOrder === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC; + const updatedFilters = setFilter({ + data: { sortOrder: newSortOrder }, + itemType: LibraryItem.SONG, + key: pageKey, }) as SongListFilter; - } else { - updatedFilters = setFilter({ - data: { musicFolderId: e.currentTarget.value }, - itemType: LibraryItem.SONG, - key: pageKey, - }) as SongListFilter; - } + handleFilterChange(updatedFilters); + }, [filter.sortOrder, handleFilterChange, pageKey, setFilter]); - handleFilterChange(updatedFilters); - }, - [filter.musicFolderId, handleFilterChange, setFilter, pageKey], - ); + const handleSetViewType = useCallback( + (e: MouseEvent<HTMLButtonElement>) => { + if (!e.currentTarget?.value) return; + const display = e.currentTarget.value as ListDisplayType; + setDisplayType({ + data: e.currentTarget.value as ListDisplayType, + key: pageKey, + }); - const handleToggleSortOrder = useCallback(() => { - const newSortOrder = filter.sortOrder === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC; - const updatedFilters = setFilter({ - data: { sortOrder: newSortOrder }, - itemType: LibraryItem.SONG, - key: pageKey, - }) as SongListFilter; - handleFilterChange(updatedFilters); - }, [filter.sortOrder, handleFilterChange, pageKey, setFilter]); - - const handleSetViewType = useCallback( - (e: MouseEvent<HTMLButtonElement>) => { - if (!e.currentTarget?.value) return; - const display = e.currentTarget.value as ListDisplayType; - setDisplayType({ - data: e.currentTarget.value as ListDisplayType, - key: pageKey, - }); - - if (display === ListDisplayType.TABLE) { - tableRef.current?.api.paginationSetPageSize(tableRef.current.props.infiniteInitialRowCount); - setTablePagination({ data: { currentPage: 0 }, key: pageKey }); - } else if (display === ListDisplayType.TABLE_PAGINATED) { - setTablePagination({ data: { currentPage: 0 }, key: pageKey }); - } - }, - [pageKey, setDisplayType, setTablePagination, tableRef], - ); - - const handleTableColumns = (values: TableColumn[]) => { - const existingColumns = table.columns; - - if (values.length === 0) { - return setTable({ - data: { - columns: [], + if (display === ListDisplayType.TABLE) { + tableRef.current?.api.paginationSetPageSize( + tableRef.current.props.infiniteInitialRowCount, + ); + setTablePagination({ data: { currentPage: 0 }, key: pageKey }); + } else if (display === ListDisplayType.TABLE_PAGINATED) { + setTablePagination({ data: { currentPage: 0 }, key: pageKey }); + } }, - key: pageKey, - }); - } + [pageKey, setDisplayType, setTablePagination, tableRef], + ); - // If adding a column - if (values.length > existingColumns.length) { - const newColumn = { column: values[values.length - 1], width: 100 }; + const handleTableColumns = (values: TableColumn[]) => { + const existingColumns = table.columns; - return setTable({ data: { columns: [...existingColumns, newColumn] }, key: pageKey }); - } + if (values.length === 0) { + return setTable({ + data: { + columns: [], + }, + key: pageKey, + }); + } - // If removing a column - const removed = existingColumns.filter((column) => !values.includes(column.column)); - const newColumns = existingColumns.filter((column) => !removed.includes(column)); + // If adding a column + if (values.length > existingColumns.length) { + const newColumn = { column: values[values.length - 1], width: 100 }; - return setTable({ data: { columns: newColumns }, key: pageKey }); - }; + return setTable({ data: { columns: [...existingColumns, newColumn] }, key: pageKey }); + } - const handleAutoFitColumns = (e: ChangeEvent<HTMLInputElement>) => { - setTable({ data: { autoFit: e.currentTarget.checked }, key: pageKey }); + // If removing a column + const removed = existingColumns.filter((column) => !values.includes(column.column)); + const newColumns = existingColumns.filter((column) => !removed.includes(column)); - if (e.currentTarget.checked) { - tableRef.current?.api.sizeColumnsToFit(); - } - }; + return setTable({ data: { columns: newColumns }, key: pageKey }); + }; - const handleRowHeight = (e: number) => { - setTable({ data: { rowHeight: e }, key: pageKey }); - }; + const handleAutoFitColumns = (e: ChangeEvent<HTMLInputElement>) => { + setTable({ data: { autoFit: e.currentTarget.checked }, key: pageKey }); - const handleRefresh = () => { - queryClient.invalidateQueries(queryKeys.songs.list(server?.id || '')); - handleFilterChange(filter); - }; + if (e.currentTarget.checked) { + tableRef.current?.api.sizeColumnsToFit(); + } + }; - const handleOpenFiltersModal = () => { - openModal({ - children: ( - <> - {server?.type === ServerType.NAVIDROME ? ( - <NavidromeSongFilters - handleFilterChange={handleFilterChange} - id={id} - pageKey={pageKey} - /> - ) : ( - <JellyfinSongFilters - handleFilterChange={handleFilterChange} - id={id} - pageKey={pageKey} - /> - )} - </> - ), - title: 'Song Filters', - }); - }; + const handleRowHeight = (e: number) => { + setTable({ data: { rowHeight: e }, key: pageKey }); + }; - const isFilterApplied = useMemo(() => { - const isNavidromeFilterApplied = - server?.type === ServerType.NAVIDROME && - filter._custom?.navidrome && - Object.values(filter?._custom?.navidrome).some((value) => value !== undefined); + const handleRefresh = () => { + queryClient.invalidateQueries(queryKeys.songs.list(server?.id || '')); + handleFilterChange(filter); + }; - const isJellyfinFilterApplied = - server?.type === ServerType.JELLYFIN && - filter?._custom?.jellyfin && - Object.values(filter?._custom?.jellyfin) - .filter((value) => value !== 'Audio') // Don't account for includeItemTypes: Audio - .some((value) => value !== undefined); + const handleOpenFiltersModal = () => { + openModal({ + children: ( + <> + {server?.type === ServerType.NAVIDROME ? ( + <NavidromeSongFilters + handleFilterChange={handleFilterChange} + id={id} + pageKey={pageKey} + /> + ) : ( + <JellyfinSongFilters + handleFilterChange={handleFilterChange} + id={id} + pageKey={pageKey} + /> + )} + </> + ), + title: 'Song Filters', + }); + }; - return isNavidromeFilterApplied || isJellyfinFilterApplied; - }, [filter?._custom?.jellyfin, filter?._custom?.navidrome, server?.type]); + const isFilterApplied = useMemo(() => { + const isNavidromeFilterApplied = + server?.type === ServerType.NAVIDROME && + filter._custom?.navidrome && + Object.values(filter?._custom?.navidrome).some((value) => value !== undefined); - return ( - <Flex justify="space-between"> - <Group - ref={cq.ref} - spacing="sm" - w="100%" - > - <DropdownMenu position="bottom-start"> - <DropdownMenu.Target> - <Button - compact - fw="600" - size="md" - variant="subtle" + const isJellyfinFilterApplied = + server?.type === ServerType.JELLYFIN && + filter?._custom?.jellyfin && + Object.values(filter?._custom?.jellyfin) + .filter((value) => value !== 'Audio') // Don't account for includeItemTypes: Audio + .some((value) => value !== undefined); + + return isNavidromeFilterApplied || isJellyfinFilterApplied; + }, [filter?._custom?.jellyfin, filter?._custom?.navidrome, server?.type]); + + return ( + <Flex justify="space-between"> + <Group + ref={cq.ref} + spacing="sm" + w="100%" > - {sortByLabel} - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - {FILTERS[server?.type as keyof typeof FILTERS].map((f) => ( - <DropdownMenu.Item - key={`filter-${f.name}`} - $isActive={f.value === filter.sortBy} - value={f.value} - onClick={handleSetSortBy} - > - {f.name} - </DropdownMenu.Item> - ))} - </DropdownMenu.Dropdown> - </DropdownMenu> - <Button - compact - fw="600" - size="md" - variant="subtle" - onClick={handleToggleSortOrder} - > - {cq.isSm ? ( - sortOrderLabel - ) : ( - <> - {filter.sortOrder === SortOrder.ASC ? ( - <RiSortAsc size="1.3rem" /> - ) : ( - <RiSortDesc size="1.3rem" /> - )} - </> - )} - </Button> - {server?.type === ServerType.JELLYFIN && ( - <DropdownMenu position="bottom-start"> - <DropdownMenu.Target> - <Button - compact - fw="600" - size="md" - variant="subtle" - > - {cq.isSm ? 'Folder' : <RiFolder2Line size="1.3rem" />} - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - {musicFoldersQuery.data?.items.map((folder) => ( - <DropdownMenu.Item - key={`musicFolder-${folder.id}`} - $isActive={filter.musicFolderId === folder.id} - value={folder.id} - onClick={handleSetMusicFolder} + <DropdownMenu position="bottom-start"> + <DropdownMenu.Target> + <Button + compact + fw="600" + size="md" + variant="subtle" + > + {sortByLabel} + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + {FILTERS[server?.type as keyof typeof FILTERS].map((f) => ( + <DropdownMenu.Item + key={`filter-${f.name}`} + $isActive={f.value === filter.sortBy} + value={f.value} + onClick={handleSetSortBy} + > + {f.name} + </DropdownMenu.Item> + ))} + </DropdownMenu.Dropdown> + </DropdownMenu> + <Button + compact + fw="600" + size="md" + variant="subtle" + onClick={handleToggleSortOrder} > - {folder.name} - </DropdownMenu.Item> - ))} - </DropdownMenu.Dropdown> - </DropdownMenu> - )} - <DropdownMenu position="bottom-start"> - <DropdownMenu.Target> - <Button - compact - fw="600" - size="md" - variant="subtle" + {cq.isSm ? ( + sortOrderLabel + ) : ( + <> + {filter.sortOrder === SortOrder.ASC ? ( + <RiSortAsc size="1.3rem" /> + ) : ( + <RiSortDesc size="1.3rem" /> + )} + </> + )} + </Button> + {server?.type === ServerType.JELLYFIN && ( + <DropdownMenu position="bottom-start"> + <DropdownMenu.Target> + <Button + compact + fw="600" + size="md" + variant="subtle" + > + {cq.isSm ? 'Folder' : <RiFolder2Line size="1.3rem" />} + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + {musicFoldersQuery.data?.items.map((folder) => ( + <DropdownMenu.Item + key={`musicFolder-${folder.id}`} + $isActive={filter.musicFolderId === folder.id} + value={folder.id} + onClick={handleSetMusicFolder} + > + {folder.name} + </DropdownMenu.Item> + ))} + </DropdownMenu.Dropdown> + </DropdownMenu> + )} + <DropdownMenu position="bottom-start"> + <DropdownMenu.Target> + <Button + compact + fw="600" + size="md" + variant="subtle" + > + <RiMoreFill size="1.3rem" /> + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + <DropdownMenu.Item + icon={<RiPlayFill />} + onClick={() => handlePlay?.({ playType: Play.NOW })} + > + Play + </DropdownMenu.Item> + <DropdownMenu.Item + icon={<RiAddBoxFill />} + onClick={() => handlePlay?.({ playType: Play.LAST })} + > + Add to queue + </DropdownMenu.Item> + <DropdownMenu.Item + icon={<RiAddCircleFill />} + onClick={() => handlePlay?.({ playType: Play.NEXT })} + > + Add to queue next + </DropdownMenu.Item> + <DropdownMenu.Divider /> + <DropdownMenu.Item + icon={<RiRefreshLine />} + onClick={handleRefresh} + > + Refresh + </DropdownMenu.Item> + </DropdownMenu.Dropdown> + </DropdownMenu> + </Group> + <Group + noWrap + spacing="sm" > - <RiMoreFill size="1.3rem" /> - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - <DropdownMenu.Item - icon={<RiPlayFill />} - onClick={() => handlePlay?.({ playType: Play.NOW })} - > - Play - </DropdownMenu.Item> - <DropdownMenu.Item - icon={<RiAddBoxFill />} - onClick={() => handlePlay?.({ playType: Play.LAST })} - > - Add to queue - </DropdownMenu.Item> - <DropdownMenu.Item - icon={<RiAddCircleFill />} - onClick={() => handlePlay?.({ playType: Play.NEXT })} - > - Add to queue next - </DropdownMenu.Item> - <DropdownMenu.Divider /> - <DropdownMenu.Item - icon={<RiRefreshLine />} - onClick={handleRefresh} - > - Refresh - </DropdownMenu.Item> - </DropdownMenu.Dropdown> - </DropdownMenu> - </Group> - <Group - noWrap - spacing="sm" - > - <Button - compact - size="md" - sx={{ svg: { fill: isFilterApplied ? 'var(--primary-color) !important' : undefined } }} - tooltip={{ label: 'Filters' }} - variant="subtle" - onClick={handleOpenFiltersModal} - > - <RiFilterFill size="1.3rem" /> - </Button> - <DropdownMenu position="bottom-end"> - <DropdownMenu.Target> - <Button - compact - size="md" - variant="subtle" - > - <RiSettings3Fill size="1.3rem" /> - </Button> - </DropdownMenu.Target> - <DropdownMenu.Dropdown> - <DropdownMenu.Label>Display type</DropdownMenu.Label> - <DropdownMenu.Item - $isActive={display === ListDisplayType.TABLE} - value={ListDisplayType.TABLE} - onClick={handleSetViewType} - > - Table - </DropdownMenu.Item> - <DropdownMenu.Item - $isActive={display === ListDisplayType.TABLE_PAGINATED} - value={ListDisplayType.TABLE_PAGINATED} - onClick={handleSetViewType} - > - Table (paginated) - </DropdownMenu.Item> - <DropdownMenu.Divider /> - <DropdownMenu.Label>Item Size</DropdownMenu.Label> - <DropdownMenu.Item closeMenuOnClick={false}> - <Slider - defaultValue={table.rowHeight || 0} - label={null} - max={100} - min={25} - onChangeEnd={handleRowHeight} - /> - </DropdownMenu.Item> - <DropdownMenu.Label>Table Columns</DropdownMenu.Label> - <DropdownMenu.Item - closeMenuOnClick={false} - component="div" - sx={{ cursor: 'default' }} - > - <Stack> - <MultiSelect - clearable - data={SONG_TABLE_COLUMNS} - defaultValue={table?.columns.map((column) => column.column)} - width={300} - onChange={handleTableColumns} - /> - <Group position="apart"> - <Text>Auto Fit Columns</Text> - <Switch - defaultChecked={table.autoFit} - onChange={handleAutoFitColumns} - /> - </Group> - </Stack> - </DropdownMenu.Item> - </DropdownMenu.Dropdown> - </DropdownMenu> - </Group> - </Flex> - ); + <Button + compact + size="md" + sx={{ + svg: { + fill: isFilterApplied ? 'var(--primary-color) !important' : undefined, + }, + }} + tooltip={{ label: 'Filters' }} + variant="subtle" + onClick={handleOpenFiltersModal} + > + <RiFilterFill size="1.3rem" /> + </Button> + <DropdownMenu position="bottom-end"> + <DropdownMenu.Target> + <Button + compact + size="md" + variant="subtle" + > + <RiSettings3Fill size="1.3rem" /> + </Button> + </DropdownMenu.Target> + <DropdownMenu.Dropdown> + <DropdownMenu.Label>Display type</DropdownMenu.Label> + <DropdownMenu.Item + $isActive={display === ListDisplayType.TABLE} + value={ListDisplayType.TABLE} + onClick={handleSetViewType} + > + Table + </DropdownMenu.Item> + <DropdownMenu.Item + $isActive={display === ListDisplayType.TABLE_PAGINATED} + value={ListDisplayType.TABLE_PAGINATED} + onClick={handleSetViewType} + > + Table (paginated) + </DropdownMenu.Item> + <DropdownMenu.Divider /> + <DropdownMenu.Label>Item Size</DropdownMenu.Label> + <DropdownMenu.Item closeMenuOnClick={false}> + <Slider + defaultValue={table.rowHeight || 0} + label={null} + max={100} + min={25} + onChangeEnd={handleRowHeight} + /> + </DropdownMenu.Item> + <DropdownMenu.Label>Table Columns</DropdownMenu.Label> + <DropdownMenu.Item + closeMenuOnClick={false} + component="div" + sx={{ cursor: 'default' }} + > + <Stack> + <MultiSelect + clearable + data={SONG_TABLE_COLUMNS} + defaultValue={table?.columns.map((column) => column.column)} + width={300} + onChange={handleTableColumns} + /> + <Group position="apart"> + <Text>Auto Fit Columns</Text> + <Switch + defaultChecked={table.autoFit} + onChange={handleAutoFitColumns} + /> + </Group> + </Stack> + </DropdownMenu.Item> + </DropdownMenu.Dropdown> + </DropdownMenu> + </Group> + </Flex> + ); }; diff --git a/src/renderer/features/songs/components/song-list-header.tsx b/src/renderer/features/songs/components/song-list-header.tsx index 48651877..963979f4 100644 --- a/src/renderer/features/songs/components/song-list-header.tsx +++ b/src/renderer/features/songs/components/song-list-header.tsx @@ -13,112 +13,114 @@ import { useSongListContext } from '/@/renderer/features/songs/context/song-list import { useContainerQuery } from '/@/renderer/hooks'; import { queryClient } from '/@/renderer/lib/react-query'; import { - SongListFilter, - useCurrentServer, - useListStoreActions, - useSongListFilter, + SongListFilter, + useCurrentServer, + useListStoreActions, + useSongListFilter, } from '/@/renderer/store'; import { usePlayButtonBehavior } from '/@/renderer/store/settings.store'; interface SongListHeaderProps { - itemCount?: number; - tableRef: MutableRefObject<AgGridReactType | null>; - title?: string; + itemCount?: number; + tableRef: MutableRefObject<AgGridReactType | null>; + title?: string; } export const SongListHeader = ({ title, itemCount, tableRef }: SongListHeaderProps) => { - const server = useCurrentServer(); - const { id, pageKey, handlePlay } = useSongListContext(); - const filter = useSongListFilter({ id, key: pageKey }); - const { setFilter, setTablePagination } = useListStoreActions(); - const cq = useContainerQuery(); + const server = useCurrentServer(); + const { id, pageKey, handlePlay } = useSongListContext(); + const filter = useSongListFilter({ id, key: pageKey }); + const { setFilter, setTablePagination } = useListStoreActions(); + const cq = useContainerQuery(); - const handleFilterChange = useCallback( - async (filters?: SongListFilter) => { - const dataSource: IDatasource = { - getRows: async (params) => { - const limit = params.endRow - params.startRow; - const startIndex = params.startRow; + const handleFilterChange = useCallback( + async (filters?: SongListFilter) => { + const dataSource: IDatasource = { + getRows: async (params) => { + const limit = params.endRow - params.startRow; + const startIndex = params.startRow; - const pageFilters = filters || filter; + const pageFilters = filters || filter; - const query: SongListQuery = { - limit, - startIndex, - ...pageFilters, - }; + const query: SongListQuery = { + limit, + startIndex, + ...pageFilters, + }; - const queryKey = queryKeys.songs.list(server?.id || '', query); + const queryKey = queryKeys.songs.list(server?.id || '', query); - const songsRes = await queryClient.fetchQuery( - queryKey, - async ({ signal }) => - api.controller.getSongList({ - apiClientProps: { - server, - signal, + const songsRes = await queryClient.fetchQuery( + queryKey, + async ({ signal }) => + api.controller.getSongList({ + apiClientProps: { + server, + signal, + }, + query, + }), + { cacheTime: 1000 * 60 * 1 }, + ); + + params.successCallback(songsRes?.items || [], songsRes?.totalRecordCount || 0); }, - query, - }), - { cacheTime: 1000 * 60 * 1 }, - ); - - params.successCallback(songsRes?.items || [], songsRes?.totalRecordCount || 0); + rowCount: undefined, + }; + tableRef.current?.api.setDatasource(dataSource); + tableRef.current?.api.purgeInfiniteCache(); + tableRef.current?.api.ensureIndexVisible(0, 'top'); + setTablePagination({ data: { currentPage: 0 }, key: pageKey }); }, - rowCount: undefined, - }; - tableRef.current?.api.setDatasource(dataSource); - tableRef.current?.api.purgeInfiniteCache(); - tableRef.current?.api.ensureIndexVisible(0, 'top'); - setTablePagination({ data: { currentPage: 0 }, key: pageKey }); - }, - [filter, pageKey, server, setTablePagination, tableRef], - ); + [filter, pageKey, server, setTablePagination, tableRef], + ); - const handleSearch = debounce((e: ChangeEvent<HTMLInputElement>) => { - const previousSearchTerm = filter.searchTerm; - const searchTerm = e.target.value === '' ? undefined : e.target.value; - const updatedFilters = setFilter({ - data: { searchTerm }, - itemType: LibraryItem.SONG, - key: pageKey, - }) as SongListFilter; - if (previousSearchTerm !== searchTerm) handleFilterChange(updatedFilters); - }, 500); + const handleSearch = debounce((e: ChangeEvent<HTMLInputElement>) => { + const previousSearchTerm = filter.searchTerm; + const searchTerm = e.target.value === '' ? undefined : e.target.value; + const updatedFilters = setFilter({ + data: { searchTerm }, + itemType: LibraryItem.SONG, + key: pageKey, + }) as SongListFilter; + if (previousSearchTerm !== searchTerm) handleFilterChange(updatedFilters); + }, 500); - const playButtonBehavior = usePlayButtonBehavior(); + const playButtonBehavior = usePlayButtonBehavior(); - return ( - <Stack - ref={cq.ref} - spacing={0} - > - <PageHeader backgroundColor="var(--titlebar-bg)"> - <Flex - justify="space-between" - w="100%" + return ( + <Stack + ref={cq.ref} + spacing={0} > - <LibraryHeaderBar> - <LibraryHeaderBar.PlayButton - onClick={() => handlePlay?.({ playType: playButtonBehavior })} - /> - <LibraryHeaderBar.Title>{title || 'Tracks'}</LibraryHeaderBar.Title> - <LibraryHeaderBar.Badge isLoading={itemCount === null || itemCount === undefined}> - {itemCount} - </LibraryHeaderBar.Badge> - </LibraryHeaderBar> - <Group> - <SearchInput - defaultValue={filter.searchTerm} - openedWidth={cq.isMd ? 250 : cq.isSm ? 200 : 150} - onChange={handleSearch} - /> - </Group> - </Flex> - </PageHeader> - <FilterBar> - <SongListHeaderFilters tableRef={tableRef} /> - </FilterBar> - </Stack> - ); + <PageHeader backgroundColor="var(--titlebar-bg)"> + <Flex + justify="space-between" + w="100%" + > + <LibraryHeaderBar> + <LibraryHeaderBar.PlayButton + onClick={() => handlePlay?.({ playType: playButtonBehavior })} + /> + <LibraryHeaderBar.Title>{title || 'Tracks'}</LibraryHeaderBar.Title> + <LibraryHeaderBar.Badge + isLoading={itemCount === null || itemCount === undefined} + > + {itemCount} + </LibraryHeaderBar.Badge> + </LibraryHeaderBar> + <Group> + <SearchInput + defaultValue={filter.searchTerm} + openedWidth={cq.isMd ? 250 : cq.isSm ? 200 : 150} + onChange={handleSearch} + /> + </Group> + </Flex> + </PageHeader> + <FilterBar> + <SongListHeaderFilters tableRef={tableRef} /> + </FilterBar> + </Stack> + ); }; diff --git a/src/renderer/features/songs/context/song-list-context.tsx b/src/renderer/features/songs/context/song-list-context.tsx index 8e77ae2d..fe9a316a 100644 --- a/src/renderer/features/songs/context/song-list-context.tsx +++ b/src/renderer/features/songs/context/song-list-context.tsx @@ -3,16 +3,16 @@ import { ListKey } from '/@/renderer/store'; import { Play } from '/@/renderer/types'; interface SongListContextProps { - handlePlay?: (args: { initialSongId?: string; playType: Play }) => void; - id?: string; - pageKey: ListKey; + handlePlay?: (args: { initialSongId?: string; playType: Play }) => void; + id?: string; + pageKey: ListKey; } export const SongListContext = createContext<SongListContextProps>({ - pageKey: 'song', + pageKey: 'song', }); export const useSongListContext = () => { - const ctxValue = useContext(SongListContext); - return ctxValue; + const ctxValue = useContext(SongListContext); + return ctxValue; }; diff --git a/src/renderer/features/songs/queries/song-list-query.ts b/src/renderer/features/songs/queries/song-list-query.ts index 43826ea3..20adf834 100644 --- a/src/renderer/features/songs/queries/song-list-query.ts +++ b/src/renderer/features/songs/queries/song-list-query.ts @@ -6,16 +6,16 @@ import { getServerById } from '/@/renderer/store'; import type { QueryHookArgs } from '/@/renderer/lib/react-query'; export const useSongList = (args: QueryHookArgs<SongListQuery>) => { - const { query, options, serverId } = args || {}; - const server = getServerById(serverId); + const { query, options, serverId } = args || {}; + const server = getServerById(serverId); - return useQuery({ - enabled: !!server?.id, - queryFn: ({ signal }) => { - if (!server) throw new Error('Server not found'); - return controller.getSongList({ apiClientProps: { server, signal }, query }); - }, - queryKey: queryKeys.songs.list(server?.id || '', query), - ...options, - }); + return useQuery({ + enabled: !!server?.id, + queryFn: ({ signal }) => { + if (!server) throw new Error('Server not found'); + return controller.getSongList({ apiClientProps: { server, signal }, query }); + }, + queryKey: queryKeys.songs.list(server?.id || '', query), + ...options, + }); }; diff --git a/src/renderer/features/songs/routes/song-list-route.tsx b/src/renderer/features/songs/routes/song-list-route.tsx index 9d57487b..906d6984 100644 --- a/src/renderer/features/songs/routes/song-list-route.tsx +++ b/src/renderer/features/songs/routes/song-list-route.tsx @@ -12,81 +12,81 @@ import { generatePageKey, useCurrentServer, useSongListFilter } from '/@/rendere import { Play } from '/@/renderer/types'; const TrackListRoute = () => { - const tableRef = useRef<AgGridReactType | null>(null); - const server = useCurrentServer(); - const [searchParams] = useSearchParams(); - const { albumArtistId } = useParams(); - const pageKey = generatePageKey( - 'song', - albumArtistId ? `${albumArtistId}_${server?.id}` : undefined, - ); + const tableRef = useRef<AgGridReactType | null>(null); + const server = useCurrentServer(); + const [searchParams] = useSearchParams(); + const { albumArtistId } = useParams(); + const pageKey = generatePageKey( + 'song', + albumArtistId ? `${albumArtistId}_${server?.id}` : undefined, + ); - const handlePlayQueueAdd = usePlayQueueAdd(); - const songListFilter = useSongListFilter({ id: albumArtistId, key: pageKey }); - const itemCountCheck = useSongList({ - options: { - cacheTime: 1000 * 60, - staleTime: 1000 * 60, - }, - query: { - limit: 1, - startIndex: 0, - ...songListFilter, - }, - serverId: server?.id, - }); + const handlePlayQueueAdd = usePlayQueueAdd(); + const songListFilter = useSongListFilter({ id: albumArtistId, key: pageKey }); + const itemCountCheck = useSongList({ + options: { + cacheTime: 1000 * 60, + staleTime: 1000 * 60, + }, + query: { + limit: 1, + startIndex: 0, + ...songListFilter, + }, + serverId: server?.id, + }); - const itemCount = - itemCountCheck.data?.totalRecordCount === null - ? undefined - : itemCountCheck.data?.totalRecordCount; + const itemCount = + itemCountCheck.data?.totalRecordCount === null + ? undefined + : itemCountCheck.data?.totalRecordCount; - const handlePlay = useCallback( - async (args: { initialSongId?: string; playType: Play }) => { - if (!itemCount || itemCount === 0) return; - const { initialSongId, playType } = args; - const query: SongListQuery = { startIndex: 0, ...songListFilter }; + const handlePlay = useCallback( + async (args: { initialSongId?: string; playType: Play }) => { + if (!itemCount || itemCount === 0) return; + const { initialSongId, playType } = args; + const query: SongListQuery = { startIndex: 0, ...songListFilter }; - if (albumArtistId) { - handlePlayQueueAdd?.({ - byItemType: { - id: [albumArtistId], - type: LibraryItem.ALBUM_ARTIST, - }, - initialSongId, - playType, - query, - }); - } else { - handlePlayQueueAdd?.({ - byItemType: { - id: [], - type: LibraryItem.SONG, - }, - initialSongId, - playType, - query, - }); - } - }, - [albumArtistId, handlePlayQueueAdd, itemCount, songListFilter], - ); + if (albumArtistId) { + handlePlayQueueAdd?.({ + byItemType: { + id: [albumArtistId], + type: LibraryItem.ALBUM_ARTIST, + }, + initialSongId, + playType, + query, + }); + } else { + handlePlayQueueAdd?.({ + byItemType: { + id: [], + type: LibraryItem.SONG, + }, + initialSongId, + playType, + query, + }); + } + }, + [albumArtistId, handlePlayQueueAdd, itemCount, songListFilter], + ); - return ( - <AnimatedPage> - <SongListContext.Provider value={{ handlePlay, id: albumArtistId, pageKey }}> - <SongListHeader - itemCount={itemCount} - tableRef={tableRef} - title={searchParams.get('artistName') || undefined} - /> - <SongListContent - itemCount={itemCount} - tableRef={tableRef} - /> - </SongListContext.Provider> - </AnimatedPage> - ); + return ( + <AnimatedPage> + <SongListContext.Provider value={{ handlePlay, id: albumArtistId, pageKey }}> + <SongListHeader + itemCount={itemCount} + tableRef={tableRef} + title={searchParams.get('artistName') || undefined} + /> + <SongListContent + itemCount={itemCount} + tableRef={tableRef} + /> + </SongListContext.Provider> + </AnimatedPage> + ); }; export default TrackListRoute; diff --git a/src/renderer/features/titlebar/components/app-menu.tsx b/src/renderer/features/titlebar/components/app-menu.tsx index 4976e7aa..3ce8d87f 100644 --- a/src/renderer/features/titlebar/components/app-menu.tsx +++ b/src/renderer/features/titlebar/components/app-menu.tsx @@ -2,17 +2,17 @@ import { Group } from '@mantine/core'; import { openModal, closeAllModals } from '@mantine/modals'; import isElectron from 'is-electron'; import { - RiLockLine, - RiWindowFill, - RiArrowLeftSLine, - RiArrowRightSLine, - RiLayoutRightLine, - RiLayoutLeftLine, - RiEdit2Line, - RiSettings3Line, - RiServerLine, - RiGithubLine, - RiExternalLinkLine, + RiLockLine, + RiWindowFill, + RiArrowLeftSLine, + RiArrowRightSLine, + RiLayoutRightLine, + RiLayoutLeftLine, + RiEdit2Line, + RiSettings3Line, + RiServerLine, + RiGithubLine, + RiExternalLinkLine, } from 'react-icons/ri'; import { useNavigate } from 'react-router'; import { Link } from 'react-router-dom'; @@ -21,11 +21,11 @@ import { ServerList } from '/@/renderer/features/servers'; import { EditServerForm } from '/@/renderer/features/servers/components/edit-server-form'; import { AppRoute } from '/@/renderer/router/routes'; import { - useCurrentServer, - useServerList, - useAuthStoreActions, - useSidebarStore, - useAppStoreActions, + useCurrentServer, + useServerList, + useAuthStoreActions, + useSidebarStore, + useAppStoreActions, } from '/@/renderer/store'; import { ServerListItem, ServerType } from '/@/renderer/types'; import packageJson from '../../../../../package.json'; @@ -34,150 +34,157 @@ const browser = isElectron() ? window.electron.browser : null; const localSettings = isElectron() ? window.electron.localSettings : null; export const AppMenu = () => { - const navigate = useNavigate(); - const currentServer = useCurrentServer(); - const serverList = useServerList(); - const { setCurrentServer } = useAuthStoreActions(); - const { collapsed } = useSidebarStore(); - const { setSideBar } = useAppStoreActions(); + const navigate = useNavigate(); + const currentServer = useCurrentServer(); + const serverList = useServerList(); + const { setCurrentServer } = useAuthStoreActions(); + const { collapsed } = useSidebarStore(); + const { setSideBar } = useAppStoreActions(); - const handleSetCurrentServer = (server: ServerListItem) => { - navigate(AppRoute.HOME); - setCurrentServer(server); - }; + const handleSetCurrentServer = (server: ServerListItem) => { + navigate(AppRoute.HOME); + setCurrentServer(server); + }; - const handleCredentialsModal = async (server: ServerListItem) => { - let password: string | undefined; + const handleCredentialsModal = async (server: ServerListItem) => { + let password: string | undefined; - try { - if (localSettings && server.savePassword) { - password = await localSettings.passwordGet(server.id); - } - } catch (error) { - console.error(error); - } - openModal({ - children: server && ( - <EditServerForm - isUpdate - password={password} - server={server} - onCancel={closeAllModals} - /> - ), - size: 'sm', - title: `Update session for "${server.name}"`, - }); - }; + try { + if (localSettings && server.savePassword) { + password = await localSettings.passwordGet(server.id); + } + } catch (error) { + console.error(error); + } + openModal({ + children: server && ( + <EditServerForm + isUpdate + password={password} + server={server} + onCancel={closeAllModals} + /> + ), + size: 'sm', + title: `Update session for "${server.name}"`, + }); + }; - const handleManageServersModal = () => { - openModal({ - children: <ServerList />, - title: 'Manage Servers', - }); - }; + const handleManageServersModal = () => { + openModal({ + children: <ServerList />, + title: 'Manage Servers', + }); + }; - const handleBrowserDevTools = () => { - browser?.devtools(); - }; + const handleBrowserDevTools = () => { + browser?.devtools(); + }; - const handleCollapseSidebar = () => { - setSideBar({ collapsed: true }); - }; + const handleCollapseSidebar = () => { + setSideBar({ collapsed: true }); + }; - const handleExpandSidebar = () => { - setSideBar({ collapsed: false }); - }; + const handleExpandSidebar = () => { + setSideBar({ collapsed: false }); + }; - const showBrowserDevToolsButton = isElectron(); + const showBrowserDevToolsButton = isElectron(); - return ( - <> - <DropdownMenu.Item - icon={<RiArrowLeftSLine />} - onClick={() => navigate(-1)} - > - Go back - </DropdownMenu.Item> - <DropdownMenu.Item - icon={<RiArrowRightSLine />} - onClick={() => navigate(1)} - > - Go forward - </DropdownMenu.Item> - {collapsed ? ( - <DropdownMenu.Item - icon={<RiLayoutRightLine />} - onClick={handleExpandSidebar} - > - Expand sidebar - </DropdownMenu.Item> - ) : ( - <DropdownMenu.Item - icon={<RiLayoutLeftLine />} - onClick={handleCollapseSidebar} - > - Collapse sidebar - </DropdownMenu.Item> - )} - <DropdownMenu.Divider /> - <DropdownMenu.Item - component={Link} - icon={<RiSettings3Line />} - to={AppRoute.SETTINGS} - > - Settings - </DropdownMenu.Item> - <DropdownMenu.Item - icon={<RiEdit2Line />} - onClick={handleManageServersModal} - > - Manage servers - </DropdownMenu.Item> - - <DropdownMenu.Divider /> - <DropdownMenu.Label>Select a server</DropdownMenu.Label> - {Object.keys(serverList).map((serverId) => { - const server = serverList[serverId]; - const isNavidromeExpired = server.type === ServerType.NAVIDROME && !server.ndCredential; - const isJellyfinExpired = false; - const isSessionExpired = isNavidromeExpired || isJellyfinExpired; - - return ( - <DropdownMenu.Item - key={`server-${server.id}`} - $isActive={server.id === currentServer?.id} - icon={isSessionExpired ? <RiLockLine color="var(--danger-color)" /> : <RiServerLine />} - onClick={() => { - if (!isSessionExpired) return handleSetCurrentServer(server); - return handleCredentialsModal(server); - }} - > - <Group>{server.name}</Group> - </DropdownMenu.Item> - ); - })} - <DropdownMenu.Divider /> - <DropdownMenu.Item - component="a" - href="https://github.com/jeffvli/feishin/releases" - icon={<RiGithubLine />} - rightSection={<RiExternalLinkLine />} - target="_blank" - > - Version {packageJson.version} - </DropdownMenu.Item> - {showBrowserDevToolsButton && ( + return ( <> - <DropdownMenu.Divider /> - <DropdownMenu.Item - icon={<RiWindowFill />} - onClick={handleBrowserDevTools} - > - Open browser devtools - </DropdownMenu.Item> + <DropdownMenu.Item + icon={<RiArrowLeftSLine />} + onClick={() => navigate(-1)} + > + Go back + </DropdownMenu.Item> + <DropdownMenu.Item + icon={<RiArrowRightSLine />} + onClick={() => navigate(1)} + > + Go forward + </DropdownMenu.Item> + {collapsed ? ( + <DropdownMenu.Item + icon={<RiLayoutRightLine />} + onClick={handleExpandSidebar} + > + Expand sidebar + </DropdownMenu.Item> + ) : ( + <DropdownMenu.Item + icon={<RiLayoutLeftLine />} + onClick={handleCollapseSidebar} + > + Collapse sidebar + </DropdownMenu.Item> + )} + <DropdownMenu.Divider /> + <DropdownMenu.Item + component={Link} + icon={<RiSettings3Line />} + to={AppRoute.SETTINGS} + > + Settings + </DropdownMenu.Item> + <DropdownMenu.Item + icon={<RiEdit2Line />} + onClick={handleManageServersModal} + > + Manage servers + </DropdownMenu.Item> + + <DropdownMenu.Divider /> + <DropdownMenu.Label>Select a server</DropdownMenu.Label> + {Object.keys(serverList).map((serverId) => { + const server = serverList[serverId]; + const isNavidromeExpired = + server.type === ServerType.NAVIDROME && !server.ndCredential; + const isJellyfinExpired = false; + const isSessionExpired = isNavidromeExpired || isJellyfinExpired; + + return ( + <DropdownMenu.Item + key={`server-${server.id}`} + $isActive={server.id === currentServer?.id} + icon={ + isSessionExpired ? ( + <RiLockLine color="var(--danger-color)" /> + ) : ( + <RiServerLine /> + ) + } + onClick={() => { + if (!isSessionExpired) return handleSetCurrentServer(server); + return handleCredentialsModal(server); + }} + > + <Group>{server.name}</Group> + </DropdownMenu.Item> + ); + })} + <DropdownMenu.Divider /> + <DropdownMenu.Item + component="a" + href="https://github.com/jeffvli/feishin/releases" + icon={<RiGithubLine />} + rightSection={<RiExternalLinkLine />} + target="_blank" + > + Version {packageJson.version} + </DropdownMenu.Item> + {showBrowserDevToolsButton && ( + <> + <DropdownMenu.Divider /> + <DropdownMenu.Item + icon={<RiWindowFill />} + onClick={handleBrowserDevTools} + > + Open browser devtools + </DropdownMenu.Item> + </> + )} </> - )} - </> - ); + ); }; diff --git a/src/renderer/features/titlebar/components/titlebar.tsx b/src/renderer/features/titlebar/components/titlebar.tsx index 72b89333..4e512e31 100644 --- a/src/renderer/features/titlebar/components/titlebar.tsx +++ b/src/renderer/features/titlebar/components/titlebar.tsx @@ -4,19 +4,19 @@ import styled from 'styled-components'; import { WindowControls } from '../../window-controls'; interface TitlebarProps { - children?: ReactNode; + children?: ReactNode; } const TitlebarContainer = styled.div` - display: flex; - flex-direction: row; - align-items: center; - justify-content: space-between; - color: var(--titlebar-fg); + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + color: var(--titlebar-fg); - button { - -webkit-app-region: no-drag; - } + button { + -webkit-app-region: no-drag; + } `; // const Left = styled.div` @@ -37,27 +37,27 @@ const TitlebarContainer = styled.div` // `; const Right = styled.div` - display: flex; - flex: 1/3; - justify-content: center; - height: 100%; + display: flex; + flex: 1/3; + justify-content: center; + height: 100%; `; export const Titlebar = ({ children }: TitlebarProps) => { - return ( - <> - <TitlebarContainer> - <Right> - {children} - <Group spacing="xs"> - <WindowControls /> - </Group> - </Right> - </TitlebarContainer> - </> - ); + return ( + <> + <TitlebarContainer> + <Right> + {children} + <Group spacing="xs"> + <WindowControls /> + </Group> + </Right> + </TitlebarContainer> + </> + ); }; Titlebar.defaultProps = { - children: undefined, + children: undefined, }; diff --git a/src/renderer/features/users/queries/user-list-query.ts b/src/renderer/features/users/queries/user-list-query.ts index 61b2e2dd..7caef8cc 100644 --- a/src/renderer/features/users/queries/user-list-query.ts +++ b/src/renderer/features/users/queries/user-list-query.ts @@ -6,16 +6,16 @@ import { api } from '/@/renderer/api'; import type { QueryHookArgs } from '/@/renderer/lib/react-query'; export const useUserList = (args: QueryHookArgs<UserListQuery>) => { - const { query, serverId, options } = args || {}; - const server = getServerById(serverId); + const { query, serverId, options } = args || {}; + const server = getServerById(serverId); - return useQuery({ - enabled: !!server, - queryFn: ({ signal }) => { - if (!server) throw new Error('Server not found'); - api.controller.getUserList({ apiClientProps: { server, signal }, query }); - }, - queryKey: queryKeys.users.list(server?.id || '', query), - ...options, - }); + return useQuery({ + enabled: !!server, + queryFn: ({ signal }) => { + if (!server) throw new Error('Server not found'); + api.controller.getUserList({ apiClientProps: { server, signal }, query }); + }, + queryKey: queryKeys.users.list(server?.id || '', query), + ...options, + }); }; diff --git a/src/renderer/features/window-controls/components/window-controls.tsx b/src/renderer/features/window-controls/components/window-controls.tsx index 50ad2857..e90b43ef 100644 --- a/src/renderer/features/window-controls/components/window-controls.tsx +++ b/src/renderer/features/window-controls/components/window-controls.tsx @@ -6,33 +6,33 @@ import styled from 'styled-components'; const browser = isElectron() ? window.electron.browser : null; interface WindowControlsProps { - style?: 'macos' | 'windows' | 'linux'; + style?: 'macos' | 'windows' | 'linux'; } const WindowsButtonGroup = styled.div` - display: flex; - width: 130px; - height: 100%; - -webkit-app-region: no-drag; + display: flex; + width: 130px; + height: 100%; + -webkit-app-region: no-drag; `; export const WindowsButton = styled.div<{ $exit?: boolean }>` - display: flex; - flex: 1; - align-items: center; - justify-content: center; - -webkit-app-region: no-drag; - width: 50px; - height: 65px; + display: flex; + flex: 1; + align-items: center; + justify-content: center; + -webkit-app-region: no-drag; + width: 50px; + height: 65px; - img { - width: 35%; - height: 50%; - } + img { + width: 35%; + height: 50%; + } - &:hover { - background: ${({ $exit }) => ($exit ? 'var(--danger-color)' : 'rgba(125, 125, 125, 30%)')}; - } + &:hover { + background: ${({ $exit }) => ($exit ? 'var(--danger-color)' : 'rgba(125, 125, 125, 30%)')}; + } `; const close = () => browser.exit(); @@ -44,54 +44,54 @@ const maximize = () => browser.maximize(); const unmaximize = () => browser.unmaximize(); export const WindowControls = ({ style }: WindowControlsProps) => { - const [max, setMax] = useState(false); + const [max, setMax] = useState(false); - const handleMinimize = () => minimize(); + const handleMinimize = () => minimize(); - const handleMaximize = () => { - if (max) { - unmaximize(); - } else { - maximize(); - } - setMax(!max); - }; + const handleMaximize = () => { + if (max) { + unmaximize(); + } else { + maximize(); + } + setMax(!max); + }; - const handleClose = () => close(); + const handleClose = () => close(); - return ( - <> - {isElectron() && ( + return ( <> - {style === 'windows' && ( - <WindowsButtonGroup> - <WindowsButton - role="button" - onClick={handleMinimize} - > - <RiSubtractLine size={19} /> - </WindowsButton> - <WindowsButton - role="button" - onClick={handleMaximize} - > - <RiCheckboxBlankLine size={13} /> - </WindowsButton> - <WindowsButton - $exit - role="button" - onClick={handleClose} - > - <RiCloseLine size={19} /> - </WindowsButton> - </WindowsButtonGroup> - )} + {isElectron() && ( + <> + {style === 'windows' && ( + <WindowsButtonGroup> + <WindowsButton + role="button" + onClick={handleMinimize} + > + <RiSubtractLine size={19} /> + </WindowsButton> + <WindowsButton + role="button" + onClick={handleMaximize} + > + <RiCheckboxBlankLine size={13} /> + </WindowsButton> + <WindowsButton + $exit + role="button" + onClick={handleClose} + > + <RiCloseLine size={19} /> + </WindowsButton> + </WindowsButtonGroup> + )} + </> + )} </> - )} - </> - ); + ); }; WindowControls.defaultProps = { - style: 'windows', + style: 'windows', }; diff --git a/src/renderer/hooks/use-container-query.ts b/src/renderer/hooks/use-container-query.ts index 10768cb5..3cf02732 100644 --- a/src/renderer/hooks/use-container-query.ts +++ b/src/renderer/hooks/use-container-query.ts @@ -1,21 +1,21 @@ import { useElementSize } from '@mantine/hooks'; interface UseContainerQueryProps { - lg?: number; - md?: number; - sm?: number; - xl?: number; + lg?: number; + md?: number; + sm?: number; + xl?: number; } export const useContainerQuery = (props?: UseContainerQueryProps) => { - const { lg, md, sm, xl } = props || {}; - const { ref, width, height } = useElementSize(); + const { lg, md, sm, xl } = props || {}; + const { ref, width, height } = useElementSize(); - const isXs = width >= 0; - const isSm = width >= (sm || 600); - const isMd = width >= (md || 768); - const isLg = width >= (lg || 1200); - const isXl = width >= (xl || 1500); + const isXs = width >= 0; + const isSm = width >= (sm || 600); + const isMd = width >= (md || 768); + const isLg = width >= (lg || 1200); + const isXl = width >= (xl || 1500); - return { height, isLg, isMd, isSm, isXl, isXs, ref, width }; + return { height, isLg, isMd, isSm, isXl, isXs, ref, width }; }; diff --git a/src/renderer/hooks/use-fast-average-color.tsx b/src/renderer/hooks/use-fast-average-color.tsx index 214b5df4..158d286e 100644 --- a/src/renderer/hooks/use-fast-average-color.tsx +++ b/src/renderer/hooks/use-fast-average-color.tsx @@ -2,41 +2,40 @@ import { useEffect, useState } from 'react'; import { FastAverageColor } from 'fast-average-color'; export const useFastAverageColor = ( - src?: string | null, - srcLoaded?: boolean, - aglorithm?: 'dominant' | 'simple' | 'sqrt', + src?: string | null, + srcLoaded?: boolean, + aglorithm?: 'dominant' | 'simple' | 'sqrt', ) => { - const [color, setColor] = useState<string | undefined>(undefined); + const [color, setColor] = useState<string | undefined>(undefined); - useEffect(() => { - const fac = new FastAverageColor(); + useEffect(() => { + const fac = new FastAverageColor(); - if (src && srcLoaded) { - fac - .getColorAsync(src, { - algorithm: aglorithm || 'dominant', - ignoredColor: [ - [255, 255, 255, 255, 55], // White - [0, 0, 0, 255, 20], // Black - [0, 0, 0, 0, 20], // Transparent - ], - mode: 'speed', - }) - .then((color) => { - return setColor(color.rgb); - }) - .catch((e) => { - console.log('Error fetching average color', e); - return setColor('rgba(0, 0, 0, 0)'); - }); - } else if (srcLoaded) { - return setColor('var(--placeholder-bg)'); - } + if (src && srcLoaded) { + fac.getColorAsync(src, { + algorithm: aglorithm || 'dominant', + ignoredColor: [ + [255, 255, 255, 255, 55], // White + [0, 0, 0, 255, 20], // Black + [0, 0, 0, 0, 20], // Transparent + ], + mode: 'speed', + }) + .then((color) => { + return setColor(color.rgb); + }) + .catch((e) => { + console.log('Error fetching average color', e); + return setColor('rgba(0, 0, 0, 0)'); + }); + } else if (srcLoaded) { + return setColor('var(--placeholder-bg)'); + } - return () => { - fac.destroy(); - }; - }, [aglorithm, srcLoaded, src]); + return () => { + fac.destroy(); + }; + }, [aglorithm, srcLoaded, src]); - return color; + return color; }; diff --git a/src/renderer/hooks/use-hide-scrollbar.ts b/src/renderer/hooks/use-hide-scrollbar.ts index 18a0a2f0..7f3f5712 100644 --- a/src/renderer/hooks/use-hide-scrollbar.ts +++ b/src/renderer/hooks/use-hide-scrollbar.ts @@ -2,24 +2,24 @@ import { useEffect, useState } from 'react'; import { useTimeout } from '@mantine/hooks'; export const useHideScrollbar = (timeout: number) => { - const [hideScrollbar, setHideScrollbar] = useState(false); - const { start, clear } = useTimeout(() => setHideScrollbar(true), timeout); + const [hideScrollbar, setHideScrollbar] = useState(false); + const { start, clear } = useTimeout(() => setHideScrollbar(true), timeout); - // Automatically hide the scrollbar after the timeout duration - useEffect(() => { - start(); - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); + // Automatically hide the scrollbar after the timeout duration + useEffect(() => { + start(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); - const hideScrollbarElementProps = { - onMouseEnter: () => { - setHideScrollbar(false); - clear(); - }, - onMouseLeave: () => { - start(); - }, - }; + const hideScrollbarElementProps = { + onMouseEnter: () => { + setHideScrollbar(false); + clear(); + }, + onMouseLeave: () => { + start(); + }, + }; - return { hideScrollbarElementProps, isScrollbarHidden: hideScrollbar }; + return { hideScrollbarElementProps, isScrollbarHidden: hideScrollbar }; }; diff --git a/src/renderer/hooks/use-is-mounted.ts b/src/renderer/hooks/use-is-mounted.ts index 7b3aafa4..04d1a39a 100644 --- a/src/renderer/hooks/use-is-mounted.ts +++ b/src/renderer/hooks/use-is-mounted.ts @@ -1,11 +1,11 @@ import { useEffect, useState } from 'react'; export const useIsMounted = () => { - const [isMounted, setIsMounted] = useState(false); + const [isMounted, setIsMounted] = useState(false); - useEffect(() => { - setIsMounted(true); - }, []); + useEffect(() => { + setIsMounted(true); + }, []); - return isMounted; + return isMounted; }; diff --git a/src/renderer/hooks/use-should-pad-titlebar.tsx b/src/renderer/hooks/use-should-pad-titlebar.tsx index b83424cd..b880ce76 100644 --- a/src/renderer/hooks/use-should-pad-titlebar.tsx +++ b/src/renderer/hooks/use-should-pad-titlebar.tsx @@ -5,19 +5,19 @@ import { useSidebarRightExpanded, useGeneralSettings, useWindowSettings } from ' import { Platform } from '/@/renderer/types'; export const useShouldPadTitlebar = () => { - const location = useLocation(); - const isSidebarExpanded = useSidebarRightExpanded(); - const isQueuePage = location.pathname === AppRoute.NOW_PLAYING; - const { sideQueueType } = useGeneralSettings(); - const { windowBarStyle } = useWindowSettings(); + const location = useLocation(); + const isSidebarExpanded = useSidebarRightExpanded(); + const isQueuePage = location.pathname === AppRoute.NOW_PLAYING; + const { sideQueueType } = useGeneralSettings(); + const { windowBarStyle } = useWindowSettings(); - const conditions = [ - isElectron(), - windowBarStyle === Platform.WEB, - !(isSidebarExpanded && sideQueueType === 'sideQueue' && !isQueuePage), - ]; + const conditions = [ + isElectron(), + windowBarStyle === Platform.WEB, + !(isSidebarExpanded && sideQueueType === 'sideQueue' && !isQueuePage), + ]; - const shouldPadTitlebar = conditions.every((condition) => condition); + const shouldPadTitlebar = conditions.every((condition) => condition); - return shouldPadTitlebar; + return shouldPadTitlebar; }; diff --git a/src/renderer/hooks/use-theme.ts b/src/renderer/hooks/use-theme.ts index 8a636f2e..3516d13e 100644 --- a/src/renderer/hooks/use-theme.ts +++ b/src/renderer/hooks/use-theme.ts @@ -3,40 +3,40 @@ import { useSettingsStore } from '/@/renderer/store/settings.store'; import { AppTheme } from '/@/renderer/themes/types'; export const THEME_DATA = [ - { label: 'Default Dark', type: 'dark', value: AppTheme.DEFAULT_DARK }, - { label: 'Default Light', type: 'light', value: AppTheme.DEFAULT_LIGHT }, + { label: 'Default Dark', type: 'dark', value: AppTheme.DEFAULT_DARK }, + { label: 'Default Light', type: 'light', value: AppTheme.DEFAULT_LIGHT }, ]; export const useTheme = () => { - const getCurrentTheme = () => window.matchMedia('(prefers-color-scheme: dark)').matches; - const [isDarkTheme, setIsDarkTheme] = useState(getCurrentTheme()); - const { followSystemTheme, theme, themeDark, themeLight } = useSettingsStore( - (state) => state.general, - ); + const getCurrentTheme = () => window.matchMedia('(prefers-color-scheme: dark)').matches; + const [isDarkTheme, setIsDarkTheme] = useState(getCurrentTheme()); + const { followSystemTheme, theme, themeDark, themeLight } = useSettingsStore( + (state) => state.general, + ); - const mqListener = (e: any) => { - setIsDarkTheme(e.matches); - }; + const mqListener = (e: any) => { + setIsDarkTheme(e.matches); + }; - const getTheme = () => { - if (followSystemTheme) { - return isDarkTheme ? themeDark : themeLight; - } + const getTheme = () => { + if (followSystemTheme) { + return isDarkTheme ? themeDark : themeLight; + } - return theme; - }; + return theme; + }; - const appTheme = getTheme(); + const appTheme = getTheme(); - useEffect(() => { - const darkThemeMq = window.matchMedia('(prefers-color-scheme: dark)'); - darkThemeMq.addListener(mqListener); - return () => darkThemeMq.removeListener(mqListener); - }, []); + useEffect(() => { + const darkThemeMq = window.matchMedia('(prefers-color-scheme: dark)'); + darkThemeMq.addListener(mqListener); + return () => darkThemeMq.removeListener(mqListener); + }, []); - useEffect(() => { - document.body.setAttribute('data-theme', appTheme); - }, [appTheme]); + useEffect(() => { + document.body.setAttribute('data-theme', appTheme); + }, [appTheme]); - return THEME_DATA.find((t) => t.value === appTheme)?.type || 'dark'; + return THEME_DATA.find((t) => t.value === appTheme)?.type || 'dark'; }; diff --git a/src/renderer/index.tsx b/src/renderer/index.tsx index 06c09124..8c3e9678 100644 --- a/src/renderer/index.tsx +++ b/src/renderer/index.tsx @@ -8,11 +8,11 @@ const container = document.getElementById('root')! as HTMLElement; const root = createRoot(container); root.render( - <QueryClientProvider client={queryClient}> - <Notifications - containerWidth="300px" - position="bottom-center" - /> - <App /> - </QueryClientProvider>, + <QueryClientProvider client={queryClient}> + <Notifications + containerWidth="300px" + position="bottom-center" + /> + <App /> + </QueryClientProvider>, ); diff --git a/src/renderer/layouts/auth-layout.tsx b/src/renderer/layouts/auth-layout.tsx index b05c618d..29362476 100644 --- a/src/renderer/layouts/auth-layout.tsx +++ b/src/renderer/layouts/auth-layout.tsx @@ -3,29 +3,29 @@ import styled from 'styled-components'; import { Titlebar } from '/@/renderer/features/titlebar/components/titlebar'; const WindowsTitlebarContainer = styled.div` - position: absolute; - z-index: 1000; - display: flex; - width: 100%; - height: 50px; - user-select: none; - -webkit-app-region: drag; + position: absolute; + z-index: 1000; + display: flex; + width: 100%; + height: 50px; + user-select: none; + -webkit-app-region: drag; `; const ContentContainer = styled.div` - display: flex; - height: 100%; + display: flex; + height: 100%; `; export const AuthLayout = () => { - return ( - <> - <WindowsTitlebarContainer> - <Titlebar /> - </WindowsTitlebarContainer> - <ContentContainer> - <Outlet /> - </ContentContainer> - </> - ); + return ( + <> + <WindowsTitlebarContainer> + <Titlebar /> + </WindowsTitlebarContainer> + <ContentContainer> + <Outlet /> + </ContentContainer> + </> + ); }; diff --git a/src/renderer/layouts/default-layout.tsx b/src/renderer/layouts/default-layout.tsx index 0cab9056..1338d22c 100644 --- a/src/renderer/layouts/default-layout.tsx +++ b/src/renderer/layouts/default-layout.tsx @@ -2,11 +2,11 @@ import { lazy } from 'react'; import isElectron from 'is-electron'; import styled from 'styled-components'; import { - useWindowSettings, - useSettingsStore, - useHotkeySettings, - useGeneralSettings, - useSettingsStoreActions, + useWindowSettings, + useSettingsStore, + useHotkeySettings, + useGeneralSettings, + useSettingsStoreActions, } from '/@/renderer/store/settings.store'; import { Platform, PlaybackType } from '/@/renderer/types'; import { MainContent } from '/@/renderer/layouts/default-layout/main-content'; @@ -16,86 +16,86 @@ import { CommandPalette } from '/@/renderer/features/search/components/command-p import { useCommandPalette } from '/@/renderer/store'; if (!isElectron()) { - useSettingsStore.getState().actions.setSettings({ - playback: { - ...useSettingsStore.getState().playback, - type: PlaybackType.WEB, - }, - }); + useSettingsStore.getState().actions.setSettings({ + playback: { + ...useSettingsStore.getState().playback, + type: PlaybackType.WEB, + }, + }); } const Layout = styled.div<{ windowBarStyle: Platform }>` - display: grid; - grid-template-areas: - 'window-bar' - 'main-content' - 'player'; - grid-template-rows: ${(props) => - props.windowBarStyle === Platform.WINDOWS || props.windowBarStyle === Platform.MACOS - ? '30px calc(100vh - 120px) 90px' - : '0px calc(100vh - 90px) 90px'}; - grid-template-columns: 1fr; - gap: 0; - height: 100%; - overflow: hidden; + display: grid; + grid-template-areas: + 'window-bar' + 'main-content' + 'player'; + grid-template-rows: ${(props) => + props.windowBarStyle === Platform.WINDOWS || props.windowBarStyle === Platform.MACOS + ? '30px calc(100vh - 120px) 90px' + : '0px calc(100vh - 90px) 90px'}; + grid-template-columns: 1fr; + gap: 0; + height: 100%; + overflow: hidden; `; const WindowBar = lazy(() => - import('/@/renderer/layouts/window-bar').then((module) => ({ - default: module.WindowBar, - })), + import('/@/renderer/layouts/window-bar').then((module) => ({ + default: module.WindowBar, + })), ); interface DefaultLayoutProps { - shell?: boolean; + shell?: boolean; } export const DefaultLayout = ({ shell }: DefaultLayoutProps) => { - const { windowBarStyle } = useWindowSettings(); - const { opened, ...handlers } = useCommandPalette(); - const { bindings } = useHotkeySettings(); - const localSettings = isElectron() ? window.electron.localSettings : null; - const settings = useGeneralSettings(); - const { setSettings } = useSettingsStoreActions(); + const { windowBarStyle } = useWindowSettings(); + const { opened, ...handlers } = useCommandPalette(); + const { bindings } = useHotkeySettings(); + const localSettings = isElectron() ? window.electron.localSettings : null; + const settings = useGeneralSettings(); + const { setSettings } = useSettingsStoreActions(); - const updateZoom = (increase: number) => { - const newVal = settings.zoomFactor + increase; - if (newVal > 300 || newVal < 50 || !isElectron()) return; - setSettings({ - general: { - ...settings, - zoomFactor: newVal, - }, - }); + const updateZoom = (increase: number) => { + const newVal = settings.zoomFactor + increase; + if (newVal > 300 || newVal < 50 || !isElectron()) return; + setSettings({ + general: { + ...settings, + zoomFactor: newVal, + }, + }); + localSettings?.setZoomFactor(settings.zoomFactor); + }; localSettings?.setZoomFactor(settings.zoomFactor); - }; - localSettings?.setZoomFactor(settings.zoomFactor); - const zoomHotkeys: HotkeyItem[] = [ - [bindings.zoomIn.hotkey, () => updateZoom(5)], - [bindings.zoomOut.hotkey, () => updateZoom(-5)], - ]; + const zoomHotkeys: HotkeyItem[] = [ + [bindings.zoomIn.hotkey, () => updateZoom(5)], + [bindings.zoomOut.hotkey, () => updateZoom(-5)], + ]; - useHotkeys([ - [bindings.globalSearch.hotkey, () => handlers.open()], - ...(isElectron() ? zoomHotkeys : []), - ]); + useHotkeys([ + [bindings.globalSearch.hotkey, () => handlers.open()], + ...(isElectron() ? zoomHotkeys : []), + ]); - return ( - <> - <Layout - id="default-layout" - windowBarStyle={windowBarStyle} - > - {windowBarStyle !== Platform.WEB && <WindowBar />} - <MainContent shell={shell} /> - <PlayerBar /> - </Layout> - <CommandPalette modalProps={{ handlers, opened }} /> - </> - ); + return ( + <> + <Layout + id="default-layout" + windowBarStyle={windowBarStyle} + > + {windowBarStyle !== Platform.WEB && <WindowBar />} + <MainContent shell={shell} /> + <PlayerBar /> + </Layout> + <CommandPalette modalProps={{ handlers, opened }} /> + </> + ); }; DefaultLayout.defaultProps = { - shell: false, + shell: false, }; diff --git a/src/renderer/layouts/default-layout/full-screen-overlay.tsx b/src/renderer/layouts/default-layout/full-screen-overlay.tsx index 1803d356..ca09edbf 100644 --- a/src/renderer/layouts/default-layout/full-screen-overlay.tsx +++ b/src/renderer/layouts/default-layout/full-screen-overlay.tsx @@ -3,11 +3,11 @@ import { FullScreenPlayer } from '/@/renderer/features/player/components/full-sc import { useFullScreenPlayerStore } from '/@/renderer/store'; export const FullScreenOverlay = () => { - const { expanded: isFullScreenPlayerExpanded } = useFullScreenPlayerStore(); + const { expanded: isFullScreenPlayerExpanded } = useFullScreenPlayerStore(); - return ( - <AnimatePresence initial={false}> - {isFullScreenPlayerExpanded && <FullScreenPlayer />} - </AnimatePresence> - ); + return ( + <AnimatePresence initial={false}> + {isFullScreenPlayerExpanded && <FullScreenPlayer />} + </AnimatePresence> + ); }; diff --git a/src/renderer/layouts/default-layout/left-sidebar.tsx b/src/renderer/layouts/default-layout/left-sidebar.tsx index d84b1241..aaa9bd2c 100644 --- a/src/renderer/layouts/default-layout/left-sidebar.tsx +++ b/src/renderer/layouts/default-layout/left-sidebar.tsx @@ -6,33 +6,33 @@ import { Sidebar } from '/@/renderer/features/sidebar/components/sidebar'; import { useSidebarStore } from '/@/renderer/store'; const SidebarContainer = styled.aside` - position: relative; - grid-area: sidebar; - background: var(--sidebar-bg); - border-right: var(--sidebar-border); + position: relative; + grid-area: sidebar; + background: var(--sidebar-bg); + border-right: var(--sidebar-border); `; interface LeftSidebarProps { - isResizing: boolean; - startResizing: (direction: 'left' | 'right') => void; + isResizing: boolean; + startResizing: (direction: 'left' | 'right') => void; } export const LeftSidebar = ({ isResizing, startResizing }: LeftSidebarProps) => { - const sidebarRef = useRef<HTMLDivElement | null>(null); - const { collapsed } = useSidebarStore(); + const sidebarRef = useRef<HTMLDivElement | null>(null); + const { collapsed } = useSidebarStore(); - return ( - <SidebarContainer id="sidebar"> - <ResizeHandle - ref={sidebarRef} - isResizing={isResizing} - placement="right" - onMouseDown={(e) => { - e.preventDefault(); - startResizing('left'); - }} - /> - {collapsed ? <CollapsedSidebar /> : <Sidebar />} - </SidebarContainer> - ); + return ( + <SidebarContainer id="sidebar"> + <ResizeHandle + ref={sidebarRef} + isResizing={isResizing} + placement="right" + onMouseDown={(e) => { + e.preventDefault(); + startResizing('left'); + }} + /> + {collapsed ? <CollapsedSidebar /> : <Sidebar />} + </SidebarContainer> + ); }; diff --git a/src/renderer/layouts/default-layout/main-content.tsx b/src/renderer/layouts/default-layout/main-content.tsx index 4b731626..0e02a951 100644 --- a/src/renderer/layouts/default-layout/main-content.tsx +++ b/src/renderer/layouts/default-layout/main-content.tsx @@ -12,113 +12,117 @@ import { RightSidebar } from '/@/renderer/layouts/default-layout/right-sidebar'; import { Spinner } from '/@/renderer/components'; const SideDrawerQueue = lazy(() => - import('/@/renderer/layouts/default-layout/side-drawer-queue').then((module) => ({ - default: module.SideDrawerQueue, - })), + import('/@/renderer/layouts/default-layout/side-drawer-queue').then((module) => ({ + default: module.SideDrawerQueue, + })), ); const MINIMUM_SIDEBAR_WIDTH = 260; const MainContentContainer = styled.div<{ - leftSidebarWidth: string; - rightExpanded?: boolean; - rightSidebarWidth?: string; - shell?: boolean; - sidebarCollapsed?: boolean; + leftSidebarWidth: string; + rightExpanded?: boolean; + rightSidebarWidth?: string; + shell?: boolean; + sidebarCollapsed?: boolean; }>` - position: relative; - display: ${(props) => (props.shell ? 'flex' : 'grid')}; - grid-area: main-content; - grid-template-areas: 'sidebar . right-sidebar'; - grid-template-rows: 1fr; - grid-template-columns: ${(props) => (props.sidebarCollapsed ? '80px' : props.leftSidebarWidth)} 1fr ${( - props, - ) => props.rightExpanded && props.rightSidebarWidth}; + position: relative; + display: ${(props) => (props.shell ? 'flex' : 'grid')}; + grid-area: main-content; + grid-template-areas: 'sidebar . right-sidebar'; + grid-template-rows: 1fr; + grid-template-columns: ${(props) => (props.sidebarCollapsed ? '80px' : props.leftSidebarWidth)} 1fr ${( + props, + ) => props.rightExpanded && props.rightSidebarWidth}; - gap: 0; - background: var(--main-bg); + gap: 0; + background: var(--main-bg); `; export const MainContent = ({ shell }: { shell?: boolean }) => { - const location = useLocation(); - const { collapsed, leftWidth, rightWidth, rightExpanded } = useSidebarStore(); - const { setSideBar } = useAppStoreActions(); - const { sideQueueType, showQueueDrawerButton } = useGeneralSettings(); - const [isResizing, setIsResizing] = useState(false); - const [isResizingRight, setIsResizingRight] = useState(false); + const location = useLocation(); + const { collapsed, leftWidth, rightWidth, rightExpanded } = useSidebarStore(); + const { setSideBar } = useAppStoreActions(); + const { sideQueueType, showQueueDrawerButton } = useGeneralSettings(); + const [isResizing, setIsResizing] = useState(false); + const [isResizingRight, setIsResizingRight] = useState(false); - const showSideQueue = rightExpanded && location.pathname !== AppRoute.NOW_PLAYING; - const rightSidebarRef = useRef<HTMLDivElement | null>(null); + const showSideQueue = rightExpanded && location.pathname !== AppRoute.NOW_PLAYING; + const rightSidebarRef = useRef<HTMLDivElement | null>(null); - const startResizing = useCallback((position: 'left' | 'right') => { - if (position === 'left') return setIsResizing(true); - return setIsResizingRight(true); - }, []); + const startResizing = useCallback((position: 'left' | 'right') => { + if (position === 'left') return setIsResizing(true); + return setIsResizingRight(true); + }, []); - const stopResizing = useCallback(() => { - setIsResizing(false); - setIsResizingRight(false); - }, []); + const stopResizing = useCallback(() => { + setIsResizing(false); + setIsResizingRight(false); + }, []); - const resize = useCallback( - (mouseMoveEvent: any) => { - if (isResizing) { - const width = mouseMoveEvent.clientX; - const constrainedWidth = `${constrainSidebarWidth(width)}px`; + const resize = useCallback( + (mouseMoveEvent: any) => { + if (isResizing) { + const width = mouseMoveEvent.clientX; + const constrainedWidth = `${constrainSidebarWidth(width)}px`; - if (width < MINIMUM_SIDEBAR_WIDTH - 100) { - setSideBar({ collapsed: true }); - } else { - setSideBar({ collapsed: false, leftWidth: constrainedWidth }); - } - } else if (isResizingRight) { - const start = Number(rightWidth.split('px')[0]); - const { left } = rightSidebarRef!.current!.getBoundingClientRect(); - const width = `${constrainRightSidebarWidth(start + left - mouseMoveEvent.clientX)}px`; - setSideBar({ rightWidth: width }); - } - }, - [isResizing, isResizingRight, setSideBar, rightWidth], - ); + if (width < MINIMUM_SIDEBAR_WIDTH - 100) { + setSideBar({ collapsed: true }); + } else { + setSideBar({ collapsed: false, leftWidth: constrainedWidth }); + } + } else if (isResizingRight) { + const start = Number(rightWidth.split('px')[0]); + const { left } = rightSidebarRef!.current!.getBoundingClientRect(); + const width = `${constrainRightSidebarWidth( + start + left - mouseMoveEvent.clientX, + )}px`; + setSideBar({ rightWidth: width }); + } + }, + [isResizing, isResizingRight, setSideBar, rightWidth], + ); - const throttledResize = useMemo(() => throttle(resize, 50), [resize]); + const throttledResize = useMemo(() => throttle(resize, 50), [resize]); - useEffect(() => { - window.addEventListener('mousemove', throttledResize); - window.addEventListener('mouseup', stopResizing); - return () => { - window.removeEventListener('mousemove', throttledResize); - window.removeEventListener('mouseup', stopResizing); - }; - }, [throttledResize, stopResizing]); + useEffect(() => { + window.addEventListener('mousemove', throttledResize); + window.addEventListener('mouseup', stopResizing); + return () => { + window.removeEventListener('mousemove', throttledResize); + window.removeEventListener('mouseup', stopResizing); + }; + }, [throttledResize, stopResizing]); - return ( - <MainContentContainer - id="main-content" - leftSidebarWidth={leftWidth} - rightExpanded={showSideQueue && sideQueueType === 'sideQueue'} - rightSidebarWidth={rightWidth} - shell={shell} - sidebarCollapsed={collapsed} - > - {!shell && ( - <> - <Suspense fallback={<></>}>{showQueueDrawerButton && <SideDrawerQueue />}</Suspense> - <FullScreenOverlay /> - <LeftSidebar - isResizing={isResizing} - startResizing={startResizing} - /> - <RightSidebar - ref={rightSidebarRef} - isResizing={isResizingRight} - startResizing={startResizing} - /> - </> - )} - <Suspense fallback={<Spinner container />}> - <Outlet /> - </Suspense> - </MainContentContainer> - ); + return ( + <MainContentContainer + id="main-content" + leftSidebarWidth={leftWidth} + rightExpanded={showSideQueue && sideQueueType === 'sideQueue'} + rightSidebarWidth={rightWidth} + shell={shell} + sidebarCollapsed={collapsed} + > + {!shell && ( + <> + <Suspense fallback={<></>}> + {showQueueDrawerButton && <SideDrawerQueue />} + </Suspense> + <FullScreenOverlay /> + <LeftSidebar + isResizing={isResizing} + startResizing={startResizing} + /> + <RightSidebar + ref={rightSidebarRef} + isResizing={isResizingRight} + startResizing={startResizing} + /> + </> + )} + <Suspense fallback={<Spinner container />}> + <Outlet /> + </Suspense> + </MainContentContainer> + ); }; diff --git a/src/renderer/layouts/default-layout/player-bar.tsx b/src/renderer/layouts/default-layout/player-bar.tsx index 29cc2f23..9b9a3506 100644 --- a/src/renderer/layouts/default-layout/player-bar.tsx +++ b/src/renderer/layouts/default-layout/player-bar.tsx @@ -2,15 +2,15 @@ import styled from 'styled-components'; import { Playerbar } from '/@/renderer/features/player'; const PlayerbarContainer = styled.footer` - z-index: 200; - grid-area: player; - background: var(--playerbar-bg); + z-index: 200; + grid-area: player; + background: var(--playerbar-bg); `; export const PlayerBar = () => { - return ( - <PlayerbarContainer id="player-bar"> - <Playerbar /> - </PlayerbarContainer> - ); + return ( + <PlayerbarContainer id="player-bar"> + <Playerbar /> + </PlayerbarContainer> + ); }; diff --git a/src/renderer/layouts/default-layout/right-sidebar.tsx b/src/renderer/layouts/default-layout/right-sidebar.tsx index 49ceb827..946b9637 100644 --- a/src/renderer/layouts/default-layout/right-sidebar.tsx +++ b/src/renderer/layouts/default-layout/right-sidebar.tsx @@ -9,134 +9,137 @@ import { useGeneralSettings, useSidebarStore, useWindowSettings } from '/@/rende import { Platform } from '/@/renderer/types'; const RightSidebarContainer = styled(motion.aside)` - position: relative; - grid-area: right-sidebar; - height: 100%; - background: var(--sidebar-bg); - border-left: var(--sidebar-border); + position: relative; + grid-area: right-sidebar; + height: 100%; + background: var(--sidebar-bg); + border-left: var(--sidebar-border); `; const queueSidebarVariants: Variants = { - closed: (rightWidth) => ({ - transition: { duration: 0.5 }, - width: rightWidth, - x: 1000, - zIndex: 120, - }), - open: (rightWidth) => ({ - transition: { - duration: 0.5, - ease: 'anticipate', - }, - width: rightWidth, - x: 0, - zIndex: 120, - }), + closed: (rightWidth) => ({ + transition: { duration: 0.5 }, + width: rightWidth, + x: 1000, + zIndex: 120, + }), + open: (rightWidth) => ({ + transition: { + duration: 0.5, + ease: 'anticipate', + }, + width: rightWidth, + x: 0, + zIndex: 120, + }), }; const QueueDrawer = styled(motion.div)` - background: var(--main-bg); - border: 3px solid var(--generic-border-color); - border-radius: 10px; + background: var(--main-bg); + border: 3px solid var(--generic-border-color); + border-radius: 10px; `; const queueDrawerVariants: Variants = { - closed: (windowBarStyle) => ({ - height: - windowBarStyle === Platform.WINDOWS || Platform.MACOS - ? 'calc(100vh - 205px)' - : 'calc(100vh - 175px)', - position: 'absolute', - right: 0, - top: '75px', - transition: { - duration: 0.4, - ease: 'anticipate', - }, - width: '450px', - x: '50vw', - }), - open: (windowBarStyle) => ({ - boxShadow: '0px 0px 10px 0px rgba(0, 0, 0, 0.8)', - height: - windowBarStyle === Platform.WINDOWS || Platform.MACOS - ? 'calc(100vh - 205px)' - : 'calc(100vh - 175px)', - position: 'absolute', - right: '20px', - top: '75px', - transition: { - damping: 10, - delay: 0, - duration: 0.4, - ease: 'anticipate', - mass: 0.5, - }, - width: '450px', - x: 0, - zIndex: 120, - }), + closed: (windowBarStyle) => ({ + height: + windowBarStyle === Platform.WINDOWS || Platform.MACOS + ? 'calc(100vh - 205px)' + : 'calc(100vh - 175px)', + position: 'absolute', + right: 0, + top: '75px', + transition: { + duration: 0.4, + ease: 'anticipate', + }, + width: '450px', + x: '50vw', + }), + open: (windowBarStyle) => ({ + boxShadow: '0px 0px 10px 0px rgba(0, 0, 0, 0.8)', + height: + windowBarStyle === Platform.WINDOWS || Platform.MACOS + ? 'calc(100vh - 205px)' + : 'calc(100vh - 175px)', + position: 'absolute', + right: '20px', + top: '75px', + transition: { + damping: 10, + delay: 0, + duration: 0.4, + ease: 'anticipate', + mass: 0.5, + }, + width: '450px', + x: 0, + zIndex: 120, + }), }; interface RightSidebarProps { - isResizing: boolean; - startResizing: (direction: 'left' | 'right') => void; + isResizing: boolean; + startResizing: (direction: 'left' | 'right') => void; } export const RightSidebar = forwardRef( - ({ isResizing: isResizingRight, startResizing }: RightSidebarProps, ref: Ref<HTMLDivElement>) => { - const { windowBarStyle } = useWindowSettings(); - const { rightWidth, rightExpanded } = useSidebarStore(); - const { sideQueueType } = useGeneralSettings(); - const location = useLocation(); - const showSideQueue = rightExpanded && location.pathname !== AppRoute.NOW_PLAYING; + ( + { isResizing: isResizingRight, startResizing }: RightSidebarProps, + ref: Ref<HTMLDivElement>, + ) => { + const { windowBarStyle } = useWindowSettings(); + const { rightWidth, rightExpanded } = useSidebarStore(); + const { sideQueueType } = useGeneralSettings(); + const location = useLocation(); + const showSideQueue = rightExpanded && location.pathname !== AppRoute.NOW_PLAYING; - return ( - <AnimatePresence - key="queue-sidebar" - presenceAffectsLayout - initial={false} - mode="sync" - > - {showSideQueue && ( - <> - {sideQueueType === 'sideQueue' ? ( - <RightSidebarContainer + return ( + <AnimatePresence key="queue-sidebar" - animate="open" - custom={rightWidth} - exit="closed" - id="sidebar-queue" - initial="closed" - variants={queueSidebarVariants} - > - <ResizeHandle - ref={ref} - isResizing={isResizingRight} - placement="left" - onMouseDown={(e) => { - e.preventDefault(); - startResizing('right'); - }} - /> - <SidebarPlayQueue /> - </RightSidebarContainer> - ) : ( - <QueueDrawer - key="queue-drawer" - animate="open" - custom={windowBarStyle} - exit="closed" - id="drawer-queue" - initial="closed" - variants={queueDrawerVariants} - > - <DrawerPlayQueue /> - </QueueDrawer> - )} - </> - )} - </AnimatePresence> - ); - }, + presenceAffectsLayout + initial={false} + mode="sync" + > + {showSideQueue && ( + <> + {sideQueueType === 'sideQueue' ? ( + <RightSidebarContainer + key="queue-sidebar" + animate="open" + custom={rightWidth} + exit="closed" + id="sidebar-queue" + initial="closed" + variants={queueSidebarVariants} + > + <ResizeHandle + ref={ref} + isResizing={isResizingRight} + placement="left" + onMouseDown={(e) => { + e.preventDefault(); + startResizing('right'); + }} + /> + <SidebarPlayQueue /> + </RightSidebarContainer> + ) : ( + <QueueDrawer + key="queue-drawer" + animate="open" + custom={windowBarStyle} + exit="closed" + id="drawer-queue" + initial="closed" + variants={queueDrawerVariants} + > + <DrawerPlayQueue /> + </QueueDrawer> + )} + </> + )} + </AnimatePresence> + ); + }, ); diff --git a/src/renderer/layouts/default-layout/side-drawer-queue.tsx b/src/renderer/layouts/default-layout/side-drawer-queue.tsx index 84230218..c23c7b59 100644 --- a/src/renderer/layouts/default-layout/side-drawer-queue.tsx +++ b/src/renderer/layouts/default-layout/side-drawer-queue.tsx @@ -10,132 +10,132 @@ import { useAppStore, useSidebarStore } from '/@/renderer/store'; import { Platform } from '/@/renderer/types'; const QueueDrawerArea = styled(motion.div)` - position: absolute; - top: 50%; - right: 25px; - z-index: 100; - display: flex; - align-items: center; - width: 20px; - height: 30px; - user-select: none; + position: absolute; + top: 50%; + right: 25px; + z-index: 100; + display: flex; + align-items: center; + width: 20px; + height: 30px; + user-select: none; `; const QueueDrawer = styled(motion.div)` - background: var(--main-bg); - border: 3px solid var(--generic-border-color); - border-radius: 10px; + background: var(--main-bg); + border: 3px solid var(--generic-border-color); + border-radius: 10px; `; const queueDrawerVariants: Variants = { - closed: (windowBarStyle) => ({ - height: - windowBarStyle === Platform.WINDOWS || Platform.MACOS - ? 'calc(100vh - 205px)' - : 'calc(100vh - 175px)', - position: 'absolute', - right: 0, - top: '75px', - transition: { - duration: 0.4, - ease: 'anticipate', - }, - width: '450px', - x: '50vw', - }), - open: (windowBarStyle) => ({ - boxShadow: '0px 0px 10px 0px rgba(0, 0, 0, 0.8)', - height: - windowBarStyle === Platform.WINDOWS || Platform.MACOS - ? 'calc(100vh - 205px)' - : 'calc(100vh - 175px)', - position: 'absolute', - right: '20px', - top: '75px', - transition: { - damping: 10, - delay: 0, - duration: 0.4, - ease: 'anticipate', - mass: 0.5, - }, - width: '450px', - x: 0, - zIndex: 120, - }), + closed: (windowBarStyle) => ({ + height: + windowBarStyle === Platform.WINDOWS || Platform.MACOS + ? 'calc(100vh - 205px)' + : 'calc(100vh - 175px)', + position: 'absolute', + right: 0, + top: '75px', + transition: { + duration: 0.4, + ease: 'anticipate', + }, + width: '450px', + x: '50vw', + }), + open: (windowBarStyle) => ({ + boxShadow: '0px 0px 10px 0px rgba(0, 0, 0, 0.8)', + height: + windowBarStyle === Platform.WINDOWS || Platform.MACOS + ? 'calc(100vh - 205px)' + : 'calc(100vh - 175px)', + position: 'absolute', + right: '20px', + top: '75px', + transition: { + damping: 10, + delay: 0, + duration: 0.4, + ease: 'anticipate', + mass: 0.5, + }, + width: '450px', + x: 0, + zIndex: 120, + }), }; const queueDrawerButtonVariants: Variants = { - hidden: { - opacity: 0, - transition: { duration: 0.2 }, - x: 100, - }, - visible: { - opacity: 0.5, - transition: { duration: 0.1, ease: 'anticipate' }, - x: 0, - }, + hidden: { + opacity: 0, + transition: { duration: 0.2 }, + x: 100, + }, + visible: { + opacity: 0.5, + transition: { duration: 0.1, ease: 'anticipate' }, + x: 0, + }, }; export const SideDrawerQueue = () => { - const location = useLocation(); - const [drawer, drawerHandler] = useDisclosure(false); - const { rightExpanded } = useSidebarStore(); + const location = useLocation(); + const [drawer, drawerHandler] = useDisclosure(false); + const { rightExpanded } = useSidebarStore(); - const drawerTimeout = useTimeout(() => drawerHandler.open(), 500); + const drawerTimeout = useTimeout(() => drawerHandler.open(), 500); - const handleEnterDrawerButton = useCallback(() => { - drawerTimeout.start(); - }, [drawerTimeout]); + const handleEnterDrawerButton = useCallback(() => { + drawerTimeout.start(); + }, [drawerTimeout]); - const handleLeaveDrawerButton = useCallback(() => { - drawerTimeout.clear(); - }, [drawerTimeout]); + const handleLeaveDrawerButton = useCallback(() => { + drawerTimeout.clear(); + }, [drawerTimeout]); - const isQueueDrawerButtonVisible = - !rightExpanded && !drawer && location.pathname !== AppRoute.NOW_PLAYING; + const isQueueDrawerButtonVisible = + !rightExpanded && !drawer && location.pathname !== AppRoute.NOW_PLAYING; - return ( - <> - <AnimatePresence - initial={false} - mode="wait" - > - {isQueueDrawerButtonVisible && ( - <QueueDrawerArea - key="queue-drawer-button" - animate="visible" - exit="hidden" - initial="hidden" - variants={queueDrawerButtonVariants} - whileHover={{ opacity: 1, scale: 2, transition: { duration: 0.5 } }} - onMouseEnter={handleEnterDrawerButton} - onMouseLeave={handleLeaveDrawerButton} - > - <TbArrowBarLeft size={12} /> - </QueueDrawerArea> - )} + return ( + <> + <AnimatePresence + initial={false} + mode="wait" + > + {isQueueDrawerButtonVisible && ( + <QueueDrawerArea + key="queue-drawer-button" + animate="visible" + exit="hidden" + initial="hidden" + variants={queueDrawerButtonVariants} + whileHover={{ opacity: 1, scale: 2, transition: { duration: 0.5 } }} + onMouseEnter={handleEnterDrawerButton} + onMouseLeave={handleLeaveDrawerButton} + > + <TbArrowBarLeft size={12} /> + </QueueDrawerArea> + )} - {drawer && ( - <QueueDrawer - key="queue-drawer" - animate="open" - exit="closed" - initial="closed" - variants={queueDrawerVariants} - onMouseLeave={() => { - // The drawer will close due to the delay when setting isReorderingQueue - setTimeout(() => { - if (useAppStore.getState().isReorderingQueue) return; - drawerHandler.close(); - }, 50); - }} - > - <DrawerPlayQueue /> - </QueueDrawer> - )} - </AnimatePresence> - </> - ); + {drawer && ( + <QueueDrawer + key="queue-drawer" + animate="open" + exit="closed" + initial="closed" + variants={queueDrawerVariants} + onMouseLeave={() => { + // The drawer will close due to the delay when setting isReorderingQueue + setTimeout(() => { + if (useAppStore.getState().isReorderingQueue) return; + drawerHandler.close(); + }, 50); + }} + > + <DrawerPlayQueue /> + </QueueDrawer> + )} + </AnimatePresence> + </> + ); }; diff --git a/src/renderer/layouts/window-bar.tsx b/src/renderer/layouts/window-bar.tsx index 72f7c9c3..bc2724b0 100644 --- a/src/renderer/layouts/window-bar.tsx +++ b/src/renderer/layouts/window-bar.tsx @@ -14,49 +14,49 @@ import macMinHover from './assets/min-mac-hover.png'; import macMin from './assets/min-mac.png'; const WindowsContainer = styled.div` - display: flex; - align-items: center; - justify-content: space-between; - width: 100vw; - color: var(--window-bar-fg); - background-color: var(--window-bar-bg); - -webkit-app-region: drag; + display: flex; + align-items: center; + justify-content: space-between; + width: 100vw; + color: var(--window-bar-fg); + background-color: var(--window-bar-bg); + -webkit-app-region: drag; `; const WindowsButtonGroup = styled.div` - display: flex; - width: 130px; - height: 100%; - -webkit-app-region: no-drag; + display: flex; + width: 130px; + height: 100%; + -webkit-app-region: no-drag; `; const WindowsButton = styled.div<{ $exit?: boolean }>` - display: flex; - flex: 1; - align-items: center; - justify-content: center; - -webkit-app-region: no-drag; - width: 50px; - height: 30px; + display: flex; + flex: 1; + align-items: center; + justify-content: center; + -webkit-app-region: no-drag; + width: 50px; + height: 30px; - img { - width: 35%; - height: 50%; - } + img { + width: 35%; + height: 50%; + } - &:hover { - background: ${({ $exit }) => ($exit ? 'var(--danger-color)' : 'rgba(125, 125, 125, 30%)')}; - } + &:hover { + background: ${({ $exit }) => ($exit ? 'var(--danger-color)' : 'rgba(125, 125, 125, 30%)')}; + } `; const PlayerStatusContainer = styled.div` - display: flex; - gap: 0.5rem; - max-width: 45vw; - padding-left: 1rem; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; + display: flex; + gap: 0.5rem; + max-width: 45vw; + padding-left: 1rem; + overflow: hidden; + white-space: nowrap; + text-overflow: ellipsis; `; const browser = isElectron() ? window.electron.browser : null; @@ -66,192 +66,193 @@ const maximize = () => browser.maximize(); const unmaximize = () => browser.unmaximize(); interface WindowBarControlsProps { - controls: { - handleClose: () => void; - handleMaximize: () => void; - handleMinimize: () => void; - }; - title: string; + controls: { + handleClose: () => void; + handleMaximize: () => void; + handleMinimize: () => void; + }; + title: string; } const WindowsControls = ({ controls, title }: WindowBarControlsProps) => { - const { handleClose, handleMaximize, handleMinimize } = controls; + const { handleClose, handleMaximize, handleMinimize } = controls; - return ( - <WindowsContainer> - <PlayerStatusContainer> - <img - alt="" - height={18} - src={appIcon} - width={18} - /> - {title} - </PlayerStatusContainer> - <WindowsButtonGroup> - <WindowsButton - role="button" - onClick={handleMinimize} - > - <RiSubtractLine size={19} /> - </WindowsButton> - <WindowsButton - role="button" - onClick={handleMaximize} - > - <RiCheckboxBlankLine size={13} /> - </WindowsButton> - <WindowsButton - $exit - role="button" - onClick={handleClose} - > - <RiCloseLine size={19} /> - </WindowsButton> - </WindowsButtonGroup> - </WindowsContainer> - ); + return ( + <WindowsContainer> + <PlayerStatusContainer> + <img + alt="" + height={18} + src={appIcon} + width={18} + /> + {title} + </PlayerStatusContainer> + <WindowsButtonGroup> + <WindowsButton + role="button" + onClick={handleMinimize} + > + <RiSubtractLine size={19} /> + </WindowsButton> + <WindowsButton + role="button" + onClick={handleMaximize} + > + <RiCheckboxBlankLine size={13} /> + </WindowsButton> + <WindowsButton + $exit + role="button" + onClick={handleClose} + > + <RiCloseLine size={19} /> + </WindowsButton> + </WindowsButtonGroup> + </WindowsContainer> + ); }; const MacOsContainer = styled.div` - display: flex; - align-items: center; - justify-content: center; - width: 100vw; - -webkit-app-region: drag; - color: var(--window-bar-fg); - background-color: var(--window-bar-bg); + display: flex; + align-items: center; + justify-content: center; + width: 100vw; + -webkit-app-region: drag; + color: var(--window-bar-fg); + background-color: var(--window-bar-bg); `; const MacOsButtonGroup = styled.div` - position: absolute; - top: 5px; - left: 0.5rem; - display: grid; - grid-template-columns: repeat(3, 20px); - height: 100%; + position: absolute; + top: 5px; + left: 0.5rem; + display: grid; + grid-template-columns: repeat(3, 20px); + height: 100%; - -webkit-app-region: no-drag; + -webkit-app-region: no-drag; `; export const MacOsButton = styled.div<{ - maxButton?: boolean; - minButton?: boolean; - restoreButton?: boolean; + maxButton?: boolean; + minButton?: boolean; + restoreButton?: boolean; }>` - grid-row: 1 / span 1; - grid-column: ${(props) => (props.minButton ? 2 : props.maxButton || props.restoreButton ? 3 : 1)}; - align-items: center; - justify-content: center; - width: 100%; - height: 100%; - user-select: none; + grid-row: 1 / span 1; + grid-column: ${(props) => + props.minButton ? 2 : props.maxButton || props.restoreButton ? 3 : 1}; + align-items: center; + justify-content: center; + width: 100%; + height: 100%; + user-select: none; - img { - width: 18px; - height: 18px; - } + img { + width: 18px; + height: 18px; + } `; const MacOsControls = ({ controls, title }: WindowBarControlsProps) => { - const { handleClose, handleMaximize, handleMinimize } = controls; + const { handleClose, handleMaximize, handleMinimize } = controls; - const [hoverMin, setHoverMin] = useState(false); - const [hoverMax, setHoverMax] = useState(false); - const [hoverClose, setHoverClose] = useState(false); + const [hoverMin, setHoverMin] = useState(false); + const [hoverMax, setHoverMax] = useState(false); + const [hoverClose, setHoverClose] = useState(false); - return ( - <MacOsContainer> - <MacOsButtonGroup> - <MacOsButton - minButton - className="button" - id="min-button" - onClick={handleMinimize} - onMouseLeave={() => setHoverMin(false)} - onMouseOver={() => setHoverMin(true)} - > - <img - alt="" - className="icon" - draggable="false" - src={hoverMin ? macMinHover : macMin} - /> - </MacOsButton> - <MacOsButton - maxButton - className="button" - id="max-button" - onClick={handleMaximize} - onMouseLeave={() => setHoverMax(false)} - onMouseOver={() => setHoverMax(true)} - > - <img - alt="" - className="icon" - draggable="false" - src={hoverMax ? macMaxHover : macMax} - /> - </MacOsButton> - <MacOsButton - className="button" - id="close-button" - onClick={handleClose} - onMouseLeave={() => setHoverClose(false)} - onMouseOver={() => setHoverClose(true)} - > - <img - alt="" - className="icon" - draggable="false" - src={hoverClose ? macCloseHover : macClose} - /> - </MacOsButton> - </MacOsButtonGroup> - <PlayerStatusContainer>{title}</PlayerStatusContainer> - </MacOsContainer> - ); + return ( + <MacOsContainer> + <MacOsButtonGroup> + <MacOsButton + minButton + className="button" + id="min-button" + onClick={handleMinimize} + onMouseLeave={() => setHoverMin(false)} + onMouseOver={() => setHoverMin(true)} + > + <img + alt="" + className="icon" + draggable="false" + src={hoverMin ? macMinHover : macMin} + /> + </MacOsButton> + <MacOsButton + maxButton + className="button" + id="max-button" + onClick={handleMaximize} + onMouseLeave={() => setHoverMax(false)} + onMouseOver={() => setHoverMax(true)} + > + <img + alt="" + className="icon" + draggable="false" + src={hoverMax ? macMaxHover : macMax} + /> + </MacOsButton> + <MacOsButton + className="button" + id="close-button" + onClick={handleClose} + onMouseLeave={() => setHoverClose(false)} + onMouseOver={() => setHoverClose(true)} + > + <img + alt="" + className="icon" + draggable="false" + src={hoverClose ? macCloseHover : macClose} + /> + </MacOsButton> + </MacOsButtonGroup> + <PlayerStatusContainer>{title}</PlayerStatusContainer> + </MacOsContainer> + ); }; export const WindowBar = () => { - const playerStatus = useCurrentStatus(); - const { currentSong, index, length } = useQueueStatus(); - const { windowBarStyle } = useWindowSettings(); + const playerStatus = useCurrentStatus(); + const { currentSong, index, length } = useQueueStatus(); + const { windowBarStyle } = useWindowSettings(); - const statusString = playerStatus === PlayerStatus.PAUSED ? '(Paused) ' : ''; - const queueString = length ? `(${index + 1} / ${length}) ` : ''; - const title = length ? `${statusString}${queueString}${currentSong?.name}` : 'Feishin'; - document.title = title; + const statusString = playerStatus === PlayerStatus.PAUSED ? '(Paused) ' : ''; + const queueString = length ? `(${index + 1} / ${length}) ` : ''; + const title = length ? `${statusString}${queueString}${currentSong?.name}` : 'Feishin'; + document.title = title; - const [max, setMax] = useState(false); + const [max, setMax] = useState(false); - const handleMinimize = () => minimize(); + const handleMinimize = () => minimize(); - const handleMaximize = useCallback(() => { - if (max) { - unmaximize(); - } else { - maximize(); - } - setMax(!max); - }, [max]); + const handleMaximize = useCallback(() => { + if (max) { + unmaximize(); + } else { + maximize(); + } + setMax(!max); + }, [max]); - const handleClose = useCallback(() => close(), []); + const handleClose = useCallback(() => close(), []); - return ( - <> - {windowBarStyle === Platform.WINDOWS && ( - <WindowsControls - controls={{ handleClose, handleMaximize, handleMinimize }} - title={title} - /> - )} - {windowBarStyle === Platform.MACOS && ( - <MacOsControls - controls={{ handleClose, handleMaximize, handleMinimize }} - title={title} - /> - )} - </> - ); + return ( + <> + {windowBarStyle === Platform.WINDOWS && ( + <WindowsControls + controls={{ handleClose, handleMaximize, handleMinimize }} + title={title} + /> + )} + {windowBarStyle === Platform.MACOS && ( + <MacOsControls + controls={{ handleClose, handleMaximize, handleMinimize }} + title={title} + /> + )} + </> + ); }; diff --git a/src/renderer/lib/react-query.ts b/src/renderer/lib/react-query.ts index d5b7656a..dff03c26 100644 --- a/src/renderer/lib/react-query.ts +++ b/src/renderer/lib/react-query.ts @@ -1,97 +1,97 @@ import type { - UseQueryOptions, - DefaultOptions, - UseMutationOptions, - UseInfiniteQueryOptions, + UseQueryOptions, + DefaultOptions, + UseMutationOptions, + UseInfiniteQueryOptions, } from '@tanstack/react-query'; import { QueryClient, QueryCache } from '@tanstack/react-query'; import { toast } from '/@/renderer/components/toast/index'; const queryCache = new QueryCache({ - onError: (error: any, query) => { - if (query.state.data !== undefined) { - toast.show({ message: `${error.message}`, type: 'error' }); - } - }, + onError: (error: any, query) => { + if (query.state.data !== undefined) { + toast.show({ message: `${error.message}`, type: 'error' }); + } + }, }); const queryConfig: DefaultOptions = { - mutations: { - retry: process.env.NODE_ENV === 'production', - }, - queries: { - cacheTime: 1000 * 60 * 3, - onError: (err) => { - console.error('react query error:', err); + mutations: { + retry: process.env.NODE_ENV === 'production', }, - refetchOnWindowFocus: false, - retry: process.env.NODE_ENV === 'production', - staleTime: 1000 * 5, - useErrorBoundary: (error: any) => { - return error?.response?.status >= 500; + queries: { + cacheTime: 1000 * 60 * 3, + onError: (err) => { + console.error('react query error:', err); + }, + refetchOnWindowFocus: false, + retry: process.env.NODE_ENV === 'production', + staleTime: 1000 * 5, + useErrorBoundary: (error: any) => { + return error?.response?.status >= 500; + }, }, - }, }; export const queryClient = new QueryClient({ - defaultOptions: queryConfig, - queryCache, + defaultOptions: queryConfig, + queryCache, }); export type QueryHookArgs<T> = { - options?: QueryOptions; - query: T; - serverId: string | undefined; + options?: QueryOptions; + query: T; + serverId: string | undefined; }; export type MutationHookArgs = { - options?: MutationOptions; + options?: MutationOptions; }; export type QueryOptions = { - cacheTime?: UseQueryOptions['cacheTime']; - enabled?: UseQueryOptions['enabled']; - keepPreviousData?: UseQueryOptions['keepPreviousData']; - meta?: UseQueryOptions['meta']; - onError?: (err: any) => void; - onSettled?: any; - onSuccess?: any; - queryKey?: UseQueryOptions['queryKey']; - refetchInterval?: number; - refetchIntervalInBackground?: UseQueryOptions['refetchIntervalInBackground']; - refetchOnWindowFocus?: boolean; - retry?: UseQueryOptions['retry']; - retryDelay?: UseQueryOptions['retryDelay']; - staleTime?: UseQueryOptions['staleTime']; - suspense?: UseQueryOptions['suspense']; - useErrorBoundary?: boolean; + cacheTime?: UseQueryOptions['cacheTime']; + enabled?: UseQueryOptions['enabled']; + keepPreviousData?: UseQueryOptions['keepPreviousData']; + meta?: UseQueryOptions['meta']; + onError?: (err: any) => void; + onSettled?: any; + onSuccess?: any; + queryKey?: UseQueryOptions['queryKey']; + refetchInterval?: number; + refetchIntervalInBackground?: UseQueryOptions['refetchIntervalInBackground']; + refetchOnWindowFocus?: boolean; + retry?: UseQueryOptions['retry']; + retryDelay?: UseQueryOptions['retryDelay']; + staleTime?: UseQueryOptions['staleTime']; + suspense?: UseQueryOptions['suspense']; + useErrorBoundary?: boolean; }; export type MutationOptions = { - mutationKey: UseMutationOptions['mutationKey']; - onError?: (err: any) => void; - onSettled?: any; - onSuccess?: any; - retry?: UseQueryOptions['retry']; - retryDelay?: UseQueryOptions['retryDelay']; - useErrorBoundary?: boolean; + mutationKey: UseMutationOptions['mutationKey']; + onError?: (err: any) => void; + onSettled?: any; + onSuccess?: any; + retry?: UseQueryOptions['retry']; + retryDelay?: UseQueryOptions['retryDelay']; + useErrorBoundary?: boolean; }; export type InfiniteQueryOptions = { - cacheTime?: UseInfiniteQueryOptions['cacheTime']; - enabled?: UseInfiniteQueryOptions['enabled']; - keepPreviousData?: UseInfiniteQueryOptions['keepPreviousData']; - meta?: UseInfiniteQueryOptions['meta']; - onError?: (err: any) => void; - onSettled?: any; - onSuccess?: any; - queryKey?: UseInfiniteQueryOptions['queryKey']; - refetchInterval?: number; - refetchIntervalInBackground?: UseInfiniteQueryOptions['refetchIntervalInBackground']; - refetchOnWindowFocus?: boolean; - retry?: UseInfiniteQueryOptions['retry']; - retryDelay?: UseInfiniteQueryOptions['retryDelay']; - staleTime?: UseInfiniteQueryOptions['staleTime']; - suspense?: UseInfiniteQueryOptions['suspense']; - useErrorBoundary?: boolean; + cacheTime?: UseInfiniteQueryOptions['cacheTime']; + enabled?: UseInfiniteQueryOptions['enabled']; + keepPreviousData?: UseInfiniteQueryOptions['keepPreviousData']; + meta?: UseInfiniteQueryOptions['meta']; + onError?: (err: any) => void; + onSettled?: any; + onSuccess?: any; + queryKey?: UseInfiniteQueryOptions['queryKey']; + refetchInterval?: number; + refetchIntervalInBackground?: UseInfiniteQueryOptions['refetchIntervalInBackground']; + refetchOnWindowFocus?: boolean; + retry?: UseInfiniteQueryOptions['retry']; + retryDelay?: UseInfiniteQueryOptions['retryDelay']; + staleTime?: UseInfiniteQueryOptions['staleTime']; + suspense?: UseInfiniteQueryOptions['suspense']; + useErrorBoundary?: boolean; }; diff --git a/src/renderer/preload.d.ts b/src/renderer/preload.d.ts index e200d2bf..72b7ddba 100644 --- a/src/renderer/preload.d.ts +++ b/src/renderer/preload.d.ts @@ -3,66 +3,70 @@ import { PlayerData, PlayerState } from './store'; import { InternetProviderLyricResponse, QueueSong } from '/@/renderer/api/types'; declare global { - interface Window { - electron: { - browser: any; - ipc: any; - ipcRenderer: { - APP_RESTART(): void; - LYRIC_FETCH(data: QueueSong): void; - LYRIC_GET( - event: IpcRendererEvent, - songName: string, - source: string, - lyric: InternetProviderLyricResponse, - ): void; - PASSWORD_GET(server: string): Promise<string | null>; - PASSWORD_REMOVE(server: string): void; - PASSWORD_SET(password: string, server: string): Promise<boolean>; - PLAYER_AUTO_NEXT(data: PlayerData): void; - PLAYER_CURRENT_TIME(): void; - PLAYER_GET_TIME(): number | undefined; - PLAYER_MEDIA_KEYS_DISABLE(): void; - PLAYER_MEDIA_KEYS_ENABLE(): void; - PLAYER_MUTE(): void; - PLAYER_NEXT(): void; - PLAYER_PAUSE(): void; - PLAYER_PLAY(): void; - PLAYER_PREVIOUS(): void; - PLAYER_RESTORE_DATA(): void; - PLAYER_SAVE_QUEUE(data: PlayerState): void; - PLAYER_SEEK(seconds: number): void; - PLAYER_SEEK_TO(seconds: number): void; - PLAYER_SET_QUEUE(data: PlayerData): void; - PLAYER_SET_QUEUE_NEXT(data: PlayerData): void; - PLAYER_STOP(): void; - PLAYER_VOLUME(value: number): void; - RENDERER_PLAYER_AUTO_NEXT(cb: (event: IpcRendererEvent, data: any) => void): void; - RENDERER_PLAYER_CURRENT_TIME(cb: (event: IpcRendererEvent, data: any) => void): void; - RENDERER_PLAYER_NEXT(cb: (event: IpcRendererEvent, data: any) => void): void; - RENDERER_PLAYER_PAUSE(cb: (event: IpcRendererEvent, data: any) => void): void; - RENDERER_PLAYER_PLAY(cb: (event: IpcRendererEvent, data: any) => void): void; - RENDERER_PLAYER_PLAY_PAUSE(cb: (event: IpcRendererEvent, data: any) => void): void; - RENDERER_PLAYER_PREVIOUS(cb: (event: IpcRendererEvent, data: any) => void): void; - RENDERER_PLAYER_RESTORE_QUEUE(cb: (event: IpcRendererEvent, data: any) => void): void; - RENDERER_PLAYER_SAVE_QUEUE(cb: (event: IpcRendererEvent, data: any) => void): void; - RENDERER_PLAYER_STOP(cb: (event: IpcRendererEvent, data: any) => void): void; - SETTINGS_GET(data: { property: string }): any; - SETTINGS_SET(data: { property: string; value: any }): void; - removeAllListeners(value: string): void; - windowClose(): void; - windowMaximize(): void; - windowMinimize(): void; - windowUnmaximize(): void; - }; - localSettings: any; - lyrics: any; - mpris: any; - mpvPlayer: any; - mpvPlayerListener: any; - utils: any; - }; - } + interface Window { + electron: { + browser: any; + ipc: any; + ipcRenderer: { + APP_RESTART(): void; + LYRIC_FETCH(data: QueueSong): void; + LYRIC_GET( + event: IpcRendererEvent, + songName: string, + source: string, + lyric: InternetProviderLyricResponse, + ): void; + PASSWORD_GET(server: string): Promise<string | null>; + PASSWORD_REMOVE(server: string): void; + PASSWORD_SET(password: string, server: string): Promise<boolean>; + PLAYER_AUTO_NEXT(data: PlayerData): void; + PLAYER_CURRENT_TIME(): void; + PLAYER_GET_TIME(): number | undefined; + PLAYER_MEDIA_KEYS_DISABLE(): void; + PLAYER_MEDIA_KEYS_ENABLE(): void; + PLAYER_MUTE(): void; + PLAYER_NEXT(): void; + PLAYER_PAUSE(): void; + PLAYER_PLAY(): void; + PLAYER_PREVIOUS(): void; + PLAYER_RESTORE_DATA(): void; + PLAYER_SAVE_QUEUE(data: PlayerState): void; + PLAYER_SEEK(seconds: number): void; + PLAYER_SEEK_TO(seconds: number): void; + PLAYER_SET_QUEUE(data: PlayerData): void; + PLAYER_SET_QUEUE_NEXT(data: PlayerData): void; + PLAYER_STOP(): void; + PLAYER_VOLUME(value: number): void; + RENDERER_PLAYER_AUTO_NEXT(cb: (event: IpcRendererEvent, data: any) => void): void; + RENDERER_PLAYER_CURRENT_TIME( + cb: (event: IpcRendererEvent, data: any) => void, + ): void; + RENDERER_PLAYER_NEXT(cb: (event: IpcRendererEvent, data: any) => void): void; + RENDERER_PLAYER_PAUSE(cb: (event: IpcRendererEvent, data: any) => void): void; + RENDERER_PLAYER_PLAY(cb: (event: IpcRendererEvent, data: any) => void): void; + RENDERER_PLAYER_PLAY_PAUSE(cb: (event: IpcRendererEvent, data: any) => void): void; + RENDERER_PLAYER_PREVIOUS(cb: (event: IpcRendererEvent, data: any) => void): void; + RENDERER_PLAYER_RESTORE_QUEUE( + cb: (event: IpcRendererEvent, data: any) => void, + ): void; + RENDERER_PLAYER_SAVE_QUEUE(cb: (event: IpcRendererEvent, data: any) => void): void; + RENDERER_PLAYER_STOP(cb: (event: IpcRendererEvent, data: any) => void): void; + SETTINGS_GET(data: { property: string }): any; + SETTINGS_SET(data: { property: string; value: any }): void; + removeAllListeners(value: string): void; + windowClose(): void; + windowMaximize(): void; + windowMinimize(): void; + windowUnmaximize(): void; + }; + localSettings: any; + lyrics: any; + mpris: any; + mpvPlayer: any; + mpvPlayerListener: any; + utils: any; + }; + } } export {}; diff --git a/src/renderer/router/app-outlet.tsx b/src/renderer/router/app-outlet.tsx index d46c50ef..7984fd94 100644 --- a/src/renderer/router/app-outlet.tsx +++ b/src/renderer/router/app-outlet.tsx @@ -7,32 +7,32 @@ import { useCurrentServer } from '/@/renderer/store'; const localSettings = isElectron() ? window.electron.localSettings : null; export const AppOutlet = () => { - const currentServer = useCurrentServer(); + const currentServer = useCurrentServer(); - const isActionsRequired = useMemo(() => { - const isMpvRequired = () => { - if (!isElectron()) return false; - const mpvPath = localSettings.get('mpv_path'); - if (mpvPath) return false; - return true; - }; + const isActionsRequired = useMemo(() => { + const isMpvRequired = () => { + if (!isElectron()) return false; + const mpvPath = localSettings.get('mpv_path'); + if (mpvPath) return false; + return true; + }; - const isServerRequired = !currentServer; + const isServerRequired = !currentServer; - const actions = [isServerRequired, isMpvRequired()]; - const isActionRequired = actions.some((c) => c); + const actions = [isServerRequired, isMpvRequired()]; + const isActionRequired = actions.some((c) => c); - return isActionRequired; - }, [currentServer]); + return isActionRequired; + }, [currentServer]); - if (isActionsRequired) { - return ( - <Navigate - replace - to={AppRoute.ACTION_REQUIRED} - /> - ); - } + if (isActionsRequired) { + return ( + <Navigate + replace + to={AppRoute.ACTION_REQUIRED} + /> + ); + } - return <Outlet />; + return <Outlet />; }; diff --git a/src/renderer/router/app-router.tsx b/src/renderer/router/app-router.tsx index 55eff48c..4341ed94 100644 --- a/src/renderer/router/app-router.tsx +++ b/src/renderer/router/app-router.tsx @@ -1,11 +1,11 @@ import isElectron from 'is-electron'; import { lazy, Suspense } from 'react'; import { - Route, - createRoutesFromElements, - RouterProvider, - createBrowserRouter, - createHashRouter, + Route, + createRoutesFromElements, + RouterProvider, + createBrowserRouter, + createHashRouter, } from 'react-router-dom'; import { AppRoute } from './routes'; import { DefaultLayout } from '/@/renderer/layouts'; @@ -13,7 +13,7 @@ import { AppOutlet } from '/@/renderer/router/app-outlet'; import { TitlebarOutlet } from '/@/renderer/router/titlebar-outlet'; const NowPlayingRoute = lazy( - () => import('/@/renderer/features/now-playing/routes/now-playing-route'), + () => import('/@/renderer/features/now-playing/routes/now-playing-route'), ); const AlbumListRoute = lazy(() => import('/@/renderer/features/albums/routes/album-list-route')); @@ -21,41 +21,41 @@ const AlbumListRoute = lazy(() => import('/@/renderer/features/albums/routes/alb const SongListRoute = lazy(() => import('/@/renderer/features/songs/routes/song-list-route')); const PlaylistDetailRoute = lazy( - () => import('/@/renderer/features/playlists/routes/playlist-detail-route'), + () => import('/@/renderer/features/playlists/routes/playlist-detail-route'), ); const PlaylistDetailSongListRoute = lazy( - () => import('/@/renderer/features/playlists/routes/playlist-detail-song-list-route'), + () => import('/@/renderer/features/playlists/routes/playlist-detail-song-list-route'), ); const PlaylistListRoute = lazy( - () => import('/@/renderer/features/playlists/routes/playlist-list-route'), + () => import('/@/renderer/features/playlists/routes/playlist-list-route'), ); const ActionRequiredRoute = lazy( - () => import('/@/renderer/features/action-required/routes/action-required-route'), + () => import('/@/renderer/features/action-required/routes/action-required-route'), ); const InvalidRoute = lazy( - () => import('/@/renderer/features/action-required/routes/invalid-route'), + () => import('/@/renderer/features/action-required/routes/invalid-route'), ); const HomeRoute = lazy(() => import('/@/renderer/features/home/routes/home-route')); const AlbumArtistListRoute = lazy( - () => import('/@/renderer/features/artists/routes/album-artist-list-route'), + () => import('/@/renderer/features/artists/routes/album-artist-list-route'), ); const AlbumArtistDetailRoute = lazy( - () => import('/@/renderer/features/artists/routes/album-artist-detail-route'), + () => import('/@/renderer/features/artists/routes/album-artist-detail-route'), ); const AlbumArtistDetailTopSongsListRoute = lazy( - () => import('../features/artists/routes/album-artist-detail-top-songs-list-route'), + () => import('../features/artists/routes/album-artist-detail-top-songs-list-route'), ); const AlbumDetailRoute = lazy( - () => import('/@/renderer/features/albums/routes/album-detail-route'), + () => import('/@/renderer/features/albums/routes/album-detail-route'), ); const SettingsRoute = lazy(() => import('/@/renderer/features/settings/routes/settings-route')); @@ -63,125 +63,125 @@ const SettingsRoute = lazy(() => import('/@/renderer/features/settings/routes/se const SearchRoute = lazy(() => import('/@/renderer/features/search/routes/search-route')); const RouteErrorBoundary = lazy( - () => import('/@/renderer/features/action-required/components/route-error-boundary'), + () => import('/@/renderer/features/action-required/components/route-error-boundary'), ); const dynamicRouter = isElectron() ? createHashRouter : createBrowserRouter; export const AppRouter = () => { - const router = dynamicRouter( - createRoutesFromElements( - <> - <Route element={<TitlebarOutlet />}> - <Route - element={<AppOutlet />} - errorElement={<RouteErrorBoundary />} - > - <Route element={<DefaultLayout />}> - <Route - index - element={<HomeRoute />} - errorElement={<RouteErrorBoundary />} - /> - <Route - element={<HomeRoute />} - errorElement={<RouteErrorBoundary />} - path={AppRoute.HOME} - /> - <Route - element={<SearchRoute />} - errorElement={<RouteErrorBoundary />} - path={AppRoute.SEARCH} - /> - <Route - element={<SettingsRoute />} - errorElement={<RouteErrorBoundary />} - path={AppRoute.SETTINGS} - /> - <Route - element={<NowPlayingRoute />} - errorElement={<RouteErrorBoundary />} - path={AppRoute.NOW_PLAYING} - /> - <Route - element={<AlbumListRoute />} - errorElement={<RouteErrorBoundary />} - path={AppRoute.LIBRARY_ALBUMS} - /> - <Route - element={<AlbumDetailRoute />} - errorElement={<RouteErrorBoundary />} - path={AppRoute.LIBRARY_ALBUMS_DETAIL} - /> - <Route - element={<SongListRoute />} - errorElement={<RouteErrorBoundary />} - path={AppRoute.LIBRARY_SONGS} - /> - <Route - element={<PlaylistListRoute />} - errorElement={<RouteErrorBoundary />} - path={AppRoute.PLAYLISTS} - /> - <Route - element={<PlaylistDetailRoute />} - errorElement={<RouteErrorBoundary />} - path={AppRoute.PLAYLISTS_DETAIL} - /> - <Route - element={<PlaylistDetailSongListRoute />} - errorElement={<RouteErrorBoundary />} - path={AppRoute.PLAYLISTS_DETAIL_SONGS} - /> - <Route - errorElement={<RouteErrorBoundary />} - path={AppRoute.LIBRARY_ALBUM_ARTISTS} - > - <Route - index - element={<AlbumArtistListRoute />} - /> - <Route path={AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL}> - <Route - index - element={<AlbumArtistDetailRoute />} - /> - <Route - element={<AlbumListRoute />} - path={AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL_DISCOGRAPHY} - /> - <Route - element={<SongListRoute />} - path={AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL_SONGS} - /> - <Route - element={<AlbumArtistDetailTopSongsListRoute />} - path={AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL_TOP_SONGS} - /> + const router = dynamicRouter( + createRoutesFromElements( + <> + <Route element={<TitlebarOutlet />}> + <Route + element={<AppOutlet />} + errorElement={<RouteErrorBoundary />} + > + <Route element={<DefaultLayout />}> + <Route + index + element={<HomeRoute />} + errorElement={<RouteErrorBoundary />} + /> + <Route + element={<HomeRoute />} + errorElement={<RouteErrorBoundary />} + path={AppRoute.HOME} + /> + <Route + element={<SearchRoute />} + errorElement={<RouteErrorBoundary />} + path={AppRoute.SEARCH} + /> + <Route + element={<SettingsRoute />} + errorElement={<RouteErrorBoundary />} + path={AppRoute.SETTINGS} + /> + <Route + element={<NowPlayingRoute />} + errorElement={<RouteErrorBoundary />} + path={AppRoute.NOW_PLAYING} + /> + <Route + element={<AlbumListRoute />} + errorElement={<RouteErrorBoundary />} + path={AppRoute.LIBRARY_ALBUMS} + /> + <Route + element={<AlbumDetailRoute />} + errorElement={<RouteErrorBoundary />} + path={AppRoute.LIBRARY_ALBUMS_DETAIL} + /> + <Route + element={<SongListRoute />} + errorElement={<RouteErrorBoundary />} + path={AppRoute.LIBRARY_SONGS} + /> + <Route + element={<PlaylistListRoute />} + errorElement={<RouteErrorBoundary />} + path={AppRoute.PLAYLISTS} + /> + <Route + element={<PlaylistDetailRoute />} + errorElement={<RouteErrorBoundary />} + path={AppRoute.PLAYLISTS_DETAIL} + /> + <Route + element={<PlaylistDetailSongListRoute />} + errorElement={<RouteErrorBoundary />} + path={AppRoute.PLAYLISTS_DETAIL_SONGS} + /> + <Route + errorElement={<RouteErrorBoundary />} + path={AppRoute.LIBRARY_ALBUM_ARTISTS} + > + <Route + index + element={<AlbumArtistListRoute />} + /> + <Route path={AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL}> + <Route + index + element={<AlbumArtistDetailRoute />} + /> + <Route + element={<AlbumListRoute />} + path={AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL_DISCOGRAPHY} + /> + <Route + element={<SongListRoute />} + path={AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL_SONGS} + /> + <Route + element={<AlbumArtistDetailTopSongsListRoute />} + path={AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL_TOP_SONGS} + /> + </Route> + </Route> + <Route + element={<InvalidRoute />} + path="*" + /> + </Route> + </Route> </Route> - </Route> - <Route - element={<InvalidRoute />} - path="*" - /> - </Route> - </Route> - </Route> - <Route element={<TitlebarOutlet />}> - <Route element={<DefaultLayout shell />}> - <Route - element={<ActionRequiredRoute />} - path={AppRoute.ACTION_REQUIRED} - /> - </Route> - </Route> - </>, - ), - ); + <Route element={<TitlebarOutlet />}> + <Route element={<DefaultLayout shell />}> + <Route + element={<ActionRequiredRoute />} + path={AppRoute.ACTION_REQUIRED} + /> + </Route> + </Route> + </>, + ), + ); - return ( - <Suspense fallback={<></>}> - <RouterProvider router={router} /> - </Suspense> - ); + return ( + <Suspense fallback={<></>}> + <RouterProvider router={router} /> + </Suspense> + ); }; diff --git a/src/renderer/router/routes.ts b/src/renderer/router/routes.ts index 66cf71f8..56af2402 100644 --- a/src/renderer/router/routes.ts +++ b/src/renderer/router/routes.ts @@ -1,25 +1,25 @@ export enum AppRoute { - ACTION_REQUIRED = '/action-required', - EXPLORE = '/explore', - HOME = '/', - LIBRARY_ALBUMS = '/library/albums', - LIBRARY_ALBUMS_DETAIL = '/library/albums/:albumId', - LIBRARY_ALBUM_ARTISTS = '/library/album-artists', - LIBRARY_ALBUM_ARTISTS_DETAIL = '/library/album-artists/:albumArtistId', - LIBRARY_ALBUM_ARTISTS_DETAIL_DISCOGRAPHY = '/library/album-artists/:albumArtistId/discography', - LIBRARY_ALBUM_ARTISTS_DETAIL_SONGS = '/library/album-artists/:albumArtistId/songs', - LIBRARY_ALBUM_ARTISTS_DETAIL_TOP_SONGS = '/library/album-artists/:albumArtistId/top-songs', - LIBRARY_ARTISTS = '/library/artists', - LIBRARY_ARTISTS_DETAIL = '/library/artists/:artistId', - LIBRARY_FOLDERS = '/library/folders', - LIBRARY_GENRES = '/library/genres', - LIBRARY_SONGS = '/library/songs', - NOW_PLAYING = '/now-playing', - PLAYING = '/playing', - PLAYLISTS = '/playlists', - PLAYLISTS_DETAIL = '/playlists/:playlistId', - PLAYLISTS_DETAIL_SONGS = '/playlists/:playlistId/songs', - SEARCH = '/search/:itemType', - SERVERS = '/servers', - SETTINGS = '/settings', + ACTION_REQUIRED = '/action-required', + EXPLORE = '/explore', + HOME = '/', + LIBRARY_ALBUMS = '/library/albums', + LIBRARY_ALBUMS_DETAIL = '/library/albums/:albumId', + LIBRARY_ALBUM_ARTISTS = '/library/album-artists', + LIBRARY_ALBUM_ARTISTS_DETAIL = '/library/album-artists/:albumArtistId', + LIBRARY_ALBUM_ARTISTS_DETAIL_DISCOGRAPHY = '/library/album-artists/:albumArtistId/discography', + LIBRARY_ALBUM_ARTISTS_DETAIL_SONGS = '/library/album-artists/:albumArtistId/songs', + LIBRARY_ALBUM_ARTISTS_DETAIL_TOP_SONGS = '/library/album-artists/:albumArtistId/top-songs', + LIBRARY_ARTISTS = '/library/artists', + LIBRARY_ARTISTS_DETAIL = '/library/artists/:artistId', + LIBRARY_FOLDERS = '/library/folders', + LIBRARY_GENRES = '/library/genres', + LIBRARY_SONGS = '/library/songs', + NOW_PLAYING = '/now-playing', + PLAYING = '/playing', + PLAYLISTS = '/playlists', + PLAYLISTS_DETAIL = '/playlists/:playlistId', + PLAYLISTS_DETAIL_SONGS = '/playlists/:playlistId/songs', + SEARCH = '/search/:itemType', + SERVERS = '/servers', + SETTINGS = '/settings', } diff --git a/src/renderer/router/titlebar-outlet.tsx b/src/renderer/router/titlebar-outlet.tsx index 093c62ad..a4be6661 100644 --- a/src/renderer/router/titlebar-outlet.tsx +++ b/src/renderer/router/titlebar-outlet.tsx @@ -5,26 +5,26 @@ import { useWindowSettings } from '/@/renderer/store/settings.store'; import { Platform } from '/@/renderer/types'; const TitlebarContainer = styled.header` - position: absolute; - top: 0; - right: 0; - z-index: 5000; - height: 65px; - background: var(--titlebar-controls-bg); - -webkit-app-region: drag; + position: absolute; + top: 0; + right: 0; + z-index: 5000; + height: 65px; + background: var(--titlebar-controls-bg); + -webkit-app-region: drag; `; export const TitlebarOutlet = () => { - const { windowBarStyle } = useWindowSettings(); + const { windowBarStyle } = useWindowSettings(); - return ( - <> - {windowBarStyle === Platform.WEB && ( - <TitlebarContainer> - <Titlebar /> - </TitlebarContainer> - )} - <Outlet /> - </> - ); + return ( + <> + {windowBarStyle === Platform.WEB && ( + <TitlebarContainer> + <Titlebar /> + </TitlebarContainer> + )} + <Outlet /> + </> + ); }; diff --git a/src/renderer/store/album-artist-list-data.store.ts b/src/renderer/store/album-artist-list-data.store.ts index cee1652f..050c84e1 100644 --- a/src/renderer/store/album-artist-list-data.store.ts +++ b/src/renderer/store/album-artist-list-data.store.ts @@ -3,35 +3,35 @@ import { devtools } from 'zustand/middleware'; import { immer } from 'zustand/middleware/immer'; export interface AlbumArtistListDataState { - itemData: any[]; + itemData: any[]; } export interface AlbumArtistListDataSlice extends AlbumArtistListDataState { - actions: { - setItemData: (data: any[]) => void; - }; + actions: { + setItemData: (data: any[]) => void; + }; } export const useAlbumArtistListDataStore = create<AlbumArtistListDataSlice>()( - devtools( - immer((set) => ({ - actions: { - setItemData: (data) => { - set((state) => { - state.itemData = data; - }); - }, - }, - itemData: [], - })), - { name: 'store_album_list_data' }, - ), + devtools( + immer((set) => ({ + actions: { + setItemData: (data) => { + set((state) => { + state.itemData = data; + }); + }, + }, + itemData: [], + })), + { name: 'store_album_list_data' }, + ), ); export const useAlbumArtistListStoreActions = () => - useAlbumArtistListDataStore((state) => state.actions); + useAlbumArtistListDataStore((state) => state.actions); export const useAlbumArtistListItemData = () => - useAlbumArtistListDataStore((state) => { - return { itemData: state.itemData, setItemData: state.actions.setItemData }; - }); + useAlbumArtistListDataStore((state) => { + return { itemData: state.itemData, setItemData: state.actions.setItemData }; + }); diff --git a/src/renderer/store/album-artist.store.ts b/src/renderer/store/album-artist.store.ts index 15303165..d8ae5d67 100644 --- a/src/renderer/store/album-artist.store.ts +++ b/src/renderer/store/album-artist.store.ts @@ -7,105 +7,108 @@ import { DataTableProps } from '/@/renderer/store/settings.store'; import { ListDisplayType, TableColumn, TablePagination } from '/@/renderer/types'; type TableProps = { - pagination: TablePagination; - scrollOffset: number; + pagination: TablePagination; + scrollOffset: number; } & DataTableProps; type ListProps<T> = { - display: ListDisplayType; - filter: T; - grid: { - scrollOffset: number; - size: number; - }; - table: TableProps; + display: ListDisplayType; + filter: T; + grid: { + scrollOffset: number; + size: number; + }; + table: TableProps; }; export type AlbumArtistListFilter = Omit<AlbumArtistListArgs['query'], 'startIndex' | 'limit'>; export interface AlbumArtistState { - list: ListProps<AlbumArtistListFilter>; + list: ListProps<AlbumArtistListFilter>; } export interface AlbumArtistSlice extends AlbumArtistState { - actions: { - setFilters: (data: Partial<AlbumArtistListFilter>) => AlbumArtistListFilter; - setStore: (data: Partial<AlbumArtistSlice>) => void; - setTable: (data: Partial<TableProps>) => void; - setTablePagination: (data: Partial<TableProps['pagination']>) => void; - }; + actions: { + setFilters: (data: Partial<AlbumArtistListFilter>) => AlbumArtistListFilter; + setStore: (data: Partial<AlbumArtistSlice>) => void; + setTable: (data: Partial<TableProps>) => void; + setTablePagination: (data: Partial<TableProps['pagination']>) => void; + }; } export const useAlbumArtistStore = create<AlbumArtistSlice>()( - persist( - devtools( - immer((set, get) => ({ - actions: { - setFilters: (data) => { - set((state) => { - state.list.filter = { ...state.list.filter, ...data }; - }); + persist( + devtools( + immer((set, get) => ({ + actions: { + setFilters: (data) => { + set((state) => { + state.list.filter = { ...state.list.filter, ...data }; + }); - return get().list.filter; - }, - setStore: (data) => { - set({ ...get(), ...data }); - }, - setTable: (data) => { - set((state) => { - state.list.table = { ...state.list.table, ...data }; - }); - }, - setTablePagination: (data) => { - set((state) => { - state.list.table.pagination = { ...state.list.table.pagination, ...data }; - }); - }, - }, - list: { - display: ListDisplayType.TABLE, - filter: { - musicFolderId: undefined, - sortBy: AlbumArtistListSort.NAME, - sortOrder: SortOrder.ASC, - }, - grid: { - scrollOffset: 0, - size: 50, - }, - table: { - autoFit: true, - columns: [ - { - column: TableColumn.ROW_INDEX, - width: 50, - }, - { - column: TableColumn.TITLE_COMBINED, - width: 500, - }, - ], - pagination: { - currentPage: 1, - itemsPerPage: 100, - totalItems: 1, - totalPages: 1, + return get().list.filter; + }, + setStore: (data) => { + set({ ...get(), ...data }); + }, + setTable: (data) => { + set((state) => { + state.list.table = { ...state.list.table, ...data }; + }); + }, + setTablePagination: (data) => { + set((state) => { + state.list.table.pagination = { + ...state.list.table.pagination, + ...data, + }; + }); + }, + }, + list: { + display: ListDisplayType.TABLE, + filter: { + musicFolderId: undefined, + sortBy: AlbumArtistListSort.NAME, + sortOrder: SortOrder.ASC, + }, + grid: { + scrollOffset: 0, + size: 50, + }, + table: { + autoFit: true, + columns: [ + { + column: TableColumn.ROW_INDEX, + width: 50, + }, + { + column: TableColumn.TITLE_COMBINED, + width: 500, + }, + ], + pagination: { + currentPage: 1, + itemsPerPage: 100, + totalItems: 1, + totalPages: 1, + }, + rowHeight: 60, + scrollOffset: 0, + }, + }, + })), + { name: 'store_album_artist' }, + ), + { + merge: (persistedState, currentState) => { + return merge(currentState, persistedState); }, - rowHeight: 60, - scrollOffset: 0, - }, + name: 'store_album_artist', + version: 1, }, - })), - { name: 'store_album_artist' }, ), - { - merge: (persistedState, currentState) => { - return merge(currentState, persistedState); - }, - name: 'store_album_artist', - version: 1, - }, - ), ); export const useAlbumArtistStoreActions = () => useAlbumArtistStore((state) => state.actions); @@ -113,14 +116,14 @@ export const useAlbumArtistStoreActions = () => useAlbumArtistStore((state) => s export const useSetAlbumArtistStore = () => useAlbumArtistStore((state) => state.actions.setStore); export const useSetAlbumArtistFilters = () => - useAlbumArtistStore((state) => state.actions.setFilters); + useAlbumArtistStore((state) => state.actions.setFilters); export const useAlbumArtistListStore = () => useAlbumArtistStore((state) => state.list); export const useAlbumArtistTablePagination = () => - useAlbumArtistStore((state) => state.list.table.pagination); + useAlbumArtistStore((state) => state.list.table.pagination); export const useSetAlbumArtistTablePagination = () => - useAlbumArtistStore((state) => state.actions.setTablePagination); + useAlbumArtistStore((state) => state.actions.setTablePagination); export const useSetAlbumArtistTable = () => useAlbumArtistStore((state) => state.actions.setTable); diff --git a/src/renderer/store/album-list-data.store.ts b/src/renderer/store/album-list-data.store.ts index c17d06fa..c79fef77 100644 --- a/src/renderer/store/album-list-data.store.ts +++ b/src/renderer/store/album-list-data.store.ts @@ -3,45 +3,45 @@ import { devtools } from 'zustand/middleware'; import { immer } from 'zustand/middleware/immer'; export interface AlbumListDataState { - itemData: any[]; + itemData: any[]; } export interface AlbumListDataSlice extends AlbumListDataState { - actions: { - setItemData: (data: any[]) => void; - setItemDataById: (id: string, data: any) => void; - }; + actions: { + setItemData: (data: any[]) => void; + setItemDataById: (id: string, data: any) => void; + }; } export const useAlbumListDataStore = create<AlbumListDataSlice>()( - devtools( - immer((set) => ({ - actions: { - setItemData: (data) => { - set((state) => { - state.itemData = data; - }); - }, - setItemDataById: (id, data) => { - set((state) => { - const index = state.itemData.findIndex((item) => item?.id === id); - if (index === -1) return; - state.itemData[index] = { ...state.itemData[index], ...data }; - }); - }, - }, - itemData: [], - })), - { name: 'store_album_list_data' }, - ), + devtools( + immer((set) => ({ + actions: { + setItemData: (data) => { + set((state) => { + state.itemData = data; + }); + }, + setItemDataById: (id, data) => { + set((state) => { + const index = state.itemData.findIndex((item) => item?.id === id); + if (index === -1) return; + state.itemData[index] = { ...state.itemData[index], ...data }; + }); + }, + }, + itemData: [], + })), + { name: 'store_album_list_data' }, + ), ); export const useAlbumListStoreActions = () => useAlbumListDataStore((state) => state.actions); export const useAlbumListItemData = () => - useAlbumListDataStore((state) => { - return { itemData: state.itemData, setItemData: state.actions.setItemData }; - }); + useAlbumListDataStore((state) => { + return { itemData: state.itemData, setItemData: state.actions.setItemData }; + }); export const useSetAlbumListItemDataById = () => - useAlbumListDataStore((state) => state.actions.setItemDataById); + useAlbumListDataStore((state) => state.actions.setItemDataById); diff --git a/src/renderer/store/app.store.ts b/src/renderer/store/app.store.ts index 068f6d8a..b4bda7bb 100644 --- a/src/renderer/store/app.store.ts +++ b/src/renderer/store/app.store.ts @@ -5,104 +5,104 @@ import { immer } from 'zustand/middleware/immer'; import { Platform } from '/@/renderer/types'; type SidebarProps = { - collapsed: boolean; - expanded: string[]; - image: boolean; - leftWidth: string; - rightExpanded: boolean; - rightWidth: string; + collapsed: boolean; + expanded: string[]; + image: boolean; + leftWidth: string; + rightExpanded: boolean; + rightWidth: string; }; type TitlebarProps = { - backgroundColor: string; - outOfView: boolean; + backgroundColor: string; + outOfView: boolean; }; type CommandPaletteProps = { - close: () => void; - open: () => void; - opened: boolean; - toggle: () => void; + close: () => void; + open: () => void; + opened: boolean; + toggle: () => void; }; export interface AppState { - commandPalette: CommandPaletteProps; - isReorderingQueue: boolean; - platform: Platform; - sidebar: SidebarProps; - titlebar: TitlebarProps; + commandPalette: CommandPaletteProps; + isReorderingQueue: boolean; + platform: Platform; + sidebar: SidebarProps; + titlebar: TitlebarProps; } export interface AppSlice extends AppState { - actions: { - setAppStore: (data: Partial<AppSlice>) => void; - setSideBar: (options: Partial<SidebarProps>) => void; - setTitleBar: (options: Partial<TitlebarProps>) => void; - }; + actions: { + setAppStore: (data: Partial<AppSlice>) => void; + setSideBar: (options: Partial<SidebarProps>) => void; + setTitleBar: (options: Partial<TitlebarProps>) => void; + }; } export const useAppStore = create<AppSlice>()( - persist( - devtools( - immer((set, get) => ({ - actions: { - setAppStore: (data) => { - set({ ...get(), ...data }); - }, - setSideBar: (options) => { - set((state) => { - state.sidebar = { ...state.sidebar, ...options }; - }); - }, - setTitleBar: (options) => { - set((state) => { - state.titlebar = { ...state.titlebar, ...options }; - }); - }, + persist( + devtools( + immer((set, get) => ({ + actions: { + setAppStore: (data) => { + set({ ...get(), ...data }); + }, + setSideBar: (options) => { + set((state) => { + state.sidebar = { ...state.sidebar, ...options }; + }); + }, + setTitleBar: (options) => { + set((state) => { + state.titlebar = { ...state.titlebar, ...options }; + }); + }, + }, + commandPalette: { + close: () => { + set((state) => { + state.commandPalette.opened = false; + }); + }, + open: () => { + set((state) => { + state.commandPalette.opened = true; + }); + }, + opened: false, + toggle: () => { + set((state) => { + state.commandPalette.opened = !state.commandPalette.opened; + }); + }, + }, + isReorderingQueue: false, + platform: Platform.WINDOWS, + sidebar: { + collapsed: false, + expanded: [], + image: false, + leftWidth: '400px', + rightExpanded: false, + rightWidth: '400px', + }, + titlebar: { + backgroundColor: '#000000', + outOfView: false, + }, + })), + { name: 'store_app' }, + ), + { + merge: (persistedState, currentState) => { + return merge(currentState, persistedState); + }, + name: 'store_app', + version: 2, }, - commandPalette: { - close: () => { - set((state) => { - state.commandPalette.opened = false; - }); - }, - open: () => { - set((state) => { - state.commandPalette.opened = true; - }); - }, - opened: false, - toggle: () => { - set((state) => { - state.commandPalette.opened = !state.commandPalette.opened; - }); - }, - }, - isReorderingQueue: false, - platform: Platform.WINDOWS, - sidebar: { - collapsed: false, - expanded: [], - image: false, - leftWidth: '400px', - rightExpanded: false, - rightWidth: '400px', - }, - titlebar: { - backgroundColor: '#000000', - outOfView: false, - }, - })), - { name: 'store_app' }, ), - { - merge: (persistedState, currentState) => { - return merge(currentState, persistedState); - }, - name: 'store_app', - version: 2, - }, - ), ); export const useAppStoreActions = () => useAppStore((state) => state.actions); diff --git a/src/renderer/store/auth.store.ts b/src/renderer/store/auth.store.ts index 6e2f731e..7fa958cd 100644 --- a/src/renderer/store/auth.store.ts +++ b/src/renderer/store/auth.store.ts @@ -9,83 +9,83 @@ import { useListStore } from '/@/renderer/store/list.store'; import { ServerListItem } from '/@/renderer/types'; export interface AuthState { - currentServer: ServerListItem | null; - deviceId: string; - serverList: Record<string, ServerListItem>; + currentServer: ServerListItem | null; + deviceId: string; + serverList: Record<string, ServerListItem>; } export interface AuthSlice extends AuthState { - actions: { - addServer: (args: ServerListItem) => void; - deleteServer: (id: string) => void; - getServer: (id: string) => ServerListItem | null; - setCurrentServer: (server: ServerListItem | null) => void; - updateServer: (id: string, args: Partial<ServerListItem>) => void; - }; + actions: { + addServer: (args: ServerListItem) => void; + deleteServer: (id: string) => void; + getServer: (id: string) => ServerListItem | null; + setCurrentServer: (server: ServerListItem | null) => void; + updateServer: (id: string, args: Partial<ServerListItem>) => void; + }; } export const useAuthStore = create<AuthSlice>()( - persist( - devtools( - immer((set, get) => ({ - actions: { - addServer: (args) => { - set((state) => { - state.serverList[args.id] = args; - }); - }, - deleteServer: (id) => { - set((state) => { - delete state.serverList[id]; + persist( + devtools( + immer((set, get) => ({ + actions: { + addServer: (args) => { + set((state) => { + state.serverList[args.id] = args; + }); + }, + deleteServer: (id) => { + set((state) => { + delete state.serverList[id]; - if (state.currentServer?.id === id) { - state.currentServer = null; - } - }); - }, - getServer: (id) => { - const server = get().serverList[id]; - if (server) return server; - return null; - }, - setCurrentServer: (server) => { - set((state) => { - state.currentServer = server; + if (state.currentServer?.id === id) { + state.currentServer = null; + } + }); + }, + getServer: (id) => { + const server = get().serverList[id]; + if (server) return server; + return null; + }, + setCurrentServer: (server) => { + set((state) => { + state.currentServer = server; - if (server) { - // Reset list filters - useListStore.getState()._actions.resetFilter(); + if (server) { + // Reset list filters + useListStore.getState()._actions.resetFilter(); - // Reset persisted grid list stores - useAlbumListDataStore.getState().actions.setItemData([]); - useAlbumArtistListDataStore.getState().actions.setItemData([]); - } - }); - }, - updateServer: (id: string, args: Partial<ServerListItem>) => { - set((state) => { - const updatedServer = { - ...state.serverList[id], - ...args, - }; + // Reset persisted grid list stores + useAlbumListDataStore.getState().actions.setItemData([]); + useAlbumArtistListDataStore.getState().actions.setItemData([]); + } + }); + }, + updateServer: (id: string, args: Partial<ServerListItem>) => { + set((state) => { + const updatedServer = { + ...state.serverList[id], + ...args, + }; - state.serverList[id] = updatedServer; - state.currentServer = updatedServer; - }); - }, + state.serverList[id] = updatedServer; + state.currentServer = updatedServer; + }); + }, + }, + currentServer: null, + deviceId: nanoid(), + serverList: {}, + })), + { name: 'store_authentication' }, + ), + { + merge: (persistedState, currentState) => merge(currentState, persistedState), + name: 'store_authentication', + version: 2, }, - currentServer: null, - deviceId: nanoid(), - serverList: {}, - })), - { name: 'store_authentication' }, ), - { - merge: (persistedState, currentState) => merge(currentState, persistedState), - name: 'store_authentication', - version: 2, - }, - ), ); export const useCurrentServerId = () => useAuthStore((state) => state.currentServer)?.id || ''; @@ -97,9 +97,9 @@ export const useServerList = () => useAuthStore((state) => state.serverList); export const useAuthStoreActions = () => useAuthStore((state) => state.actions); export const getServerById = (id?: string) => { - if (!id) { - return null; - } + if (!id) { + return null; + } - return useAuthStore.getState().actions.getServer(id); + return useAuthStore.getState().actions.getServer(id); }; diff --git a/src/renderer/store/full-screen-player.store.ts b/src/renderer/store/full-screen-player.store.ts index 12d172d0..b7ed212e 100644 --- a/src/renderer/store/full-screen-player.store.ts +++ b/src/renderer/store/full-screen-player.store.ts @@ -4,46 +4,46 @@ import { devtools, persist } from 'zustand/middleware'; import { immer } from 'zustand/middleware/immer'; interface FullScreenPlayerState { - activeTab: string | 'queue' | 'related' | 'lyrics'; - dynamicBackground?: boolean; - expanded: boolean; - useImageAspectRatio: boolean; + activeTab: string | 'queue' | 'related' | 'lyrics'; + dynamicBackground?: boolean; + expanded: boolean; + useImageAspectRatio: boolean; } export interface FullScreenPlayerSlice extends FullScreenPlayerState { - actions: { - setStore: (data: Partial<FullScreenPlayerSlice>) => void; - }; + actions: { + setStore: (data: Partial<FullScreenPlayerSlice>) => void; + }; } export const useFullScreenPlayerStore = create<FullScreenPlayerSlice>()( - persist( - devtools( - immer((set, get) => ({ - actions: { - setStore: (data) => { - set({ ...get(), ...data }); - }, + persist( + devtools( + immer((set, get) => ({ + actions: { + setStore: (data) => { + set({ ...get(), ...data }); + }, + }, + activeTab: 'queue', + dynamicBackground: true, + expanded: false, + useImageAspectRatio: false, + })), + { name: 'store_full_screen_player' }, + ), + { + merge: (persistedState, currentState) => { + return merge(currentState, persistedState); + }, + name: 'store_full_screen_player', + version: 2, }, - activeTab: 'queue', - dynamicBackground: true, - expanded: false, - useImageAspectRatio: false, - })), - { name: 'store_full_screen_player' }, ), - { - merge: (persistedState, currentState) => { - return merge(currentState, persistedState); - }, - name: 'store_full_screen_player', - version: 2, - }, - ), ); export const useFullScreenPlayerStoreActions = () => - useFullScreenPlayerStore((state) => state.actions); + useFullScreenPlayerStore((state) => state.actions); export const useSetFullScreenPlayerStore = () => - useFullScreenPlayerStore((state) => state.actions.setStore); + useFullScreenPlayerStore((state) => state.actions.setStore); diff --git a/src/renderer/store/list.store.ts b/src/renderer/store/list.store.ts index 51e699b9..9d53fbd3 100644 --- a/src/renderer/store/list.store.ts +++ b/src/renderer/store/list.store.ts @@ -4,21 +4,21 @@ import { devtools, persist } from 'zustand/middleware'; import { immer } from 'zustand/middleware/immer'; import { shallow } from 'zustand/shallow'; import { - AlbumArtistListArgs, - AlbumArtistListSort, - AlbumListArgs, - AlbumListSort, - LibraryItem, - PlaylistListSort, - SongListArgs, - SongListSort, - SortOrder, + AlbumArtistListArgs, + AlbumArtistListSort, + AlbumListArgs, + AlbumListSort, + LibraryItem, + PlaylistListSort, + SongListArgs, + SongListSort, + SortOrder, } from '/@/renderer/api/types'; import { DataTableProps, PersistedTableColumn } from '/@/renderer/store/settings.store'; import { ListDisplayType, TableColumn, TablePagination } from '/@/renderer/types'; export const generatePageKey = (page: string, id?: string) => { - return id ? `${page}_${id}` : page; + return id ? `${page}_${id}` : page; }; export type AlbumListFilter = Omit<AlbumListArgs['query'], 'startIndex' | 'limit'>; @@ -30,528 +30,539 @@ export type ListKey = keyof ListState['item'] | string; type FilterType = AlbumListFilter | SongListFilter | AlbumArtistListFilter; type ListTableProps = { - pagination: TablePagination; - scrollOffset: number; + pagination: TablePagination; + scrollOffset: number; } & DataTableProps; type ListGridProps = { - itemsPerRow?: number; - scrollOffset?: number; + itemsPerRow?: number; + scrollOffset?: number; }; type ItemProps<TFilter = any> = { - display: ListDisplayType; - filter: TFilter; - grid?: ListGridProps; - table: ListTableProps; + display: ListDisplayType; + filter: TFilter; + grid?: ListGridProps; + table: ListTableProps; }; export interface ListState { - detail: { - [key: string]: Omit<ItemProps<any>, 'display'>; - }; - item: { - album: ItemProps<AlbumListFilter>; - albumArtist: ItemProps<AlbumArtistListFilter>; - albumDetail: ItemProps<any>; - song: ItemProps<SongListFilter>; - }; + detail: { + [key: string]: Omit<ItemProps<any>, 'display'>; + }; + item: { + album: ItemProps<AlbumListFilter>; + albumArtist: ItemProps<AlbumArtistListFilter>; + albumDetail: ItemProps<any>; + song: ItemProps<SongListFilter>; + }; } type DeterministicArgs = { key: ListKey }; export interface ListSlice extends ListState { - _actions: { - getFilter: (args: { id?: string; itemType: LibraryItem; key?: string }) => FilterType; - resetFilter: () => void; - setDisplayType: (args: { data: ListDisplayType } & DeterministicArgs) => void; - setFilter: ( - args: { data: Partial<FilterType>; itemType: LibraryItem } & DeterministicArgs, - ) => FilterType; - setGrid: (args: { data: Partial<ListGridProps> } & DeterministicArgs) => void; - setStore: (data: Partial<ListSlice>) => void; - setTable: (args: { data: Partial<ListTableProps> } & DeterministicArgs) => void; - setTableColumns: (args: { data: PersistedTableColumn[] } & DeterministicArgs) => void; - setTablePagination: (args: { data: Partial<TablePagination> } & DeterministicArgs) => void; - }; + _actions: { + getFilter: (args: { id?: string; itemType: LibraryItem; key?: string }) => FilterType; + resetFilter: () => void; + setDisplayType: (args: { data: ListDisplayType } & DeterministicArgs) => void; + setFilter: ( + args: { data: Partial<FilterType>; itemType: LibraryItem } & DeterministicArgs, + ) => FilterType; + setGrid: (args: { data: Partial<ListGridProps> } & DeterministicArgs) => void; + setStore: (data: Partial<ListSlice>) => void; + setTable: (args: { data: Partial<ListTableProps> } & DeterministicArgs) => void; + setTableColumns: (args: { data: PersistedTableColumn[] } & DeterministicArgs) => void; + setTablePagination: (args: { data: Partial<TablePagination> } & DeterministicArgs) => void; + }; } export const useListStore = create<ListSlice>()( - persist( - devtools( - immer((set, get) => ({ - _actions: { - getFilter: (args) => { - const state = get(); + persist( + devtools( + immer((set, get) => ({ + _actions: { + getFilter: (args) => { + const state = get(); - if (args.id && args.key) { - return { - artistIds: [args.id], - ...state.item.song.filter, - ...state.detail[args.key]?.filter, - _custom: { - ...state.detail[args.key]?.filter?._custom, - jellyfin: { - ...state.detail[args.key]?.filter?._custom?.jellyfin, - includeItemTypes: args?.itemType === LibraryItem.ALBUM ? 'MusicAlbum' : 'Audio', - }, - navidrome: { - ...state.detail[args.key]?.filter?._custom?.navidrome, - }, - }, - }; - } + if (args.id && args.key) { + return { + artistIds: [args.id], + ...state.item.song.filter, + ...state.detail[args.key]?.filter, + _custom: { + ...state.detail[args.key]?.filter?._custom, + jellyfin: { + ...state.detail[args.key]?.filter?._custom?.jellyfin, + includeItemTypes: + args?.itemType === LibraryItem.ALBUM + ? 'MusicAlbum' + : 'Audio', + }, + navidrome: { + ...state.detail[args.key]?.filter?._custom?.navidrome, + }, + }, + }; + } - if (args.key) { - return state.item[args.key as keyof ListState['item']].filter; - } + if (args.key) { + return state.item[args.key as keyof ListState['item']].filter; + } - return state.item.song.filter; - }, - resetFilter: () => { - set((state) => { - state.item.album.filter = { - musicFolderId: undefined, - sortBy: AlbumListSort.RECENTLY_ADDED, - sortOrder: SortOrder.DESC, - } as AlbumListFilter; - - state.item.song.filter = { - musicFolderId: undefined, - sortBy: SongListSort.RECENTLY_ADDED, - sortOrder: SortOrder.DESC, - } as SongListFilter; - }); - }, - setDisplayType: (args) => { - set((state) => { - const [page] = args.key.split('_'); - state.item[page as keyof ListState['item']].display = args.data; - }); - }, - setFilter: (args) => { - const [, id] = args.key.split('_'); - - set((state) => { - if (id) { - if (!state.detail[args.key]) { - state.detail[args.key] = { - filter: {} as FilterType, - table: { - pagination: { - currentPage: 1, - itemsPerPage: 100, - totalItems: 0, - totalPages: 0, - }, - } as ListTableProps, - }; - } - - state.detail[args.key].filter = { - ...state.detail[args.key as keyof ListState['item']].filter, - ...args.data, - } as FilterType; - } else { - state.item[args.key as keyof ListState['item']].filter = { - ...state.item[args.key as keyof ListState['item']].filter, - ...args.data, - } as FilterType; - } - }); - - return get()._actions.getFilter({ id, itemType: args.itemType, key: args.key }); - }, - setGrid: (args) => { - const [page, id] = args.key.split('_'); - - set((state) => { - if (id) { - if (!state.detail[args.key]) { - state.detail[args.key] = { - filter: {} as FilterType, - grid: { - itemsPerRow: - state.item[page as keyof ListState['item']].grid?.itemsPerRow || 5, - scrollOffset: 0, + return state.item.song.filter; }, - table: { - pagination: { - currentPage: 1, - itemsPerPage: 100, - totalItems: 0, - totalPages: 0, - }, - } as ListTableProps, - }; - } + resetFilter: () => { + set((state) => { + state.item.album.filter = { + musicFolderId: undefined, + sortBy: AlbumListSort.RECENTLY_ADDED, + sortOrder: SortOrder.DESC, + } as AlbumListFilter; - if (state.detail[args.key as keyof ListState['item']].grid) { - state.detail[args.key as keyof ListState['item']].grid = { - ...state.detail[args.key as keyof ListState['item']]?.grid, - ...args.data, - }; - } - } else if (state.item[page as keyof ListState['item']].grid) { - state.item[page as keyof ListState['item']].grid = { - ...state.item[page as keyof ListState['item']]?.grid, - ...args.data, - }; - } - }); - }, - setStore: (data) => { - set({ ...get(), ...data }); - }, - setTable: (args) => { - set((state) => { - const [page, id] = args.key.split('_'); + state.item.song.filter = { + musicFolderId: undefined, + sortBy: SongListSort.RECENTLY_ADDED, + sortOrder: SortOrder.DESC, + } as SongListFilter; + }); + }, + setDisplayType: (args) => { + set((state) => { + const [page] = args.key.split('_'); + state.item[page as keyof ListState['item']].display = args.data; + }); + }, + setFilter: (args) => { + const [, id] = args.key.split('_'); - if (id) { - if (!state.detail[args.key]) { - state.detail[args.key] = { - filter: { - ...state.item[page as keyof ListState['item']].filter, - } as FilterType, - table: { - pagination: { - currentPage: 1, - itemsPerPage: 100, - totalItems: 0, - totalPages: 0, - }, - scrollOffset: 0, - } as ListTableProps, - }; - } + set((state) => { + if (id) { + if (!state.detail[args.key]) { + state.detail[args.key] = { + filter: {} as FilterType, + table: { + pagination: { + currentPage: 1, + itemsPerPage: 100, + totalItems: 0, + totalPages: 0, + }, + } as ListTableProps, + }; + } - if (state.detail[args.key as keyof ListState['item']].table) { - state.detail[args.key as keyof ListState['item']].table = { - ...state.detail[args.key as keyof ListState['item']]?.table, - ...args.data, - }; - } - } else { - state.item[page as keyof ListState['item']].table = { - ...state.item[page as keyof ListState['item']].table, - ...args.data, - }; - } - }); - }, - setTableColumns: (args) => { - set((state) => { - state.item[args.key as keyof ListState['item']].table.columns = { - ...state.item[args.key as keyof ListState['item']].table.columns, - ...args.data, - }; - }); - }, - setTablePagination: (args) => { - set((state) => { - const [, id] = args.key.split('_'); + state.detail[args.key].filter = { + ...state.detail[args.key as keyof ListState['item']].filter, + ...args.data, + } as FilterType; + } else { + state.item[args.key as keyof ListState['item']].filter = { + ...state.item[args.key as keyof ListState['item']].filter, + ...args.data, + } as FilterType; + } + }); - if (id) { - if (!state.detail[args.key]) { - state.detail[args.key] = { - filter: {} as FilterType, - table: { - pagination: { - currentPage: 1, - itemsPerPage: 100, - totalItems: 0, - totalPages: 0, - }, - } as ListTableProps, - }; - } + return get()._actions.getFilter({ + id, + itemType: args.itemType, + key: args.key, + }); + }, + setGrid: (args) => { + const [page, id] = args.key.split('_'); - state.detail[args.key as keyof ListState['item']].table.pagination = { - ...state.detail[args.key as keyof ListState['item']].table.pagination, - ...args.data, - }; - } else { - state.item[args.key as keyof ListState['item']].table.pagination = { - ...state.item[args.key as keyof ListState['item']].table.pagination, - ...args.data, - }; - } - }); - }, + set((state) => { + if (id) { + if (!state.detail[args.key]) { + state.detail[args.key] = { + filter: {} as FilterType, + grid: { + itemsPerRow: + state.item[page as keyof ListState['item']].grid + ?.itemsPerRow || 5, + scrollOffset: 0, + }, + table: { + pagination: { + currentPage: 1, + itemsPerPage: 100, + totalItems: 0, + totalPages: 0, + }, + } as ListTableProps, + }; + } + + if (state.detail[args.key as keyof ListState['item']].grid) { + state.detail[args.key as keyof ListState['item']].grid = { + ...state.detail[args.key as keyof ListState['item']]?.grid, + ...args.data, + }; + } + } else if (state.item[page as keyof ListState['item']].grid) { + state.item[page as keyof ListState['item']].grid = { + ...state.item[page as keyof ListState['item']]?.grid, + ...args.data, + }; + } + }); + }, + setStore: (data) => { + set({ ...get(), ...data }); + }, + setTable: (args) => { + set((state) => { + const [page, id] = args.key.split('_'); + + if (id) { + if (!state.detail[args.key]) { + state.detail[args.key] = { + filter: { + ...state.item[page as keyof ListState['item']].filter, + } as FilterType, + table: { + pagination: { + currentPage: 1, + itemsPerPage: 100, + totalItems: 0, + totalPages: 0, + }, + scrollOffset: 0, + } as ListTableProps, + }; + } + + if (state.detail[args.key as keyof ListState['item']].table) { + state.detail[args.key as keyof ListState['item']].table = { + ...state.detail[args.key as keyof ListState['item']]?.table, + ...args.data, + }; + } + } else { + state.item[page as keyof ListState['item']].table = { + ...state.item[page as keyof ListState['item']].table, + ...args.data, + }; + } + }); + }, + setTableColumns: (args) => { + set((state) => { + state.item[args.key as keyof ListState['item']].table.columns = { + ...state.item[args.key as keyof ListState['item']].table.columns, + ...args.data, + }; + }); + }, + setTablePagination: (args) => { + set((state) => { + const [, id] = args.key.split('_'); + + if (id) { + if (!state.detail[args.key]) { + state.detail[args.key] = { + filter: {} as FilterType, + table: { + pagination: { + currentPage: 1, + itemsPerPage: 100, + totalItems: 0, + totalPages: 0, + }, + } as ListTableProps, + }; + } + + state.detail[args.key as keyof ListState['item']].table.pagination = + { + ...state.detail[args.key as keyof ListState['item']].table + .pagination, + ...args.data, + }; + } else { + state.item[args.key as keyof ListState['item']].table.pagination = { + ...state.item[args.key as keyof ListState['item']].table + .pagination, + ...args.data, + }; + } + }); + }, + }, + detail: {}, + item: { + album: { + display: ListDisplayType.POSTER, + filter: { + sortBy: AlbumListSort.RECENTLY_ADDED, + sortOrder: SortOrder.DESC, + }, + grid: { itemsPerRow: 5, scrollOffset: 0 }, + table: { + autoFit: true, + columns: [ + { + column: TableColumn.ROW_INDEX, + width: 50, + }, + { + column: TableColumn.TITLE_COMBINED, + width: 500, + }, + { + column: TableColumn.DURATION, + width: 100, + }, + { + column: TableColumn.ALBUM_ARTIST, + width: 300, + }, + { + column: TableColumn.YEAR, + width: 100, + }, + ], + pagination: { + currentPage: 1, + itemsPerPage: 100, + totalItems: 1, + totalPages: 1, + }, + rowHeight: 60, + scrollOffset: 0, + }, + }, + albumArtist: { + display: ListDisplayType.POSTER, + filter: { + sortBy: AlbumArtistListSort.NAME, + sortOrder: SortOrder.DESC, + }, + grid: { itemsPerRow: 5, scrollOffset: 0 }, + table: { + autoFit: true, + columns: [ + { + column: TableColumn.ROW_INDEX, + width: 50, + }, + { + column: TableColumn.TITLE_COMBINED, + width: 500, + }, + ], + pagination: { + currentPage: 1, + itemsPerPage: 100, + totalItems: 1, + totalPages: 1, + }, + rowHeight: 60, + scrollOffset: 0, + }, + }, + albumDetail: { + display: ListDisplayType.TABLE, + filter: { + sortBy: SongListSort.ALBUM, + sortOrder: SortOrder.ASC, + }, + table: { + autoFit: true, + columns: [], + followCurrentSong: false, + pagination: { + currentPage: 1, + itemsPerPage: 100, + totalItems: 1, + totalPages: 1, + }, + rowHeight: 60, + scrollOffset: 0, + }, + }, + playlist: { + display: ListDisplayType.POSTER, + filter: { + sortBy: PlaylistListSort.NAME, + sortOrder: SortOrder.DESC, + }, + grid: { scrollOffset: 0, size: 0 }, + table: { + autoFit: true, + columns: [ + { + column: TableColumn.ROW_INDEX, + width: 50, + }, + { + column: TableColumn.TITLE_COMBINED, + width: 500, + }, + { + column: TableColumn.DURATION, + width: 100, + }, + { + column: TableColumn.ALBUM, + width: 500, + }, + ], + pagination: { + currentPage: 1, + itemsPerPage: 100, + totalItems: 1, + totalPages: 1, + }, + rowHeight: 60, + scrollOffset: 0, + }, + }, + song: { + display: ListDisplayType.POSTER, + filter: { + sortBy: SongListSort.RECENTLY_ADDED, + sortOrder: SortOrder.DESC, + }, + grid: { itemsPerRow: 5, scrollOffset: 0 }, + table: { + autoFit: true, + columns: [ + { + column: TableColumn.ROW_INDEX, + width: 50, + }, + { + column: TableColumn.TITLE_COMBINED, + width: 500, + }, + { + column: TableColumn.DURATION, + width: 100, + }, + { + column: TableColumn.ALBUM, + width: 300, + }, + { + column: TableColumn.ARTIST, + width: 100, + }, + { + column: TableColumn.YEAR, + width: 100, + }, + { + column: TableColumn.DATE_ADDED, + width: 100, + }, + { + column: TableColumn.PLAY_COUNT, + width: 100, + }, + ], + pagination: { + currentPage: 1, + itemsPerPage: 100, + totalItems: 1, + totalPages: 1, + }, + rowHeight: 60, + scrollOffset: 0, + }, + }, + }, + })), + { name: 'store_list' }, + ), + { + merge: (persistedState, currentState) => { + return merge(currentState, persistedState); + }, + name: 'store_list', + partialize: (state) => { + return Object.fromEntries( + Object.entries(state).filter(([key]) => !['detail'].includes(key)), + ); + }, + version: 2, }, - detail: {}, - item: { - album: { - display: ListDisplayType.POSTER, - filter: { - sortBy: AlbumListSort.RECENTLY_ADDED, - sortOrder: SortOrder.DESC, - }, - grid: { itemsPerRow: 5, scrollOffset: 0 }, - table: { - autoFit: true, - columns: [ - { - column: TableColumn.ROW_INDEX, - width: 50, - }, - { - column: TableColumn.TITLE_COMBINED, - width: 500, - }, - { - column: TableColumn.DURATION, - width: 100, - }, - { - column: TableColumn.ALBUM_ARTIST, - width: 300, - }, - { - column: TableColumn.YEAR, - width: 100, - }, - ], - pagination: { - currentPage: 1, - itemsPerPage: 100, - totalItems: 1, - totalPages: 1, - }, - rowHeight: 60, - scrollOffset: 0, - }, - }, - albumArtist: { - display: ListDisplayType.POSTER, - filter: { - sortBy: AlbumArtistListSort.NAME, - sortOrder: SortOrder.DESC, - }, - grid: { itemsPerRow: 5, scrollOffset: 0 }, - table: { - autoFit: true, - columns: [ - { - column: TableColumn.ROW_INDEX, - width: 50, - }, - { - column: TableColumn.TITLE_COMBINED, - width: 500, - }, - ], - pagination: { - currentPage: 1, - itemsPerPage: 100, - totalItems: 1, - totalPages: 1, - }, - rowHeight: 60, - scrollOffset: 0, - }, - }, - albumDetail: { - display: ListDisplayType.TABLE, - filter: { - sortBy: SongListSort.ALBUM, - sortOrder: SortOrder.ASC, - }, - table: { - autoFit: true, - columns: [], - followCurrentSong: false, - pagination: { - currentPage: 1, - itemsPerPage: 100, - totalItems: 1, - totalPages: 1, - }, - rowHeight: 60, - scrollOffset: 0, - }, - }, - playlist: { - display: ListDisplayType.POSTER, - filter: { - sortBy: PlaylistListSort.NAME, - sortOrder: SortOrder.DESC, - }, - grid: { scrollOffset: 0, size: 0 }, - table: { - autoFit: true, - columns: [ - { - column: TableColumn.ROW_INDEX, - width: 50, - }, - { - column: TableColumn.TITLE_COMBINED, - width: 500, - }, - { - column: TableColumn.DURATION, - width: 100, - }, - { - column: TableColumn.ALBUM, - width: 500, - }, - ], - pagination: { - currentPage: 1, - itemsPerPage: 100, - totalItems: 1, - totalPages: 1, - }, - rowHeight: 60, - scrollOffset: 0, - }, - }, - song: { - display: ListDisplayType.POSTER, - filter: { - sortBy: SongListSort.RECENTLY_ADDED, - sortOrder: SortOrder.DESC, - }, - grid: { itemsPerRow: 5, scrollOffset: 0 }, - table: { - autoFit: true, - columns: [ - { - column: TableColumn.ROW_INDEX, - width: 50, - }, - { - column: TableColumn.TITLE_COMBINED, - width: 500, - }, - { - column: TableColumn.DURATION, - width: 100, - }, - { - column: TableColumn.ALBUM, - width: 300, - }, - { - column: TableColumn.ARTIST, - width: 100, - }, - { - column: TableColumn.YEAR, - width: 100, - }, - { - column: TableColumn.DATE_ADDED, - width: 100, - }, - { - column: TableColumn.PLAY_COUNT, - width: 100, - }, - ], - pagination: { - currentPage: 1, - itemsPerPage: 100, - totalItems: 1, - totalPages: 1, - }, - rowHeight: 60, - scrollOffset: 0, - }, - }, - }, - })), - { name: 'store_list' }, ), - { - merge: (persistedState, currentState) => { - return merge(currentState, persistedState); - }, - name: 'store_list', - partialize: (state) => { - return Object.fromEntries( - Object.entries(state).filter(([key]) => !['detail'].includes(key)), - ); - }, - version: 2, - }, - ), ); export const useListStoreActions = () => useListStore((state) => state._actions); export const useAlbumListStore = (args?: { id?: string; key?: string }) => - useListStore((state) => { - const detail = args?.key ? state.detail[args.key] : undefined; + useListStore((state) => { + const detail = args?.key ? state.detail[args.key] : undefined; - return { - ...state.item.album, - filter: { - ...state.item.album.filter, - ...detail?.filter, - }, - grid: { - ...state.item.album.grid, - ...detail?.grid, - }, - table: { - ...state.item.album.table, - ...detail?.table, - }, - }; - }, shallow); + return { + ...state.item.album, + filter: { + ...state.item.album.filter, + ...detail?.filter, + }, + grid: { + ...state.item.album.grid, + ...detail?.grid, + }, + table: { + ...state.item.album.table, + ...detail?.table, + }, + }; + }, shallow); export const useAlbumArtistListStore = () => - useListStore((state) => state.item.albumArtist, shallow); + useListStore((state) => state.item.albumArtist, shallow); export const useSongListStore = (args?: { id?: string; key?: string }) => - useListStore((state) => { - const detail = args?.key ? state.detail[args.key] : undefined; + useListStore((state) => { + const detail = args?.key ? state.detail[args.key] : undefined; - return { - ...state.item.song, - filter: { - ...state.item.song.filter, - ...detail?.filter, - }, - grid: { - ...state.item.song.grid, - ...detail?.grid, - }, - table: { - ...state.item.song.table, - ...detail?.table, - }, - }; - }, shallow); + return { + ...state.item.song, + filter: { + ...state.item.song.filter, + ...detail?.filter, + }, + grid: { + ...state.item.song.grid, + ...detail?.grid, + }, + table: { + ...state.item.song.table, + ...detail?.table, + }, + }; + }, shallow); export const useSongListFilter = (args: { id?: string; key?: string }) => - useListStore((state) => { - return state._actions.getFilter({ - id: args.id, - itemType: LibraryItem.SONG, - key: args.key, - }) as SongListFilter; - }, shallow); + useListStore((state) => { + return state._actions.getFilter({ + id: args.id, + itemType: LibraryItem.SONG, + key: args.key, + }) as SongListFilter; + }, shallow); export const useAlbumListFilter = (args: { id?: string; key?: string }) => - useListStore((state) => { - return state._actions.getFilter({ - id: args.id, - itemType: LibraryItem.ALBUM, - key: args.key, - }) as AlbumListFilter; - }, shallow); + useListStore((state) => { + return state._actions.getFilter({ + id: args.id, + itemType: LibraryItem.ALBUM, + key: args.key, + }) as AlbumListFilter; + }, shallow); export const useAlbumArtistListFilter = (args: { id?: string; key?: string }) => - useListStore((state) => { - return state._actions.getFilter({ - id: args.id, - itemType: LibraryItem.ALBUM_ARTIST, - key: args.key, - }) as AlbumArtistListFilter; - }, shallow); + useListStore((state) => { + return state._actions.getFilter({ + id: args.id, + itemType: LibraryItem.ALBUM_ARTIST, + key: args.key, + }) as AlbumArtistListFilter; + }, shallow); export const useListDetail = (key: string) => useListStore((state) => state.detail[key], shallow); diff --git a/src/renderer/store/player.store.ts b/src/renderer/store/player.store.ts index 756aad0b..ddaf86cd 100644 --- a/src/renderer/store/player.store.ts +++ b/src/renderer/store/player.store.ts @@ -10,937 +10,979 @@ import { QueueSong } from '/@/renderer/api/types'; import { PlayerStatus, PlayerRepeat, PlayerShuffle, Play } from '/@/renderer/types'; export interface PlayerState { - current: { - index: number; - nextIndex: number; - player: 1 | 2; - previousIndex: number; - seek: boolean; - shuffledIndex: number; - song?: QueueSong; - status: PlayerStatus; - time: number; - }; - muted: boolean; - queue: { - default: QueueSong[]; - previousNode?: QueueSong; - shuffled: string[]; - sorted: QueueSong[]; - }; - repeat: PlayerRepeat; - shuffle: PlayerShuffle; - volume: number; + current: { + index: number; + nextIndex: number; + player: 1 | 2; + previousIndex: number; + seek: boolean; + shuffledIndex: number; + song?: QueueSong; + status: PlayerStatus; + time: number; + }; + muted: boolean; + queue: { + default: QueueSong[]; + previousNode?: QueueSong; + shuffled: string[]; + sorted: QueueSong[]; + }; + repeat: PlayerRepeat; + shuffle: PlayerShuffle; + volume: number; } export interface PlayerData { - current: { - index: number; - nextIndex?: number; - player: 1 | 2; - previousIndex?: number; - shuffledIndex: number; - song?: QueueSong; - status: PlayerStatus; - }; - player1?: QueueSong; - player2?: QueueSong; - queue: QueueData; + current: { + index: number; + nextIndex?: number; + player: 1 | 2; + previousIndex?: number; + shuffledIndex: number; + song?: QueueSong; + status: PlayerStatus; + }; + player1?: QueueSong; + player2?: QueueSong; + queue: QueueData; } export interface QueueData { - current?: QueueSong; - length: number; - next?: QueueSong; - previous?: QueueSong; + current?: QueueSong; + length: number; + next?: QueueSong; + previous?: QueueSong; } export interface PlayerSlice extends PlayerState { - actions: { - addToQueue: (args: { initialIndex: number; playType: Play; songs: QueueSong[] }) => PlayerData; - autoNext: () => PlayerData; - checkIsFirstTrack: () => boolean; - checkIsLastTrack: (type?: 'next' | 'prev') => boolean; - clearQueue: () => PlayerData; - getPlayerData: () => PlayerData; - getQueueData: () => QueueData; - incrementPlayCount: (ids: string[]) => string[]; - moveToBottomOfQueue: (uniqueIds: string[]) => PlayerData; - moveToTopOfQueue: (uniqueIds: string[]) => PlayerData; - next: () => PlayerData; - pause: () => void; - play: () => void; - player1: () => QueueSong | undefined; - player2: () => QueueSong | undefined; - previous: () => PlayerData; - removeFromQueue: (uniqueIds: string[]) => PlayerData; - reorderQueue: (rowUniqueIds: string[], afterUniqueId?: string) => PlayerData; - restoreQueue: (data: Partial<PlayerState>) => PlayerData; - setCurrentIndex: (index: number) => PlayerData; - setCurrentTime: (time: number, seek?: boolean) => void; - setCurrentTrack: (uniqueId: string) => PlayerData; - setFavorite: (ids: string[], favorite: boolean) => string[]; - setMuted: (muted: boolean) => void; - setRating: (ids: string[], rating: number | null) => string[]; - setRepeat: (type: PlayerRepeat) => PlayerData; - setShuffle: (type: PlayerShuffle) => PlayerData; - setShuffledIndex: (index: number) => PlayerData; - setStore: (data: Partial<PlayerState>) => void; - setVolume: (volume: number) => void; - shuffleQueue: () => PlayerData; - }; + actions: { + addToQueue: (args: { + initialIndex: number; + playType: Play; + songs: QueueSong[]; + }) => PlayerData; + autoNext: () => PlayerData; + checkIsFirstTrack: () => boolean; + checkIsLastTrack: (type?: 'next' | 'prev') => boolean; + clearQueue: () => PlayerData; + getPlayerData: () => PlayerData; + getQueueData: () => QueueData; + incrementPlayCount: (ids: string[]) => string[]; + moveToBottomOfQueue: (uniqueIds: string[]) => PlayerData; + moveToTopOfQueue: (uniqueIds: string[]) => PlayerData; + next: () => PlayerData; + pause: () => void; + play: () => void; + player1: () => QueueSong | undefined; + player2: () => QueueSong | undefined; + previous: () => PlayerData; + removeFromQueue: (uniqueIds: string[]) => PlayerData; + reorderQueue: (rowUniqueIds: string[], afterUniqueId?: string) => PlayerData; + restoreQueue: (data: Partial<PlayerState>) => PlayerData; + setCurrentIndex: (index: number) => PlayerData; + setCurrentTime: (time: number, seek?: boolean) => void; + setCurrentTrack: (uniqueId: string) => PlayerData; + setFavorite: (ids: string[], favorite: boolean) => string[]; + setMuted: (muted: boolean) => void; + setRating: (ids: string[], rating: number | null) => string[]; + setRepeat: (type: PlayerRepeat) => PlayerData; + setShuffle: (type: PlayerShuffle) => PlayerData; + setShuffledIndex: (index: number) => PlayerData; + setStore: (data: Partial<PlayerState>) => void; + setVolume: (volume: number) => void; + shuffleQueue: () => PlayerData; + }; } export const usePlayerStore = create<PlayerSlice>()( - subscribeWithSelector( - persist( - devtools( - immer((set, get) => ({ - actions: { - addToQueue: (args) => { - const { initialIndex, playType, songs } = args; - const { shuffledIndex } = get().current; - const shuffledQueue = get().queue.shuffled; - const songsToAddToQueue = map(songs, (song) => ({ - ...song, - uniqueId: nanoid(), - })); + subscribeWithSelector( + persist( + devtools( + immer((set, get) => ({ + actions: { + addToQueue: (args) => { + const { initialIndex, playType, songs } = args; + const { shuffledIndex } = get().current; + const shuffledQueue = get().queue.shuffled; + const songsToAddToQueue = map(songs, (song) => ({ + ...song, + uniqueId: nanoid(), + })); - if (playType === Play.NOW) { - if (get().shuffle === PlayerShuffle.TRACK) { - const index = initialIndex || 0; - const initialSong = songsToAddToQueue[index]; - const queueCopy = [...songsToAddToQueue]; + if (playType === Play.NOW) { + if (get().shuffle === PlayerShuffle.TRACK) { + const index = initialIndex || 0; + const initialSong = songsToAddToQueue[index]; + const queueCopy = [...songsToAddToQueue]; - // Splice the initial song from the queue - queueCopy.splice(index, 1); + // Splice the initial song from the queue + queueCopy.splice(index, 1); - const shuffledSongIndicesWithoutInitial = shuffle(queueCopy).map( - (song) => song.uniqueId, - ); + const shuffledSongIndicesWithoutInitial = shuffle( + queueCopy, + ).map((song) => song.uniqueId); - // Add the initial song to the start of the shuffled queue - const shuffledSongIndices = [ - initialSong.uniqueId, - ...shuffledSongIndicesWithoutInitial, - ]; + // Add the initial song to the start of the shuffled queue + const shuffledSongIndices = [ + initialSong.uniqueId, + ...shuffledSongIndicesWithoutInitial, + ]; - set((state) => { - state.queue.shuffled = shuffledSongIndices; - state.queue.default = songsToAddToQueue; - state.current.time = 0; - state.current.player = 1; - state.current.index = 0; - state.current.shuffledIndex = 0; - state.current.song = initialSong; - }); - } else { - const index = initialIndex || 0; - set((state) => { - state.queue.default = songsToAddToQueue; - state.current.time = 0; - state.current.player = 1; - state.current.index = index; - state.current.shuffledIndex = 0; - state.current.song = songsToAddToQueue[index]; - }); - } - } else if (playType === Play.LAST) { - // Shuffle the queue after the current track - const shuffledQueueWithNewSongs = - get().shuffle === PlayerShuffle.TRACK - ? [ - ...shuffledQueue.slice(0, shuffledIndex + 1), - ...shuffle([ - ...songsToAddToQueue.map((song) => song.uniqueId), - ...shuffledQueue.slice(shuffledIndex + 1), - ]), - ] - : []; + set((state) => { + state.queue.shuffled = shuffledSongIndices; + state.queue.default = songsToAddToQueue; + state.current.time = 0; + state.current.player = 1; + state.current.index = 0; + state.current.shuffledIndex = 0; + state.current.song = initialSong; + }); + } else { + const index = initialIndex || 0; + set((state) => { + state.queue.default = songsToAddToQueue; + state.current.time = 0; + state.current.player = 1; + state.current.index = index; + state.current.shuffledIndex = 0; + state.current.song = songsToAddToQueue[index]; + }); + } + } else if (playType === Play.LAST) { + // Shuffle the queue after the current track + const shuffledQueueWithNewSongs = + get().shuffle === PlayerShuffle.TRACK + ? [ + ...shuffledQueue.slice(0, shuffledIndex + 1), + ...shuffle([ + ...songsToAddToQueue.map((song) => song.uniqueId), + ...shuffledQueue.slice(shuffledIndex + 1), + ]), + ] + : []; - set((state) => { - state.queue.default = [...get().queue.default, ...songsToAddToQueue]; - state.queue.shuffled = shuffledQueueWithNewSongs; - }); - } else if (playType === Play.NEXT) { - const queue = get().queue.default; - const currentIndex = get().current.index; + set((state) => { + state.queue.default = [ + ...get().queue.default, + ...songsToAddToQueue, + ]; + state.queue.shuffled = shuffledQueueWithNewSongs; + }); + } else if (playType === Play.NEXT) { + const queue = get().queue.default; + const currentIndex = get().current.index; - if (get().shuffle === PlayerShuffle.TRACK) { - const shuffledIndex = get().current.shuffledIndex; - const shuffledQueue = get().queue.shuffled; + if (get().shuffle === PlayerShuffle.TRACK) { + const shuffledIndex = get().current.shuffledIndex; + const shuffledQueue = get().queue.shuffled; - // Shuffle the queue after the current track - const shuffledQueueWithNewSongs = [ - ...shuffledQueue.slice(0, shuffledIndex + 1), - ...shuffle(songsToAddToQueue.map((song) => song.uniqueId)), - ...shuffledQueue.slice(shuffledIndex + 1), - ]; + // Shuffle the queue after the current track + const shuffledQueueWithNewSongs = [ + ...shuffledQueue.slice(0, shuffledIndex + 1), + ...shuffle(songsToAddToQueue.map((song) => song.uniqueId)), + ...shuffledQueue.slice(shuffledIndex + 1), + ]; - set((state) => { - state.queue.default = [ - ...queue.slice(0, currentIndex + 1), - ...songsToAddToQueue, - ...queue.slice(currentIndex + 1), - ]; - state.queue.shuffled = shuffledQueueWithNewSongs; - }); - } else { - set((state) => { - state.queue.default = [ - ...queue.slice(0, currentIndex + 1), - ...songsToAddToQueue, - ...queue.slice(currentIndex + 1), - ]; - state.queue.shuffled = []; - }); - } - } + set((state) => { + state.queue.default = [ + ...queue.slice(0, currentIndex + 1), + ...songsToAddToQueue, + ...queue.slice(currentIndex + 1), + ]; + state.queue.shuffled = shuffledQueueWithNewSongs; + }); + } else { + set((state) => { + state.queue.default = [ + ...queue.slice(0, currentIndex + 1), + ...songsToAddToQueue, + ...queue.slice(currentIndex + 1), + ]; + state.queue.shuffled = []; + }); + } + } - return get().actions.getPlayerData(); - }, - autoNext: () => { - const isLastTrack = get().actions.checkIsLastTrack(); - const { repeat } = get(); + return get().actions.getPlayerData(); + }, + autoNext: () => { + const isLastTrack = get().actions.checkIsLastTrack(); + const { repeat } = get(); - if (repeat === PlayerRepeat.ONE) { - const nextIndex = get().current.index; + if (repeat === PlayerRepeat.ONE) { + const nextIndex = get().current.index; - set((state) => { - state.current.time = 0; - state.current.index = nextIndex; - state.current.shuffledIndex = get().current.shuffledIndex; - state.current.player = state.current.player === 1 ? 2 : 1; - state.current.song = get().queue.default[nextIndex]; - state.queue.previousNode = get().current.song; - }); - } else if (get().shuffle === PlayerShuffle.TRACK) { - const nextShuffleIndex = isLastTrack ? 0 : get().current.shuffledIndex + 1; + set((state) => { + state.current.time = 0; + state.current.index = nextIndex; + state.current.shuffledIndex = get().current.shuffledIndex; + state.current.player = state.current.player === 1 ? 2 : 1; + state.current.song = get().queue.default[nextIndex]; + state.queue.previousNode = get().current.song; + }); + } else if (get().shuffle === PlayerShuffle.TRACK) { + const nextShuffleIndex = isLastTrack + ? 0 + : get().current.shuffledIndex + 1; - const nextSong = get().queue.default.find( - (song) => song.uniqueId === get().queue.shuffled[nextShuffleIndex], - ); + const nextSong = get().queue.default.find( + (song) => + song.uniqueId === get().queue.shuffled[nextShuffleIndex], + ); - const nextSongIndex = get().queue.default.findIndex( - (song) => song.uniqueId === nextSong!.uniqueId, - ); + const nextSongIndex = get().queue.default.findIndex( + (song) => song.uniqueId === nextSong!.uniqueId, + ); - set((state) => { - state.current.time = 0; - state.current.index = nextSongIndex!; - state.current.shuffledIndex = nextShuffleIndex; - state.current.player = state.current.player === 1 ? 2 : 1; - state.current.song = nextSong!; - state.queue.previousNode = get().current.song; + set((state) => { + state.current.time = 0; + state.current.index = nextSongIndex!; + state.current.shuffledIndex = nextShuffleIndex; + state.current.player = state.current.player === 1 ? 2 : 1; + state.current.song = nextSong!; + state.queue.previousNode = get().current.song; - if (isLastTrack) { - state.queue.shuffled = shuffle(get().queue.shuffled); - } - }); - } else { - const nextIndex = isLastTrack ? 0 : get().current.index + 1; + if (isLastTrack) { + state.queue.shuffled = shuffle(get().queue.shuffled); + } + }); + } else { + const nextIndex = isLastTrack ? 0 : get().current.index + 1; - set((state) => { - state.current.time = 0; - state.current.index = nextIndex; - state.current.player = state.current.player === 1 ? 2 : 1; - state.current.song = get().queue.default[nextIndex]; - state.queue.previousNode = get().current.song; - }); - } + set((state) => { + state.current.time = 0; + state.current.index = nextIndex; + state.current.player = state.current.player === 1 ? 2 : 1; + state.current.song = get().queue.default[nextIndex]; + state.queue.previousNode = get().current.song; + }); + } - return get().actions.getPlayerData(); - }, - checkIsFirstTrack: () => { - const currentIndex = - get().shuffle === PlayerShuffle.TRACK - ? get().current.shuffledIndex - : get().current.index; + return get().actions.getPlayerData(); + }, + checkIsFirstTrack: () => { + const currentIndex = + get().shuffle === PlayerShuffle.TRACK + ? get().current.shuffledIndex + : get().current.index; - return currentIndex === 0; - }, - checkIsLastTrack: (type) => { - const isShuffled = get().shuffle === PlayerShuffle.TRACK; - const queueLength = get().queue.default.length - 1; - const modifier = type === 'next' ? 1 : type === 'prev' ? -1 : 0; + return currentIndex === 0; + }, + checkIsLastTrack: (type) => { + const isShuffled = get().shuffle === PlayerShuffle.TRACK; + const queueLength = get().queue.default.length - 1; + const modifier = type === 'next' ? 1 : type === 'prev' ? -1 : 0; - if (isShuffled) { - const currentIndex = get().current.shuffledIndex + modifier; - return currentIndex === queueLength; - } + if (isShuffled) { + const currentIndex = get().current.shuffledIndex + modifier; + return currentIndex === queueLength; + } - return get().current.index + modifier === queueLength; - }, - clearQueue: () => { - set((state) => { - state.queue.default = []; - state.queue.shuffled = []; - state.queue.sorted = []; - state.current.index = 0; - state.current.shuffledIndex = 0; - state.current.player = 1; - state.current.song = undefined; - }); + return get().current.index + modifier === queueLength; + }, + clearQueue: () => { + set((state) => { + state.queue.default = []; + state.queue.shuffled = []; + state.queue.sorted = []; + state.current.index = 0; + state.current.shuffledIndex = 0; + state.current.player = 1; + state.current.song = undefined; + }); - return get().actions.getPlayerData(); - }, - getPlayerData: () => { - const queue = get().queue.default; - const currentPlayer = get().current.player; - const { repeat } = get(); - const isLastTrack = get().actions.checkIsLastTrack(); - const isFirstTrack = get().actions.checkIsFirstTrack(); + return get().actions.getPlayerData(); + }, + getPlayerData: () => { + const queue = get().queue.default; + const currentPlayer = get().current.player; + const { repeat } = get(); + const isLastTrack = get().actions.checkIsLastTrack(); + const isFirstTrack = get().actions.checkIsFirstTrack(); - let player1; - let player2; - if (get().shuffle === PlayerShuffle.TRACK) { - const shuffledQueue = get().queue.shuffled; - const { shuffledIndex } = get().current; - const current = queue.find( - (song) => song.uniqueId === shuffledQueue[shuffledIndex], - ) as QueueSong; + let player1; + let player2; + if (get().shuffle === PlayerShuffle.TRACK) { + const shuffledQueue = get().queue.shuffled; + const { shuffledIndex } = get().current; + const current = queue.find( + (song) => song.uniqueId === shuffledQueue[shuffledIndex], + ) as QueueSong; - let nextSongIndex: number | undefined; - let previousSongIndex: number | undefined; - if (repeat === PlayerRepeat.ALL) { - if (isLastTrack) nextSongIndex = 0; - else nextSongIndex = shuffledIndex + 1; + let nextSongIndex: number | undefined; + let previousSongIndex: number | undefined; + if (repeat === PlayerRepeat.ALL) { + if (isLastTrack) nextSongIndex = 0; + else nextSongIndex = shuffledIndex + 1; - if (isFirstTrack) previousSongIndex = queue.length - 1; - else previousSongIndex = shuffledIndex - 1; - } + if (isFirstTrack) previousSongIndex = queue.length - 1; + else previousSongIndex = shuffledIndex - 1; + } - if (repeat === PlayerRepeat.ONE) { - nextSongIndex = shuffledIndex; - previousSongIndex = shuffledIndex; - } + if (repeat === PlayerRepeat.ONE) { + nextSongIndex = shuffledIndex; + previousSongIndex = shuffledIndex; + } - if (repeat === PlayerRepeat.NONE) { - if (isLastTrack) nextSongIndex = undefined; - else nextSongIndex = shuffledIndex + 1; + if (repeat === PlayerRepeat.NONE) { + if (isLastTrack) nextSongIndex = undefined; + else nextSongIndex = shuffledIndex + 1; - if (isFirstTrack) previousSongIndex = undefined; - else previousSongIndex = shuffledIndex - 1; - } + if (isFirstTrack) previousSongIndex = undefined; + else previousSongIndex = shuffledIndex - 1; + } - const next = nextSongIndex - ? (queue.find( - (song) => song.uniqueId === shuffledQueue[nextSongIndex as number], - ) as QueueSong) - : undefined; + const next = nextSongIndex + ? (queue.find( + (song) => + song.uniqueId === + shuffledQueue[nextSongIndex as number], + ) as QueueSong) + : undefined; - const previous = queue.find( - (song) => song.uniqueId === shuffledQueue[shuffledIndex - 1], - ) as QueueSong; + const previous = queue.find( + (song) => song.uniqueId === shuffledQueue[shuffledIndex - 1], + ) as QueueSong; - player1 = currentPlayer === 1 ? current : next; - player2 = currentPlayer === 1 ? next : current; + player1 = currentPlayer === 1 ? current : next; + player2 = currentPlayer === 1 ? next : current; - return { - current: { - index: get().current.index, - nextIndex: nextSongIndex, - player: get().current.player, - previousIndex: previousSongIndex, - shuffledIndex: get().current.shuffledIndex, - song: get().current.song, - status: get().current.status, - }, - player1, - player2, - queue: { - current, - length: get().queue.default.length || 0, - next, - previous, - }, - }; - } + return { + current: { + index: get().current.index, + nextIndex: nextSongIndex, + player: get().current.player, + previousIndex: previousSongIndex, + shuffledIndex: get().current.shuffledIndex, + song: get().current.song, + status: get().current.status, + }, + player1, + player2, + queue: { + current, + length: get().queue.default.length || 0, + next, + previous, + }, + }; + } - const currentIndex = get().current.index; + const currentIndex = get().current.index; - let nextSongIndex; - let previousSongIndex; - if (repeat === PlayerRepeat.ALL) { - if (isLastTrack) nextSongIndex = 0; - else nextSongIndex = currentIndex + 1; + let nextSongIndex; + let previousSongIndex; + if (repeat === PlayerRepeat.ALL) { + if (isLastTrack) nextSongIndex = 0; + else nextSongIndex = currentIndex + 1; - if (isFirstTrack) previousSongIndex = queue.length - 1; - else previousSongIndex = currentIndex - 1; - } + if (isFirstTrack) previousSongIndex = queue.length - 1; + else previousSongIndex = currentIndex - 1; + } - if (repeat === PlayerRepeat.ONE) { - nextSongIndex = currentIndex; - previousSongIndex = currentIndex; - } + if (repeat === PlayerRepeat.ONE) { + nextSongIndex = currentIndex; + previousSongIndex = currentIndex; + } - if (repeat === PlayerRepeat.NONE) { - if (isLastTrack) nextSongIndex = undefined; - else nextSongIndex = currentIndex + 1; + if (repeat === PlayerRepeat.NONE) { + if (isLastTrack) nextSongIndex = undefined; + else nextSongIndex = currentIndex + 1; - if (isFirstTrack) previousSongIndex = undefined; - else previousSongIndex = currentIndex - 1; - } + if (isFirstTrack) previousSongIndex = undefined; + else previousSongIndex = currentIndex - 1; + } - player1 = - currentPlayer === 1 - ? queue[currentIndex] - : nextSongIndex !== undefined - ? queue[nextSongIndex] - : undefined; + player1 = + currentPlayer === 1 + ? queue[currentIndex] + : nextSongIndex !== undefined + ? queue[nextSongIndex] + : undefined; - player2 = - currentPlayer === 1 - ? nextSongIndex !== undefined - ? queue[nextSongIndex] - : undefined - : queue[currentIndex]; + player2 = + currentPlayer === 1 + ? nextSongIndex !== undefined + ? queue[nextSongIndex] + : undefined + : queue[currentIndex]; - return { - current: { - index: currentIndex, - nextIndex: nextSongIndex, - player: get().current.player, - previousIndex: previousSongIndex, - shuffledIndex: get().current.shuffledIndex, - song: get().current.song, - status: get().current.status, + return { + current: { + index: currentIndex, + nextIndex: nextSongIndex, + player: get().current.player, + previousIndex: previousSongIndex, + shuffledIndex: get().current.shuffledIndex, + song: get().current.song, + status: get().current.status, + }, + player1, + player2, + queue: { + current: queue[currentIndex], + length: get().queue.default.length || 0, + next: + nextSongIndex !== undefined + ? queue[nextSongIndex] + : undefined, + previous: queue[currentIndex - 1], + }, + }; + }, + getQueueData: () => { + const queue = get().queue.default; + return { + current: queue[get().current.index], + length: queue.length || 0, + next: queue[get().current.index + 1], + previous: queue[get().current.index - 1], + }; + }, + incrementPlayCount: (ids) => { + const { default: queue } = get().queue; + const foundUniqueIds = []; + + for (const id of ids) { + const foundIndex = queue.findIndex((song) => song.id === id); + if (foundIndex !== -1) { + foundUniqueIds.push(queue[foundIndex].uniqueId); + set((state) => { + state.queue.default[foundIndex].playCount += 1; + }); + } + } + + const currentSongId = get().current.song?.id; + if (currentSongId && ids.includes(currentSongId)) { + set((state) => { + if (state.current.song) { + state.current.song.playCount += 1; + } + }); + } + + return foundUniqueIds; + }, + moveToBottomOfQueue: (uniqueIds) => { + const queue = get().queue.default; + + const songsToMove = queue.filter((song) => + uniqueIds.includes(song.uniqueId), + ); + const songsToStay = queue.filter( + (song) => !uniqueIds.includes(song.uniqueId), + ); + + const reorderedQueue = [...songsToStay, ...songsToMove]; + + const currentSongUniqueId = get().current.song?.uniqueId; + const newCurrentSongIndex = reorderedQueue.findIndex( + (song) => song.uniqueId === currentSongUniqueId, + ); + + set((state) => { + state.current.index = newCurrentSongIndex; + state.queue.default = reorderedQueue; + }); + + return get().actions.getPlayerData(); + }, + moveToTopOfQueue: (uniqueIds) => { + const queue = get().queue.default; + + const songsToMove = queue.filter((song) => + uniqueIds.includes(song.uniqueId), + ); + const songsToStay = queue.filter( + (song) => !uniqueIds.includes(song.uniqueId), + ); + + const reorderedQueue = [...songsToMove, ...songsToStay]; + + const currentSongUniqueId = get().current.song?.uniqueId; + const newCurrentSongIndex = reorderedQueue.findIndex( + (song) => song.uniqueId === currentSongUniqueId, + ); + + set((state) => { + state.current.index = newCurrentSongIndex; + state.queue.default = reorderedQueue; + }); + + return get().actions.getPlayerData(); + }, + next: () => { + const isLastTrack = get().actions.checkIsLastTrack(); + const { repeat } = get(); + + if (get().shuffle === PlayerShuffle.TRACK) { + const nextShuffleIndex = isLastTrack + ? 0 + : get().current.shuffledIndex + 1; + + const nextSong = get().queue.default.find( + (song) => + song.uniqueId === get().queue.shuffled[nextShuffleIndex], + ); + + const nextSongIndex = get().queue.default.findIndex( + (song) => song.uniqueId === nextSong?.uniqueId, + ); + + set((state) => { + state.current.time = 0; + state.current.index = nextSongIndex!; + state.current.shuffledIndex = nextShuffleIndex; + state.current.player = 1; + state.current.song = nextSong!; + state.queue.previousNode = get().current.song; + }); + + if (isLastTrack) { + get().actions.setShuffle(PlayerShuffle.TRACK); + } + } else { + let nextIndex = 0; + + if (repeat === PlayerRepeat.ALL) { + nextIndex = isLastTrack ? 0 : get().current.index + 1; + } else { + nextIndex = isLastTrack + ? get().current.index + : get().current.index + 1; + } + + set((state) => { + state.current.time = 0; + state.current.index = nextIndex; + state.current.player = 1; + state.current.song = get().queue.default[nextIndex]; + state.queue.previousNode = get().current.song; + }); + } + + return get().actions.getPlayerData(); + }, + pause: () => { + set((state) => { + state.current.status = PlayerStatus.PAUSED; + }); + }, + play: () => { + set((state) => { + state.current.status = PlayerStatus.PLAYING; + }); + }, + player1: () => { + return get().actions.getPlayerData().player1; + }, + player2: () => { + return get().actions.getPlayerData().player2; + }, + previous: () => { + const isFirstTrack = get().actions.checkIsFirstTrack(); + const { repeat } = get(); + + if (get().shuffle === PlayerShuffle.TRACK) { + const prevShuffleIndex = isFirstTrack + ? 0 + : get().current.shuffledIndex - 1; + + const prevSong = get().queue.default.find( + (song) => + song.uniqueId === get().queue.shuffled[prevShuffleIndex], + ); + + const prevIndex = get().queue.default.findIndex( + (song) => song.uniqueId === prevSong?.uniqueId, + ); + + set((state) => { + state.current.time = 0; + state.current.index = prevIndex!; + state.current.shuffledIndex = prevShuffleIndex; + state.current.player = 1; + state.current.song = prevSong!; + state.queue.previousNode = get().current.song; + }); + } else { + let prevIndex: number; + if (repeat === PlayerRepeat.ALL) { + prevIndex = isFirstTrack + ? get().queue.default.length - 1 + : get().current.index - 1; + } else { + prevIndex = isFirstTrack ? 0 : get().current.index - 1; + } + + set((state) => { + state.current.time = 0; + state.current.index = prevIndex; + state.current.player = 1; + state.current.song = state.queue.default[state.current.index]; + state.queue.previousNode = get().current.song; + }); + } + + return get().actions.getPlayerData(); + }, + removeFromQueue: (uniqueIds) => { + const queue = get().queue.default; + const currentSong = get().current.song; + + const newQueue = queue.filter( + (song) => !uniqueIds.includes(song.uniqueId), + ); + const newShuffledQueue = get().queue.shuffled.filter( + (uniqueId) => !uniqueIds.includes(uniqueId), + ); + + const isCurrentSongRemoved = + currentSong && uniqueIds.includes(currentSong?.uniqueId); + + set((state) => { + state.queue.default = newQueue; + state.queue.shuffled = newShuffledQueue; + if (isCurrentSongRemoved) { + state.current.song = newQueue[0]; + state.current.index = 0; + } + }); + + return get().actions.getPlayerData(); + }, + reorderQueue: (rowUniqueIds: string[], afterUniqueId?: string) => { + // Don't move if dropping on top of a selected row + if (afterUniqueId && rowUniqueIds.includes(afterUniqueId)) { + return get().actions.getPlayerData(); + } + + const queue = get().queue.default; + const currentSongUniqueId = get().current.song?.uniqueId; + const queueWithoutSelectedRows = queue.filter( + (song) => !rowUniqueIds.includes(song.uniqueId), + ); + + const moveBeforeIndex = queueWithoutSelectedRows.findIndex( + (song) => song.uniqueId === afterUniqueId, + ); + + // AG-Grid does not provide node data when a row is moved to the bottom of the list + const reorderedQueue = afterUniqueId + ? [ + ...queueWithoutSelectedRows.slice(0, moveBeforeIndex), + ...queue.filter((song) => + rowUniqueIds.includes(song.uniqueId), + ), + ...queueWithoutSelectedRows.slice(moveBeforeIndex), + ] + : [ + ...queueWithoutSelectedRows, + ...queue.filter((song) => + rowUniqueIds.includes(song.uniqueId), + ), + ]; + + const currentSongIndex = reorderedQueue.findIndex( + (song) => song.uniqueId === currentSongUniqueId, + ); + + set({ + current: { ...get().current, index: currentSongIndex }, + queue: { ...get().queue, default: reorderedQueue }, + }); + + return get().actions.getPlayerData(); + }, + restoreQueue: (data) => { + set((state) => { + state.current = { + ...state.current, + ...data.current, + }; + state.queue = { + ...state.queue, + ...data.queue, + }; + }); + + return get().actions.getPlayerData(); + }, + setCurrentIndex: (index) => { + if (get().shuffle === PlayerShuffle.TRACK) { + const foundSong = get().queue.default.find( + (song) => song.uniqueId === get().queue.shuffled[index], + ); + const foundIndex = get().queue.default.findIndex( + (song) => song.uniqueId === foundSong?.uniqueId, + ); + set((state) => { + state.current.time = 0; + state.current.index = foundIndex!; + state.current.shuffledIndex = index; + state.current.player = 1; + state.current.song = foundSong!; + state.queue.previousNode = get().current.song; + }); + } else { + set((state) => { + state.current.time = 0; + state.current.index = index; + state.current.player = 1; + state.current.song = state.queue.default[index]; + state.queue.previousNode = get().current.song; + }); + } + + return get().actions.getPlayerData(); + }, + setCurrentTime: (time, seek = false) => { + set((state) => { + state.current.seek = seek; + state.current.time = time; + }); + }, + setCurrentTrack: (uniqueId) => { + if (get().shuffle === PlayerShuffle.TRACK) { + const defaultIndex = get().queue.default.findIndex( + (song) => song.uniqueId === uniqueId, + ); + + const shuffledIndex = get().queue.shuffled.findIndex( + (id) => id === uniqueId, + ); + + set((state) => { + state.current.time = 0; + state.current.index = defaultIndex; + state.current.shuffledIndex = shuffledIndex; + state.current.player = 1; + state.current.song = state.queue.default[defaultIndex]; + state.queue.previousNode = get().current.song; + }); + } else { + const defaultIndex = get().queue.default.findIndex( + (song) => song.uniqueId === uniqueId, + ); + + set((state) => { + state.current.time = 0; + state.current.index = defaultIndex; + state.current.player = 1; + state.current.song = state.queue.default[defaultIndex]; + state.queue.previousNode = get().current.song; + }); + } + + return get().actions.getPlayerData(); + }, + setFavorite: (ids, favorite) => { + const { default: queue } = get().queue; + const foundUniqueIds = []; + + for (const id of ids) { + const foundIndex = queue.findIndex((song) => song.id === id); + if (foundIndex !== -1) { + foundUniqueIds.push(queue[foundIndex].uniqueId); + set((state) => { + state.queue.default[foundIndex].userFavorite = favorite; + }); + } + } + + const currentSongId = get().current.song?.id; + if (currentSongId && ids.includes(currentSongId)) { + set((state) => { + if (state.current.song) { + state.current.song.userFavorite = favorite; + } + }); + } + + return foundUniqueIds; + }, + setMuted: (muted: boolean) => { + set((state) => { + state.muted = muted; + }); + }, + setRating: (ids, rating) => { + const { default: queue } = get().queue; + const foundUniqueIds = []; + + for (const id of ids) { + const foundIndex = queue.findIndex((song) => song.id === id); + if (foundIndex !== -1) { + foundUniqueIds.push(queue[foundIndex].uniqueId); + set((state) => { + state.queue.default[foundIndex].userRating = rating; + }); + } + } + + const currentSongId = get().current.song?.id; + if (currentSongId && ids.includes(currentSongId)) { + set((state) => { + if (state.current.song) { + state.current.song.userRating = rating; + } + }); + } + + return foundUniqueIds; + }, + setRepeat: (type: PlayerRepeat) => { + set((state) => { + state.repeat = type; + }); + + return get().actions.getPlayerData(); + }, + setShuffle: (type: PlayerShuffle) => { + if (type === PlayerShuffle.NONE) { + set((state) => { + state.shuffle = type; + state.queue.shuffled = []; + }); + + return get().actions.getPlayerData(); + } + + const currentSongId = get().current.song?.uniqueId; + + const queueWithoutCurrentSong = get().queue.default.filter( + (song) => song.uniqueId !== currentSongId, + ); + + const shuffledSongIds = shuffle(queueWithoutCurrentSong).map( + (song) => song.uniqueId, + ); + + set((state) => { + state.shuffle = type; + state.current.shuffledIndex = 0; + state.queue.shuffled = [currentSongId!, ...shuffledSongIds]; + }); + + return get().actions.getPlayerData(); + }, + setShuffledIndex: (index) => { + set((state) => { + state.current.time = 0; + state.current.shuffledIndex = index; + state.current.player = 1; + state.current.song = state.queue.default[index]; + state.queue.previousNode = get().current.song; + }); + + return get().actions.getPlayerData(); + }, + setStore: (data) => { + set({ ...get(), ...data }); + }, + setVolume: (volume: number) => { + set((state) => { + state.volume = volume; + }); + }, + shuffleQueue: () => { + const queue = get().queue.default; + const shuffledQueue = shuffle(queue); + + const currentSongUniqueId = get().current.song?.uniqueId; + const newCurrentSongIndex = shuffledQueue.findIndex( + (song) => song.uniqueId === currentSongUniqueId, + ); + + set((state) => { + state.current.index = newCurrentSongIndex; + state.queue.default = shuffledQueue; + }); + + return get().actions.getPlayerData(); + }, + }, + current: { + index: 0, + nextIndex: 0, + player: 1, + previousIndex: 0, + seek: false, + shuffledIndex: 0, + song: {} as QueueSong, + status: PlayerStatus.PAUSED, + time: 0, + }, + muted: false, + queue: { + default: [], + played: [], + previousNode: {} as QueueSong, + shuffled: [], + sorted: [], + }, + repeat: PlayerRepeat.NONE, + shuffle: PlayerShuffle.NONE, + volume: 50, + })), + { name: 'store_player' }, + ), + { + merge: (persistedState, currentState) => { + return merge(currentState, persistedState); }, - player1, - player2, - queue: { - current: queue[currentIndex], - length: get().queue.default.length || 0, - next: nextSongIndex !== undefined ? queue[nextSongIndex] : undefined, - previous: queue[currentIndex - 1], + name: 'store_player', + partialize: (state) => { + const notPersisted = ['queue', 'current', 'entry']; + return Object.fromEntries( + Object.entries(state).filter(([key]) => !notPersisted.includes(key)), + ); }, - }; + version: 1, }, - getQueueData: () => { - const queue = get().queue.default; - return { - current: queue[get().current.index], - length: queue.length || 0, - next: queue[get().current.index + 1], - previous: queue[get().current.index - 1], - }; - }, - incrementPlayCount: (ids) => { - const { default: queue } = get().queue; - const foundUniqueIds = []; - - for (const id of ids) { - const foundIndex = queue.findIndex((song) => song.id === id); - if (foundIndex !== -1) { - foundUniqueIds.push(queue[foundIndex].uniqueId); - set((state) => { - state.queue.default[foundIndex].playCount += 1; - }); - } - } - - const currentSongId = get().current.song?.id; - if (currentSongId && ids.includes(currentSongId)) { - set((state) => { - if (state.current.song) { - state.current.song.playCount += 1; - } - }); - } - - return foundUniqueIds; - }, - moveToBottomOfQueue: (uniqueIds) => { - const queue = get().queue.default; - - const songsToMove = queue.filter((song) => uniqueIds.includes(song.uniqueId)); - const songsToStay = queue.filter((song) => !uniqueIds.includes(song.uniqueId)); - - const reorderedQueue = [...songsToStay, ...songsToMove]; - - const currentSongUniqueId = get().current.song?.uniqueId; - const newCurrentSongIndex = reorderedQueue.findIndex( - (song) => song.uniqueId === currentSongUniqueId, - ); - - set((state) => { - state.current.index = newCurrentSongIndex; - state.queue.default = reorderedQueue; - }); - - return get().actions.getPlayerData(); - }, - moveToTopOfQueue: (uniqueIds) => { - const queue = get().queue.default; - - const songsToMove = queue.filter((song) => uniqueIds.includes(song.uniqueId)); - const songsToStay = queue.filter((song) => !uniqueIds.includes(song.uniqueId)); - - const reorderedQueue = [...songsToMove, ...songsToStay]; - - const currentSongUniqueId = get().current.song?.uniqueId; - const newCurrentSongIndex = reorderedQueue.findIndex( - (song) => song.uniqueId === currentSongUniqueId, - ); - - set((state) => { - state.current.index = newCurrentSongIndex; - state.queue.default = reorderedQueue; - }); - - return get().actions.getPlayerData(); - }, - next: () => { - const isLastTrack = get().actions.checkIsLastTrack(); - const { repeat } = get(); - - if (get().shuffle === PlayerShuffle.TRACK) { - const nextShuffleIndex = isLastTrack ? 0 : get().current.shuffledIndex + 1; - - const nextSong = get().queue.default.find( - (song) => song.uniqueId === get().queue.shuffled[nextShuffleIndex], - ); - - const nextSongIndex = get().queue.default.findIndex( - (song) => song.uniqueId === nextSong?.uniqueId, - ); - - set((state) => { - state.current.time = 0; - state.current.index = nextSongIndex!; - state.current.shuffledIndex = nextShuffleIndex; - state.current.player = 1; - state.current.song = nextSong!; - state.queue.previousNode = get().current.song; - }); - - if (isLastTrack) { - get().actions.setShuffle(PlayerShuffle.TRACK); - } - } else { - let nextIndex = 0; - - if (repeat === PlayerRepeat.ALL) { - nextIndex = isLastTrack ? 0 : get().current.index + 1; - } else { - nextIndex = isLastTrack ? get().current.index : get().current.index + 1; - } - - set((state) => { - state.current.time = 0; - state.current.index = nextIndex; - state.current.player = 1; - state.current.song = get().queue.default[nextIndex]; - state.queue.previousNode = get().current.song; - }); - } - - return get().actions.getPlayerData(); - }, - pause: () => { - set((state) => { - state.current.status = PlayerStatus.PAUSED; - }); - }, - play: () => { - set((state) => { - state.current.status = PlayerStatus.PLAYING; - }); - }, - player1: () => { - return get().actions.getPlayerData().player1; - }, - player2: () => { - return get().actions.getPlayerData().player2; - }, - previous: () => { - const isFirstTrack = get().actions.checkIsFirstTrack(); - const { repeat } = get(); - - if (get().shuffle === PlayerShuffle.TRACK) { - const prevShuffleIndex = isFirstTrack ? 0 : get().current.shuffledIndex - 1; - - const prevSong = get().queue.default.find( - (song) => song.uniqueId === get().queue.shuffled[prevShuffleIndex], - ); - - const prevIndex = get().queue.default.findIndex( - (song) => song.uniqueId === prevSong?.uniqueId, - ); - - set((state) => { - state.current.time = 0; - state.current.index = prevIndex!; - state.current.shuffledIndex = prevShuffleIndex; - state.current.player = 1; - state.current.song = prevSong!; - state.queue.previousNode = get().current.song; - }); - } else { - let prevIndex: number; - if (repeat === PlayerRepeat.ALL) { - prevIndex = isFirstTrack - ? get().queue.default.length - 1 - : get().current.index - 1; - } else { - prevIndex = isFirstTrack ? 0 : get().current.index - 1; - } - - set((state) => { - state.current.time = 0; - state.current.index = prevIndex; - state.current.player = 1; - state.current.song = state.queue.default[state.current.index]; - state.queue.previousNode = get().current.song; - }); - } - - return get().actions.getPlayerData(); - }, - removeFromQueue: (uniqueIds) => { - const queue = get().queue.default; - const currentSong = get().current.song; - - const newQueue = queue.filter((song) => !uniqueIds.includes(song.uniqueId)); - const newShuffledQueue = get().queue.shuffled.filter( - (uniqueId) => !uniqueIds.includes(uniqueId), - ); - - const isCurrentSongRemoved = currentSong && uniqueIds.includes(currentSong?.uniqueId); - - set((state) => { - state.queue.default = newQueue; - state.queue.shuffled = newShuffledQueue; - if (isCurrentSongRemoved) { - state.current.song = newQueue[0]; - state.current.index = 0; - } - }); - - return get().actions.getPlayerData(); - }, - reorderQueue: (rowUniqueIds: string[], afterUniqueId?: string) => { - // Don't move if dropping on top of a selected row - if (afterUniqueId && rowUniqueIds.includes(afterUniqueId)) { - return get().actions.getPlayerData(); - } - - const queue = get().queue.default; - const currentSongUniqueId = get().current.song?.uniqueId; - const queueWithoutSelectedRows = queue.filter( - (song) => !rowUniqueIds.includes(song.uniqueId), - ); - - const moveBeforeIndex = queueWithoutSelectedRows.findIndex( - (song) => song.uniqueId === afterUniqueId, - ); - - // AG-Grid does not provide node data when a row is moved to the bottom of the list - const reorderedQueue = afterUniqueId - ? [ - ...queueWithoutSelectedRows.slice(0, moveBeforeIndex), - ...queue.filter((song) => rowUniqueIds.includes(song.uniqueId)), - ...queueWithoutSelectedRows.slice(moveBeforeIndex), - ] - : [ - ...queueWithoutSelectedRows, - ...queue.filter((song) => rowUniqueIds.includes(song.uniqueId)), - ]; - - const currentSongIndex = reorderedQueue.findIndex( - (song) => song.uniqueId === currentSongUniqueId, - ); - - set({ - current: { ...get().current, index: currentSongIndex }, - queue: { ...get().queue, default: reorderedQueue }, - }); - - return get().actions.getPlayerData(); - }, - restoreQueue: (data) => { - set((state) => { - state.current = { - ...state.current, - ...data.current, - }; - state.queue = { - ...state.queue, - ...data.queue, - }; - }); - - return get().actions.getPlayerData(); - }, - setCurrentIndex: (index) => { - if (get().shuffle === PlayerShuffle.TRACK) { - const foundSong = get().queue.default.find( - (song) => song.uniqueId === get().queue.shuffled[index], - ); - const foundIndex = get().queue.default.findIndex( - (song) => song.uniqueId === foundSong?.uniqueId, - ); - set((state) => { - state.current.time = 0; - state.current.index = foundIndex!; - state.current.shuffledIndex = index; - state.current.player = 1; - state.current.song = foundSong!; - state.queue.previousNode = get().current.song; - }); - } else { - set((state) => { - state.current.time = 0; - state.current.index = index; - state.current.player = 1; - state.current.song = state.queue.default[index]; - state.queue.previousNode = get().current.song; - }); - } - - return get().actions.getPlayerData(); - }, - setCurrentTime: (time, seek = false) => { - set((state) => { - state.current.seek = seek; - state.current.time = time; - }); - }, - setCurrentTrack: (uniqueId) => { - if (get().shuffle === PlayerShuffle.TRACK) { - const defaultIndex = get().queue.default.findIndex( - (song) => song.uniqueId === uniqueId, - ); - - const shuffledIndex = get().queue.shuffled.findIndex((id) => id === uniqueId); - - set((state) => { - state.current.time = 0; - state.current.index = defaultIndex; - state.current.shuffledIndex = shuffledIndex; - state.current.player = 1; - state.current.song = state.queue.default[defaultIndex]; - state.queue.previousNode = get().current.song; - }); - } else { - const defaultIndex = get().queue.default.findIndex( - (song) => song.uniqueId === uniqueId, - ); - - set((state) => { - state.current.time = 0; - state.current.index = defaultIndex; - state.current.player = 1; - state.current.song = state.queue.default[defaultIndex]; - state.queue.previousNode = get().current.song; - }); - } - - return get().actions.getPlayerData(); - }, - setFavorite: (ids, favorite) => { - const { default: queue } = get().queue; - const foundUniqueIds = []; - - for (const id of ids) { - const foundIndex = queue.findIndex((song) => song.id === id); - if (foundIndex !== -1) { - foundUniqueIds.push(queue[foundIndex].uniqueId); - set((state) => { - state.queue.default[foundIndex].userFavorite = favorite; - }); - } - } - - const currentSongId = get().current.song?.id; - if (currentSongId && ids.includes(currentSongId)) { - set((state) => { - if (state.current.song) { - state.current.song.userFavorite = favorite; - } - }); - } - - return foundUniqueIds; - }, - setMuted: (muted: boolean) => { - set((state) => { - state.muted = muted; - }); - }, - setRating: (ids, rating) => { - const { default: queue } = get().queue; - const foundUniqueIds = []; - - for (const id of ids) { - const foundIndex = queue.findIndex((song) => song.id === id); - if (foundIndex !== -1) { - foundUniqueIds.push(queue[foundIndex].uniqueId); - set((state) => { - state.queue.default[foundIndex].userRating = rating; - }); - } - } - - const currentSongId = get().current.song?.id; - if (currentSongId && ids.includes(currentSongId)) { - set((state) => { - if (state.current.song) { - state.current.song.userRating = rating; - } - }); - } - - return foundUniqueIds; - }, - setRepeat: (type: PlayerRepeat) => { - set((state) => { - state.repeat = type; - }); - - return get().actions.getPlayerData(); - }, - setShuffle: (type: PlayerShuffle) => { - if (type === PlayerShuffle.NONE) { - set((state) => { - state.shuffle = type; - state.queue.shuffled = []; - }); - - return get().actions.getPlayerData(); - } - - const currentSongId = get().current.song?.uniqueId; - - const queueWithoutCurrentSong = get().queue.default.filter( - (song) => song.uniqueId !== currentSongId, - ); - - const shuffledSongIds = shuffle(queueWithoutCurrentSong).map((song) => song.uniqueId); - - set((state) => { - state.shuffle = type; - state.current.shuffledIndex = 0; - state.queue.shuffled = [currentSongId!, ...shuffledSongIds]; - }); - - return get().actions.getPlayerData(); - }, - setShuffledIndex: (index) => { - set((state) => { - state.current.time = 0; - state.current.shuffledIndex = index; - state.current.player = 1; - state.current.song = state.queue.default[index]; - state.queue.previousNode = get().current.song; - }); - - return get().actions.getPlayerData(); - }, - setStore: (data) => { - set({ ...get(), ...data }); - }, - setVolume: (volume: number) => { - set((state) => { - state.volume = volume; - }); - }, - shuffleQueue: () => { - const queue = get().queue.default; - const shuffledQueue = shuffle(queue); - - const currentSongUniqueId = get().current.song?.uniqueId; - const newCurrentSongIndex = shuffledQueue.findIndex( - (song) => song.uniqueId === currentSongUniqueId, - ); - - set((state) => { - state.current.index = newCurrentSongIndex; - state.queue.default = shuffledQueue; - }); - - return get().actions.getPlayerData(); - }, - }, - current: { - index: 0, - nextIndex: 0, - player: 1, - previousIndex: 0, - seek: false, - shuffledIndex: 0, - song: {} as QueueSong, - status: PlayerStatus.PAUSED, - time: 0, - }, - muted: false, - queue: { - default: [], - played: [], - previousNode: {} as QueueSong, - shuffled: [], - sorted: [], - }, - repeat: PlayerRepeat.NONE, - shuffle: PlayerShuffle.NONE, - volume: 50, - })), - { name: 'store_player' }, - ), - { - merge: (persistedState, currentState) => { - return merge(currentState, persistedState); - }, - name: 'store_player', - partialize: (state) => { - const notPersisted = ['queue', 'current', 'entry']; - return Object.fromEntries( - Object.entries(state).filter(([key]) => !notPersisted.includes(key)), - ); - }, - version: 1, - }, + ), ), - ), ); export const usePlayerStoreActions = () => usePlayerStore((state) => state.actions); export const usePlayerControls = () => - usePlayerStore( - (state) => ({ - autoNext: state.actions.autoNext, - next: state.actions.next, - pause: state.actions.pause, - play: state.actions.play, - previous: state.actions.previous, - setCurrentIndex: state.actions.setCurrentIndex, - setMuted: state.actions.setMuted, - setRepeat: state.actions.setRepeat, - setShuffle: state.actions.setShuffle, - setShuffledIndex: state.actions.setShuffledIndex, - setVolume: state.actions.setVolume, - }), - shallow, - ); + usePlayerStore( + (state) => ({ + autoNext: state.actions.autoNext, + next: state.actions.next, + pause: state.actions.pause, + play: state.actions.play, + previous: state.actions.previous, + setCurrentIndex: state.actions.setCurrentIndex, + setMuted: state.actions.setMuted, + setRepeat: state.actions.setRepeat, + setShuffle: state.actions.setShuffle, + setShuffledIndex: state.actions.setShuffledIndex, + setVolume: state.actions.setVolume, + }), + shallow, + ); export const useQueueControls = () => - usePlayerStore( - (state) => ({ - addToQueue: state.actions.addToQueue, - clearQueue: state.actions.clearQueue, - moveToBottomOfQueue: state.actions.moveToBottomOfQueue, - moveToTopOfQueue: state.actions.moveToTopOfQueue, - removeFromQueue: state.actions.removeFromQueue, - reorderQueue: state.actions.reorderQueue, - restoreQueue: state.actions.restoreQueue, - setCurrentIndex: state.actions.setCurrentIndex, - setCurrentTrack: state.actions.setCurrentTrack, - setShuffledIndex: state.actions.setShuffledIndex, - shuffleQueue: state.actions.shuffleQueue, - }), - shallow, - ); + usePlayerStore( + (state) => ({ + addToQueue: state.actions.addToQueue, + clearQueue: state.actions.clearQueue, + moveToBottomOfQueue: state.actions.moveToBottomOfQueue, + moveToTopOfQueue: state.actions.moveToTopOfQueue, + removeFromQueue: state.actions.removeFromQueue, + reorderQueue: state.actions.reorderQueue, + restoreQueue: state.actions.restoreQueue, + setCurrentIndex: state.actions.setCurrentIndex, + setCurrentTrack: state.actions.setCurrentTrack, + setShuffledIndex: state.actions.setShuffledIndex, + shuffleQueue: state.actions.shuffleQueue, + }), + shallow, + ); export const useQueueData = () => usePlayerStore((state) => state.actions.getQueueData); @@ -959,12 +1001,12 @@ export const useDefaultQueue = () => usePlayerStore((state) => state.queue.defau export const useCurrentSong = () => usePlayerStore((state) => state.current.song); export const usePlayerData = () => - usePlayerStore( - (state) => state.actions.getPlayerData(), - (a, b) => { - return a.current.nextIndex === b.current.nextIndex; - }, - ); + usePlayerStore( + (state) => state.actions.getPlayerData(), + (a, b) => { + return a.current.nextIndex === b.current.nextIndex; + }, + ); export const useCurrentPlayer = () => usePlayerStore((state) => state.current.player); @@ -989,14 +1031,14 @@ export const useSetQueueFavorite = () => usePlayerStore((state) => state.actions export const useSetQueueRating = () => usePlayerStore((state) => state.actions.setRating); export const useIncrementQueuePlayCount = () => - usePlayerStore((state) => state.actions.incrementPlayCount); + usePlayerStore((state) => state.actions.incrementPlayCount); export const useQueueStatus = () => - usePlayerStore( - (state) => ({ - currentSong: state.current.song, - index: state.current.index, - length: state.queue.default.length, - }), - shallow, - ); + usePlayerStore( + (state) => ({ + currentSong: state.current.song, + index: state.current.index, + length: state.queue.default.length, + }), + shallow, + ); diff --git a/src/renderer/store/playlist.store.ts b/src/renderer/store/playlist.store.ts index bebb821b..afdeac3c 100644 --- a/src/renderer/store/playlist.store.ts +++ b/src/renderer/store/playlist.store.ts @@ -8,172 +8,175 @@ import { DataTableProps } from '/@/renderer/store/settings.store'; import { ListDisplayType, TableColumn, TablePagination } from '/@/renderer/types'; type TableProps = { - pagination: TablePagination; - scrollOffset: number; + pagination: TablePagination; + scrollOffset: number; } & DataTableProps; type ListProps<T> = { - display: ListDisplayType; - filter: T; - table: TableProps; + display: ListDisplayType; + filter: T; + table: TableProps; }; type DetailPaginationProps = TablePagination & { - scrollOffset: number; + scrollOffset: number; }; type DetailTableProps = DataTableProps & { - id: { - [key: string]: DetailPaginationProps & { filter: SongListFilter }; - }; + id: { + [key: string]: DetailPaginationProps & { filter: SongListFilter }; + }; }; type DetailProps = { - display: ListDisplayType; - table: DetailTableProps; + display: ListDisplayType; + table: DetailTableProps; }; export type PlaylistListFilter = Omit<PlaylistListArgs['query'], 'startIndex' | 'limit'>; interface PlaylistState { - detail: DetailProps; - list: ListProps<PlaylistListFilter>; + detail: DetailProps; + list: ListProps<PlaylistListFilter>; } export interface PlaylistSlice extends PlaylistState { - actions: { - setDetailFilters: (id: string, data: Partial<SongListFilter>) => SongListFilter; - setDetailTable: (data: Partial<DetailTableProps>) => void; - setDetailTablePagination: (id: string, data: Partial<DetailPaginationProps>) => void; - setFilters: (data: Partial<PlaylistListFilter>) => PlaylistListFilter; - setStore: (data: Partial<PlaylistSlice>) => void; - setTable: (data: Partial<TableProps>) => void; - setTablePagination: (args: { data: Partial<TablePagination> }) => void; - }; + actions: { + setDetailFilters: (id: string, data: Partial<SongListFilter>) => SongListFilter; + setDetailTable: (data: Partial<DetailTableProps>) => void; + setDetailTablePagination: (id: string, data: Partial<DetailPaginationProps>) => void; + setFilters: (data: Partial<PlaylistListFilter>) => PlaylistListFilter; + setStore: (data: Partial<PlaylistSlice>) => void; + setTable: (data: Partial<TableProps>) => void; + setTablePagination: (args: { data: Partial<TablePagination> }) => void; + }; } export const usePlaylistStore = create<PlaylistSlice>()( - persist( - devtools( - immer((set, get) => ({ - actions: { - setDetailFilters: (id, data) => { - set((state) => { - state.detail.table.id[id] = { - ...state.detail.table.id[id], - filter: { - ...state.detail.table.id[id].filter, - ...data, + persist( + devtools( + immer((set, get) => ({ + actions: { + setDetailFilters: (id, data) => { + set((state) => { + state.detail.table.id[id] = { + ...state.detail.table.id[id], + filter: { + ...state.detail.table.id[id].filter, + ...data, + }, + }; + }); + + return get().detail.table.id[id].filter; + }, + setDetailTable: (data) => { + set((state) => { + state.detail.table = { ...state.detail.table, ...data }; + }); + }, + setDetailTablePagination: (id, data) => { + set((state) => { + state.detail.table.id[id] = { + ...state.detail.table.id[id], + ...data, + }; + }); + }, + setFilters: (data) => { + set((state) => { + state.list.filter = { ...state.list.filter, ...data }; + }); + + return get().list.filter; + }, + setStore: (data) => { + set({ ...get(), ...data }); + }, + setTable: (data) => { + set((state) => { + state.list.table = { ...state.list.table, ...data }; + }); + }, + setTablePagination: (args) => { + set((state) => { + state.list.table.pagination = { + ...state.list.table.pagination, + ...args.data, + }; + }); + }, }, - }; - }); - - return get().detail.table.id[id].filter; - }, - setDetailTable: (data) => { - set((state) => { - state.detail.table = { ...state.detail.table, ...data }; - }); - }, - setDetailTablePagination: (id, data) => { - set((state) => { - state.detail.table.id[id] = { - ...state.detail.table.id[id], - ...data, - }; - }); - }, - setFilters: (data) => { - set((state) => { - state.list.filter = { ...state.list.filter, ...data }; - }); - - return get().list.filter; - }, - setStore: (data) => { - set({ ...get(), ...data }); - }, - setTable: (data) => { - set((state) => { - state.list.table = { ...state.list.table, ...data }; - }); - }, - setTablePagination: (args) => { - set((state) => { - state.list.table.pagination = { ...state.list.table.pagination, ...args.data }; - }); - }, - }, - detail: { - display: ListDisplayType.TABLE, - table: { - autoFit: true, - columns: [ - { - column: TableColumn.ROW_INDEX, - width: 50, - }, - { - column: TableColumn.TITLE_COMBINED, - width: 500, - }, - { - column: TableColumn.DURATION, - width: 100, - }, - { - column: TableColumn.ALBUM, - width: 500, - }, - ], - id: {}, - rowHeight: 60, - }, - }, - list: { - display: ListDisplayType.TABLE, - filter: { - musicFolderId: undefined, - sortBy: PlaylistListSort.NAME, - sortOrder: SortOrder.ASC, - }, - table: { - autoFit: true, - columns: [ - { - column: TableColumn.ROW_INDEX, - width: 50, - }, - { - column: TableColumn.TITLE, - width: 500, - }, - { - column: TableColumn.SONG_COUNT, - width: 100, - }, - ], - pagination: { - currentPage: 1, - itemsPerPage: 100, - totalItems: 1, - totalPages: 1, + detail: { + display: ListDisplayType.TABLE, + table: { + autoFit: true, + columns: [ + { + column: TableColumn.ROW_INDEX, + width: 50, + }, + { + column: TableColumn.TITLE_COMBINED, + width: 500, + }, + { + column: TableColumn.DURATION, + width: 100, + }, + { + column: TableColumn.ALBUM, + width: 500, + }, + ], + id: {}, + rowHeight: 60, + }, + }, + list: { + display: ListDisplayType.TABLE, + filter: { + musicFolderId: undefined, + sortBy: PlaylistListSort.NAME, + sortOrder: SortOrder.ASC, + }, + table: { + autoFit: true, + columns: [ + { + column: TableColumn.ROW_INDEX, + width: 50, + }, + { + column: TableColumn.TITLE, + width: 500, + }, + { + column: TableColumn.SONG_COUNT, + width: 100, + }, + ], + pagination: { + currentPage: 1, + itemsPerPage: 100, + totalItems: 1, + totalPages: 1, + }, + rowHeight: 40, + scrollOffset: 0, + }, + }, + })), + { name: 'store_playlist' }, + ), + { + merge: (persistedState, currentState) => { + return merge(currentState, persistedState); }, - rowHeight: 40, - scrollOffset: 0, - }, + name: 'store_playlist', + version: 1, }, - })), - { name: 'store_playlist' }, ), - { - merge: (persistedState, currentState) => { - return merge(currentState, persistedState); - }, - name: 'store_playlist', - version: 1, - }, - ), ); export const usePlaylistStoreActions = () => usePlaylistStore((state) => state.actions); @@ -183,29 +186,29 @@ export const useSetPlaylistStore = () => usePlaylistStore((state) => state.actio export const useSetPlaylistFilters = () => usePlaylistStore((state) => state.actions.setFilters); export const usePlaylistFilters = () => { - return usePlaylistStore((state) => [state.list.filter, state.actions.setFilters]); + return usePlaylistStore((state) => [state.list.filter, state.actions.setFilters]); }; export const usePlaylistListStore = () => usePlaylistStore((state) => state.list); export const usePlaylistTablePagination = () => - usePlaylistStore((state) => state.list.table.pagination); + usePlaylistStore((state) => state.list.table.pagination); export const useSetPlaylistTablePagination = () => - usePlaylistStore((state) => state.actions.setTablePagination); + usePlaylistStore((state) => state.actions.setTablePagination); export const useSetPlaylistTable = () => usePlaylistStore((state) => state.actions.setTable); export const usePlaylistDetailStore = () => usePlaylistStore((state) => state.detail); export const usePlaylistDetailTablePagination = (id: string) => - usePlaylistStore((state) => state.detail.table.id[id]); + usePlaylistStore((state) => state.detail.table.id[id]); export const useSetPlaylistDetailTablePagination = () => - usePlaylistStore((state) => state.actions.setDetailTablePagination); + usePlaylistStore((state) => state.actions.setDetailTablePagination); export const useSetPlaylistDetailTable = () => - usePlaylistStore((state) => state.actions.setDetailTable); + usePlaylistStore((state) => state.actions.setDetailTable); export const useSetPlaylistDetailFilters = () => - usePlaylistStore((state) => state.actions.setDetailFilters); + usePlaylistStore((state) => state.actions.setDetailFilters); diff --git a/src/renderer/store/settings.store.ts b/src/renderer/store/settings.store.ts index 80820120..cf654db1 100644 --- a/src/renderer/store/settings.store.ts +++ b/src/renderer/store/settings.store.ts @@ -12,415 +12,418 @@ import { LibraryItem, LyricSource } from '/@/renderer/api/types'; import { AppRoute } from '/@/renderer/router/routes'; import { AppTheme } from '/@/renderer/themes/types'; import { - TableColumn, - CrossfadeStyle, - Play, - PlaybackStyle, - PlaybackType, - TableType, - Platform, + TableColumn, + CrossfadeStyle, + Play, + PlaybackStyle, + PlaybackType, + TableType, + Platform, } from '/@/renderer/types'; const utils = isElectron() ? window.electron.utils : null; export type SidebarItemType = { - disabled: boolean; - id: string; - label: string; - route: AppRoute | string; + disabled: boolean; + id: string; + label: string; + route: AppRoute | string; }; export const sidebarItems = [ - { disabled: true, id: 'Now Playing', label: 'Now Playing', route: AppRoute.NOW_PLAYING }, - { - disabled: true, - id: 'Search', - label: 'Search', - route: generatePath(AppRoute.SEARCH, { itemType: LibraryItem.SONG }), - }, - { disabled: false, id: 'Home', label: 'Home', route: AppRoute.HOME }, - { disabled: false, id: 'Albums', label: 'Albums', route: AppRoute.LIBRARY_ALBUMS }, - { disabled: false, id: 'Tracks', label: 'Tracks', route: AppRoute.LIBRARY_SONGS }, - { - disabled: false, - id: 'Artists', - label: 'Artists', - route: AppRoute.LIBRARY_ALBUM_ARTISTS, - }, - { disabled: false, id: 'Genres', label: 'Genres', route: AppRoute.LIBRARY_GENRES }, - { disabled: true, id: 'Folders', label: 'Folders', route: AppRoute.LIBRARY_FOLDERS }, - { disabled: true, id: 'Playlists', label: 'Playlists', route: AppRoute.PLAYLISTS }, - { disabled: true, id: 'Settings', label: 'Settings', route: AppRoute.SETTINGS }, + { disabled: true, id: 'Now Playing', label: 'Now Playing', route: AppRoute.NOW_PLAYING }, + { + disabled: true, + id: 'Search', + label: 'Search', + route: generatePath(AppRoute.SEARCH, { itemType: LibraryItem.SONG }), + }, + { disabled: false, id: 'Home', label: 'Home', route: AppRoute.HOME }, + { disabled: false, id: 'Albums', label: 'Albums', route: AppRoute.LIBRARY_ALBUMS }, + { disabled: false, id: 'Tracks', label: 'Tracks', route: AppRoute.LIBRARY_SONGS }, + { + disabled: false, + id: 'Artists', + label: 'Artists', + route: AppRoute.LIBRARY_ALBUM_ARTISTS, + }, + { disabled: false, id: 'Genres', label: 'Genres', route: AppRoute.LIBRARY_GENRES }, + { disabled: true, id: 'Folders', label: 'Folders', route: AppRoute.LIBRARY_FOLDERS }, + { disabled: true, id: 'Playlists', label: 'Playlists', route: AppRoute.PLAYLISTS }, + { disabled: true, id: 'Settings', label: 'Settings', route: AppRoute.SETTINGS }, ]; export type PersistedTableColumn = { - column: TableColumn; - extraProps?: Partial<ColDef>; - width: number; + column: TableColumn; + extraProps?: Partial<ColDef>; + width: number; }; export type DataTableProps = { - autoFit: boolean; - columns: PersistedTableColumn[]; - followCurrentSong?: boolean; - rowHeight: number; + autoFit: boolean; + columns: PersistedTableColumn[]; + followCurrentSong?: boolean; + rowHeight: number; }; export type SideQueueType = 'sideQueue' | 'sideDrawerQueue'; type MpvSettings = { - audioExclusiveMode: 'yes' | 'no'; - audioFormat?: 's16' | 's32' | 'float'; - audioSampleRateHz?: number; - gaplessAudio: 'yes' | 'no' | 'weak'; - replayGainClip: boolean; - replayGainFallbackDB?: number; - replayGainMode: 'no' | 'track' | 'album'; - replayGainPreampDB?: number; + audioExclusiveMode: 'yes' | 'no'; + audioFormat?: 's16' | 's32' | 'float'; + audioSampleRateHz?: number; + gaplessAudio: 'yes' | 'no' | 'weak'; + replayGainClip: boolean; + replayGainFallbackDB?: number; + replayGainMode: 'no' | 'track' | 'album'; + replayGainPreampDB?: number; }; export enum BindingActions { - GLOBAL_SEARCH = 'globalSearch', - LOCAL_SEARCH = 'localSearch', - MUTE = 'volumeMute', - NEXT = 'next', - PAUSE = 'pause', - PLAY = 'play', - PLAY_PAUSE = 'playPause', - PREVIOUS = 'previous', - SHUFFLE = 'toggleShuffle', - SKIP_BACKWARD = 'skipBackward', - SKIP_FORWARD = 'skipForward', - STOP = 'stop', - TOGGLE_FULLSCREEN_PLAYER = 'toggleFullscreenPlayer', - TOGGLE_QUEUE = 'toggleQueue', - TOGGLE_REPEAT = 'toggleRepeat', - VOLUME_DOWN = 'volumeDown', - VOLUME_UP = 'volumeUp', - ZOOM_IN = 'zoomIn', - ZOOM_OUT = 'zoomOut', + GLOBAL_SEARCH = 'globalSearch', + LOCAL_SEARCH = 'localSearch', + MUTE = 'volumeMute', + NEXT = 'next', + PAUSE = 'pause', + PLAY = 'play', + PLAY_PAUSE = 'playPause', + PREVIOUS = 'previous', + SHUFFLE = 'toggleShuffle', + SKIP_BACKWARD = 'skipBackward', + SKIP_FORWARD = 'skipForward', + STOP = 'stop', + TOGGLE_FULLSCREEN_PLAYER = 'toggleFullscreenPlayer', + TOGGLE_QUEUE = 'toggleQueue', + TOGGLE_REPEAT = 'toggleRepeat', + VOLUME_DOWN = 'volumeDown', + VOLUME_UP = 'volumeUp', + ZOOM_IN = 'zoomIn', + ZOOM_OUT = 'zoomOut', } export interface SettingsState { - general: { - followSystemTheme: boolean; - fontContent: string; - playButtonBehavior: Play; - resume: boolean; - showQueueDrawerButton: boolean; - sideQueueType: SideQueueType; - sidebarItems: SidebarItemType[]; - sidebarPlaylistList: boolean; - skipButtons: { - enabled: boolean; - skipBackwardSeconds: number; - skipForwardSeconds: number; + general: { + followSystemTheme: boolean; + fontContent: string; + playButtonBehavior: Play; + resume: boolean; + showQueueDrawerButton: boolean; + sideQueueType: SideQueueType; + sidebarItems: SidebarItemType[]; + sidebarPlaylistList: boolean; + skipButtons: { + enabled: boolean; + skipBackwardSeconds: number; + skipForwardSeconds: number; + }; + theme: AppTheme; + themeDark: AppTheme; + themeLight: AppTheme; + volumeWheelStep: number; + zoomFactor: number; }; - theme: AppTheme; - themeDark: AppTheme; - themeLight: AppTheme; - volumeWheelStep: number; - zoomFactor: number; - }; - hotkeys: { - bindings: Record<BindingActions, { allowGlobal: boolean; hotkey: string; isGlobal: boolean }>; - globalMediaHotkeys: boolean; - }; - lyrics: { - delayMs: number; - fetch: boolean; - follow: boolean; - sources: LyricSource[]; - }; - playback: { - audioDeviceId?: string | null; - crossfadeDuration: number; - crossfadeStyle: CrossfadeStyle; - mpvExtraParameters: string[]; - mpvProperties: MpvSettings; - muted: boolean; - scrobble: { - enabled: boolean; - scrobbleAtDuration: number; - scrobbleAtPercentage: number; + hotkeys: { + bindings: Record< + BindingActions, + { allowGlobal: boolean; hotkey: string; isGlobal: boolean } + >; + globalMediaHotkeys: boolean; + }; + lyrics: { + delayMs: number; + fetch: boolean; + follow: boolean; + sources: LyricSource[]; + }; + playback: { + audioDeviceId?: string | null; + crossfadeDuration: number; + crossfadeStyle: CrossfadeStyle; + mpvExtraParameters: string[]; + mpvProperties: MpvSettings; + muted: boolean; + scrobble: { + enabled: boolean; + scrobbleAtDuration: number; + scrobbleAtPercentage: number; + }; + style: PlaybackStyle; + type: PlaybackType; + }; + tab: 'general' | 'playback' | 'window' | 'hotkeys' | string; + tables: { + fullScreen: DataTableProps; + nowPlaying: DataTableProps; + sideDrawerQueue: DataTableProps; + sideQueue: DataTableProps; + songs: DataTableProps; + }; + window: { + disableAutoUpdate: boolean; + exitToTray: boolean; + minimizeToTray: boolean; + windowBarStyle: Platform; }; - style: PlaybackStyle; - type: PlaybackType; - }; - tab: 'general' | 'playback' | 'window' | 'hotkeys' | string; - tables: { - fullScreen: DataTableProps; - nowPlaying: DataTableProps; - sideDrawerQueue: DataTableProps; - sideQueue: DataTableProps; - songs: DataTableProps; - }; - window: { - disableAutoUpdate: boolean; - exitToTray: boolean; - minimizeToTray: boolean; - windowBarStyle: Platform; - }; } export interface SettingsSlice extends SettingsState { - actions: { - reset: () => void; - setSettings: (data: Partial<SettingsState>) => void; - setSidebarItems: (items: SidebarItemType[]) => void; - }; + actions: { + reset: () => void; + setSettings: (data: Partial<SettingsState>) => void; + setSidebarItems: (items: SidebarItemType[]) => void; + }; } // Determines the default/initial windowBarStyle value based on the current platform. const getPlatformDefaultWindowBarStyle = (): Platform => { - return isElectron() ? (utils.isMacOS() ? Platform.MACOS : Platform.WINDOWS) : Platform.WEB; + return isElectron() ? (utils.isMacOS() ? Platform.MACOS : Platform.WINDOWS) : Platform.WEB; }; const platformDefaultWindowBarStyle: Platform = getPlatformDefaultWindowBarStyle(); const initialState: SettingsState = { - general: { - followSystemTheme: false, - fontContent: 'Poppins', - playButtonBehavior: Play.NOW, - resume: false, - showQueueDrawerButton: false, - sideQueueType: 'sideQueue', - sidebarItems, - sidebarPlaylistList: true, - skipButtons: { - enabled: false, - skipBackwardSeconds: 5, - skipForwardSeconds: 10, + general: { + followSystemTheme: false, + fontContent: 'Poppins', + playButtonBehavior: Play.NOW, + resume: false, + showQueueDrawerButton: false, + sideQueueType: 'sideQueue', + sidebarItems, + sidebarPlaylistList: true, + skipButtons: { + enabled: false, + skipBackwardSeconds: 5, + skipForwardSeconds: 10, + }, + theme: AppTheme.DEFAULT_DARK, + themeDark: AppTheme.DEFAULT_DARK, + themeLight: AppTheme.DEFAULT_LIGHT, + volumeWheelStep: 5, + zoomFactor: 100, }, - theme: AppTheme.DEFAULT_DARK, - themeDark: AppTheme.DEFAULT_DARK, - themeLight: AppTheme.DEFAULT_LIGHT, - volumeWheelStep: 5, - zoomFactor: 100, - }, - hotkeys: { - bindings: { - globalSearch: { allowGlobal: false, hotkey: 'mod+k', isGlobal: false }, - localSearch: { allowGlobal: false, hotkey: 'mod+f', isGlobal: false }, - next: { allowGlobal: true, hotkey: '', isGlobal: false }, - pause: { allowGlobal: true, hotkey: '', isGlobal: false }, - play: { allowGlobal: true, hotkey: '', isGlobal: false }, - playPause: { allowGlobal: true, hotkey: '', isGlobal: false }, - previous: { allowGlobal: true, hotkey: '', isGlobal: false }, - skipBackward: { allowGlobal: true, hotkey: '', isGlobal: false }, - skipForward: { allowGlobal: true, hotkey: '', isGlobal: false }, - stop: { allowGlobal: true, hotkey: '', isGlobal: false }, - toggleFullscreenPlayer: { allowGlobal: false, hotkey: '', isGlobal: false }, - toggleQueue: { allowGlobal: false, hotkey: '', isGlobal: false }, - toggleRepeat: { allowGlobal: true, hotkey: '', isGlobal: false }, - toggleShuffle: { allowGlobal: true, hotkey: '', isGlobal: false }, - volumeDown: { allowGlobal: true, hotkey: '', isGlobal: false }, - volumeMute: { allowGlobal: true, hotkey: '', isGlobal: false }, - volumeUp: { allowGlobal: true, hotkey: '', isGlobal: false }, - zoomIn: { allowGlobal: true, hotkey: '', isGlobal: false }, - zoomOut: { allowGlobal: true, hotkey: '', isGlobal: false }, + hotkeys: { + bindings: { + globalSearch: { allowGlobal: false, hotkey: 'mod+k', isGlobal: false }, + localSearch: { allowGlobal: false, hotkey: 'mod+f', isGlobal: false }, + next: { allowGlobal: true, hotkey: '', isGlobal: false }, + pause: { allowGlobal: true, hotkey: '', isGlobal: false }, + play: { allowGlobal: true, hotkey: '', isGlobal: false }, + playPause: { allowGlobal: true, hotkey: '', isGlobal: false }, + previous: { allowGlobal: true, hotkey: '', isGlobal: false }, + skipBackward: { allowGlobal: true, hotkey: '', isGlobal: false }, + skipForward: { allowGlobal: true, hotkey: '', isGlobal: false }, + stop: { allowGlobal: true, hotkey: '', isGlobal: false }, + toggleFullscreenPlayer: { allowGlobal: false, hotkey: '', isGlobal: false }, + toggleQueue: { allowGlobal: false, hotkey: '', isGlobal: false }, + toggleRepeat: { allowGlobal: true, hotkey: '', isGlobal: false }, + toggleShuffle: { allowGlobal: true, hotkey: '', isGlobal: false }, + volumeDown: { allowGlobal: true, hotkey: '', isGlobal: false }, + volumeMute: { allowGlobal: true, hotkey: '', isGlobal: false }, + volumeUp: { allowGlobal: true, hotkey: '', isGlobal: false }, + zoomIn: { allowGlobal: true, hotkey: '', isGlobal: false }, + zoomOut: { allowGlobal: true, hotkey: '', isGlobal: false }, + }, + globalMediaHotkeys: true, }, - globalMediaHotkeys: true, - }, - lyrics: { - delayMs: 0, - fetch: false, - follow: true, - sources: [], - }, - playback: { - audioDeviceId: undefined, - crossfadeDuration: 5, - crossfadeStyle: CrossfadeStyle.EQUALPOWER, - mpvExtraParameters: [], - mpvProperties: { - audioExclusiveMode: 'no', - audioFormat: undefined, - audioSampleRateHz: 0, - gaplessAudio: 'weak', - replayGainClip: true, - replayGainFallbackDB: undefined, - replayGainMode: 'no', - replayGainPreampDB: 0, + lyrics: { + delayMs: 0, + fetch: false, + follow: true, + sources: [], }, - muted: false, - scrobble: { - enabled: true, - scrobbleAtDuration: 240, - scrobbleAtPercentage: 75, + playback: { + audioDeviceId: undefined, + crossfadeDuration: 5, + crossfadeStyle: CrossfadeStyle.EQUALPOWER, + mpvExtraParameters: [], + mpvProperties: { + audioExclusiveMode: 'no', + audioFormat: undefined, + audioSampleRateHz: 0, + gaplessAudio: 'weak', + replayGainClip: true, + replayGainFallbackDB: undefined, + replayGainMode: 'no', + replayGainPreampDB: 0, + }, + muted: false, + scrobble: { + enabled: true, + scrobbleAtDuration: 240, + scrobbleAtPercentage: 75, + }, + style: PlaybackStyle.GAPLESS, + type: PlaybackType.LOCAL, }, - style: PlaybackStyle.GAPLESS, - type: PlaybackType.LOCAL, - }, - tab: 'general', - tables: { - fullScreen: { - autoFit: true, - columns: [ - { - column: TableColumn.TITLE_COMBINED, - width: 500, + tab: 'general', + tables: { + fullScreen: { + autoFit: true, + columns: [ + { + column: TableColumn.TITLE_COMBINED, + width: 500, + }, + { + column: TableColumn.DURATION, + width: 100, + }, + { + column: TableColumn.USER_FAVORITE, + width: 100, + }, + ], + followCurrentSong: true, + rowHeight: 60, }, - { - column: TableColumn.DURATION, - width: 100, + nowPlaying: { + autoFit: true, + columns: [ + { + column: TableColumn.ROW_INDEX, + width: 50, + }, + { + column: TableColumn.TITLE, + width: 500, + }, + { + column: TableColumn.DURATION, + width: 100, + }, + { + column: TableColumn.ALBUM, + width: 100, + }, + { + column: TableColumn.ALBUM_ARTIST, + width: 100, + }, + { + column: TableColumn.GENRE, + width: 100, + }, + { + column: TableColumn.YEAR, + width: 100, + }, + ], + followCurrentSong: true, + rowHeight: 30, }, - { - column: TableColumn.USER_FAVORITE, - width: 100, + sideDrawerQueue: { + autoFit: true, + columns: [ + { + column: TableColumn.TITLE_COMBINED, + width: 500, + }, + { + column: TableColumn.DURATION, + width: 100, + }, + ], + followCurrentSong: true, + rowHeight: 60, + }, + sideQueue: { + autoFit: true, + columns: [ + { + column: TableColumn.ROW_INDEX, + width: 50, + }, + { + column: TableColumn.TITLE_COMBINED, + width: 500, + }, + { + column: TableColumn.DURATION, + width: 100, + }, + ], + followCurrentSong: true, + rowHeight: 60, + }, + songs: { + autoFit: true, + columns: [ + { + column: TableColumn.ROW_INDEX, + width: 50, + }, + { + column: TableColumn.TITLE_COMBINED, + width: 500, + }, + { + column: TableColumn.DURATION, + width: 100, + }, + { + column: TableColumn.ALBUM, + width: 300, + }, + { + column: TableColumn.ARTIST, + width: 100, + }, + { + column: TableColumn.YEAR, + width: 100, + }, + ], + rowHeight: 60, }, - ], - followCurrentSong: true, - rowHeight: 60, }, - nowPlaying: { - autoFit: true, - columns: [ - { - column: TableColumn.ROW_INDEX, - width: 50, - }, - { - column: TableColumn.TITLE, - width: 500, - }, - { - column: TableColumn.DURATION, - width: 100, - }, - { - column: TableColumn.ALBUM, - width: 100, - }, - { - column: TableColumn.ALBUM_ARTIST, - width: 100, - }, - { - column: TableColumn.GENRE, - width: 100, - }, - { - column: TableColumn.YEAR, - width: 100, - }, - ], - followCurrentSong: true, - rowHeight: 30, + window: { + disableAutoUpdate: false, + exitToTray: false, + minimizeToTray: false, + windowBarStyle: platformDefaultWindowBarStyle, }, - sideDrawerQueue: { - autoFit: true, - columns: [ - { - column: TableColumn.TITLE_COMBINED, - width: 500, - }, - { - column: TableColumn.DURATION, - width: 100, - }, - ], - followCurrentSong: true, - rowHeight: 60, - }, - sideQueue: { - autoFit: true, - columns: [ - { - column: TableColumn.ROW_INDEX, - width: 50, - }, - { - column: TableColumn.TITLE_COMBINED, - width: 500, - }, - { - column: TableColumn.DURATION, - width: 100, - }, - ], - followCurrentSong: true, - rowHeight: 60, - }, - songs: { - autoFit: true, - columns: [ - { - column: TableColumn.ROW_INDEX, - width: 50, - }, - { - column: TableColumn.TITLE_COMBINED, - width: 500, - }, - { - column: TableColumn.DURATION, - width: 100, - }, - { - column: TableColumn.ALBUM, - width: 300, - }, - { - column: TableColumn.ARTIST, - width: 100, - }, - { - column: TableColumn.YEAR, - width: 100, - }, - ], - rowHeight: 60, - }, - }, - window: { - disableAutoUpdate: false, - exitToTray: false, - minimizeToTray: false, - windowBarStyle: platformDefaultWindowBarStyle, - }, }; export const useSettingsStore = create<SettingsSlice>()( - persist( - devtools( - immer((set, get) => ({ - actions: { - reset: () => { - if (!isElectron()) { - set({ - ...initialState, - playback: { - ...initialState.playback, - type: PlaybackType.WEB, + persist( + devtools( + immer((set, get) => ({ + actions: { + reset: () => { + if (!isElectron()) { + set({ + ...initialState, + playback: { + ...initialState.playback, + type: PlaybackType.WEB, + }, + }); + } else { + set(initialState); + } + }, + setSettings: (data) => { + set({ ...get(), ...data }); + }, + setSidebarItems: (items: SidebarItemType[]) => { + set((state) => { + state.general.sidebarItems = items; + }); + }, }, - }); - } else { - set(initialState); - } - }, - setSettings: (data) => { - set({ ...get(), ...data }); - }, - setSidebarItems: (items: SidebarItemType[]) => { - set((state) => { - state.general.sidebarItems = items; - }); - }, + ...initialState, + })), + { name: 'store_settings' }, + ), + { + merge: (persistedState, currentState) => { + return merge(currentState, persistedState); + }, + name: 'store_settings', + version: 6, }, - ...initialState, - })), - { name: 'store_settings' }, ), - { - merge: (persistedState, currentState) => { - return merge(currentState, persistedState); - }, - name: 'store_settings', - version: 6, - }, - ), ); export const useSettingsStoreActions = () => useSettingsStore((state) => state.actions); @@ -428,20 +431,20 @@ export const useSettingsStoreActions = () => useSettingsStore((state) => state.a export const usePlaybackSettings = () => useSettingsStore((state) => state.playback, shallow); export const useTableSettings = (type: TableType) => - useSettingsStore((state) => state.tables[type]); + useSettingsStore((state) => state.tables[type]); export const useGeneralSettings = () => useSettingsStore((state) => state.general, shallow); export const usePlayerType = () => useSettingsStore((state) => state.playback.type, shallow); export const usePlayButtonBehavior = () => - useSettingsStore((state) => state.general.playButtonBehavior, shallow); + useSettingsStore((state) => state.general.playButtonBehavior, shallow); export const useWindowSettings = () => useSettingsStore((state) => state.window, shallow); export const useHotkeySettings = () => useSettingsStore((state) => state.hotkeys, shallow); export const useMpvSettings = () => - useSettingsStore((state) => state.playback.mpvProperties, shallow); + useSettingsStore((state) => state.playback.mpvProperties, shallow); export const useLyricsSettings = () => useSettingsStore((state) => state.lyrics, shallow); diff --git a/src/renderer/styles/fonts.ts b/src/renderer/styles/fonts.ts index 2130261a..b2dc4664 100644 --- a/src/renderer/styles/fonts.ts +++ b/src/renderer/styles/fonts.ts @@ -1,28 +1,28 @@ import { css } from 'styled-components'; export enum Font { - EPILOGUE = 'Epilogue', - GOTHAM = 'Gotham', - INTER = 'Inter', - POPPINS = 'Poppins', + EPILOGUE = 'Epilogue', + GOTHAM = 'Gotham', + INTER = 'Inter', + POPPINS = 'Poppins', } export const fontGotham = (weight?: number) => css` - font-weight: ${weight || 400}; - font-family: Gotham, sans-serif; + font-weight: ${weight || 400}; + font-family: Gotham, sans-serif; `; export const fontPoppins = (weight?: number) => css` - font-weight: ${weight || 400}; - font-family: Poppins, sans-serif; + font-weight: ${weight || 400}; + font-family: Poppins, sans-serif; `; export const fontInter = (weight?: number) => css` - font-weight: ${weight || 400}; - font-family: Inter, sans-serif; + font-weight: ${weight || 400}; + font-family: Inter, sans-serif; `; export const fontEpilogue = (weight?: number) => css` - font-weight: ${weight || 400}; - font-family: Epilogue, sans-serif; + font-weight: ${weight || 400}; + font-family: Epilogue, sans-serif; `; diff --git a/src/renderer/styles/helpers.ts b/src/renderer/styles/helpers.ts index 7245c14b..95417caa 100644 --- a/src/renderer/styles/helpers.ts +++ b/src/renderer/styles/helpers.ts @@ -1,9 +1,9 @@ const size = { - desktop: '320px', - mobile: '640px', + desktop: '320px', + mobile: '640px', }; export const device = { - desktop: `(max-width: ${size.desktop})`, - mobile: `(max-width: ${size.mobile})`, + desktop: `(max-width: ${size.desktop})`, + mobile: `(max-width: ${size.mobile})`, }; diff --git a/src/renderer/styles/mixins.ts b/src/renderer/styles/mixins.ts index 90542448..51230fdf 100644 --- a/src/renderer/styles/mixins.ts +++ b/src/renderer/styles/mixins.ts @@ -1,53 +1,53 @@ import { css } from 'styled-components'; export const textEllipsis = css` - white-space: nowrap; - text-overflow: ellipsis; + white-space: nowrap; + text-overflow: ellipsis; `; export const flexBetween = css` - display: flex; - flex-direction: row; - justify-content: space-between; + display: flex; + flex-direction: row; + justify-content: space-between; `; export const flexCenter = css` - display: flex; - align-items: center; - justify-content: center; + display: flex; + align-items: center; + justify-content: center; `; export const flexCenterColumn = css` - ${flexCenter} - flex-direction: column; + ${flexCenter} + flex-direction: column; `; export const coverBackground = css` - background-repeat: no-repeat; - background-position: center; - background-size: cover; + background-repeat: no-repeat; + background-position: center; + background-size: cover; `; export const fadeIn = css` - @keyframes fadein { - from { - opacity: 0; - } + @keyframes fadein { + from { + opacity: 0; + } - to { - opacity: 1; + to { + opacity: 1; + } } - } `; export const rotating = css` - @keyframes rotating { - from { - transform: rotate(0deg); - } + @keyframes rotating { + from { + transform: rotate(0deg); + } - to { - transform: rotate(360deg); + to { + transform: rotate(360deg); + } } - } `; diff --git a/src/renderer/themes/types.ts b/src/renderer/themes/types.ts index 50058272..88bfe4be 100644 --- a/src/renderer/themes/types.ts +++ b/src/renderer/themes/types.ts @@ -1,4 +1,4 @@ export enum AppTheme { - DEFAULT_DARK = 'defaultDark', - DEFAULT_LIGHT = 'defaultLight', + DEFAULT_DARK = 'defaultDark', + DEFAULT_LIGHT = 'defaultLight', } diff --git a/src/renderer/types.ts b/src/renderer/types.ts index 809dae64..44816f4a 100644 --- a/src/renderer/types.ts +++ b/src/renderer/types.ts @@ -2,178 +2,178 @@ import { Album, AlbumArtist, Artist, LibraryItem, QueueSong } from '/@/renderer/ import { AppRoute } from '/@/renderer/router/routes'; export type TablePagination = { - currentPage: number; - itemsPerPage: number; - totalItems: number; - totalPages: number; + currentPage: number; + itemsPerPage: number; + totalItems: number; + totalPages: number; }; export type RouteSlug = { - idProperty: string; - slugProperty: string; + idProperty: string; + slugProperty: string; }; export type CardRoute = { - route: AppRoute | string; - slugs?: RouteSlug[]; + route: AppRoute | string; + slugs?: RouteSlug[]; }; export type TableType = 'nowPlaying' | 'sideQueue' | 'sideDrawerQueue' | 'songs' | 'fullScreen'; export type CardRow<T> = { - arrayProperty?: string; - property: keyof T; - route?: CardRoute; + arrayProperty?: string; + property: keyof T; + route?: CardRoute; }; export enum ListDisplayType { - CARD = 'card', - POSTER = 'poster', - TABLE = 'table', - TABLE_PAGINATED = 'paginatedTable', + CARD = 'card', + POSTER = 'poster', + TABLE = 'table', + TABLE_PAGINATED = 'paginatedTable', } export enum Platform { - LINUX = 'linux', - MACOS = 'macos', - WEB = 'web', - WINDOWS = 'windows', + LINUX = 'linux', + MACOS = 'macos', + WEB = 'web', + WINDOWS = 'windows', } export enum ServerType { - JELLYFIN = 'jellyfin', - NAVIDROME = 'navidrome', - SUBSONIC = 'subsonic', + JELLYFIN = 'jellyfin', + NAVIDROME = 'navidrome', + SUBSONIC = 'subsonic', } export type ServerListItem = { - credential: string; - id: string; - name: string; - ndCredential?: string; - savePassword?: boolean; - type: ServerType; - url: string; - userId: string | null; - username: string; + credential: string; + id: string; + name: string; + ndCredential?: string; + savePassword?: boolean; + type: ServerType; + url: string; + userId: string | null; + username: string; }; export enum PlayerStatus { - PAUSED = 'paused', - PLAYING = 'playing', + PAUSED = 'paused', + PLAYING = 'playing', } export enum PlayerRepeat { - ALL = 'all', - NONE = 'none', - ONE = 'one', + ALL = 'all', + NONE = 'none', + ONE = 'one', } export enum PlayerShuffle { - ALBUM = 'album', - NONE = 'none', - TRACK = 'track', + ALBUM = 'album', + NONE = 'none', + TRACK = 'track', } export enum Play { - LAST = 'last', - NEXT = 'next', - NOW = 'now', + LAST = 'last', + NEXT = 'next', + NOW = 'now', } export enum CrossfadeStyle { - CONSTANT_POWER = 'constantPower', - CONSTANT_POWER_SLOW_CUT = 'constantPowerSlowCut', - CONSTANT_POWER_SLOW_FADE = 'constantPowerSlowFade', - DIPPED = 'dipped', - EQUALPOWER = 'equalPower', - LINEAR = 'linear', + CONSTANT_POWER = 'constantPower', + CONSTANT_POWER_SLOW_CUT = 'constantPowerSlowCut', + CONSTANT_POWER_SLOW_FADE = 'constantPowerSlowFade', + DIPPED = 'dipped', + EQUALPOWER = 'equalPower', + LINEAR = 'linear', } export enum PlaybackStyle { - CROSSFADE = 'crossfade', - GAPLESS = 'gapless', + CROSSFADE = 'crossfade', + GAPLESS = 'gapless', } export enum PlaybackType { - LOCAL = 'local', - WEB = 'web', + LOCAL = 'local', + WEB = 'web', } export interface UniqueId { - uniqueId: string; + uniqueId: string; } export type QueryBuilderRule = { - field?: string | null; - operator?: string | null; - uniqueId: string; - value?: string | number | Date | undefined | null | any; + field?: string | null; + operator?: string | null; + uniqueId: string; + value?: string | number | Date | undefined | null | any; }; export type QueryBuilderGroup = { - group: QueryBuilderGroup[]; - rules: QueryBuilderRule[]; - type: 'any' | 'all'; - uniqueId: string; + group: QueryBuilderGroup[]; + rules: QueryBuilderRule[]; + type: 'any' | 'all'; + uniqueId: string; }; export enum TableColumn { - ALBUM = 'album', - ALBUM_ARTIST = 'albumArtist', - ALBUM_COUNT = 'albumCount', - ARTIST = 'artist', - BIOGRAPHY = 'biography', - BIT_RATE = 'bitRate', - BPM = 'bpm', - CHANNELS = 'channels', - COMMENT = 'comment', - DATE_ADDED = 'dateAdded', - DISC_NUMBER = 'discNumber', - DURATION = 'duration', - GENRE = 'genre', - LAST_PLAYED = 'lastPlayedAt', - OWNER = 'username', - PATH = 'path', - PLAY_COUNT = 'playCount', - RELEASE_DATE = 'releaseDate', - ROW_INDEX = 'rowIndex', - SIZE = 'size', - SKIP = 'skip', - SONG_COUNT = 'songCount', - TITLE = 'title', - TITLE_COMBINED = 'titleCombined', - TRACK_NUMBER = 'trackNumber', - USER_FAVORITE = 'userFavorite', - USER_RATING = 'userRating', - YEAR = 'releaseYear', + ALBUM = 'album', + ALBUM_ARTIST = 'albumArtist', + ALBUM_COUNT = 'albumCount', + ARTIST = 'artist', + BIOGRAPHY = 'biography', + BIT_RATE = 'bitRate', + BPM = 'bpm', + CHANNELS = 'channels', + COMMENT = 'comment', + DATE_ADDED = 'dateAdded', + DISC_NUMBER = 'discNumber', + DURATION = 'duration', + GENRE = 'genre', + LAST_PLAYED = 'lastPlayedAt', + OWNER = 'username', + PATH = 'path', + PLAY_COUNT = 'playCount', + RELEASE_DATE = 'releaseDate', + ROW_INDEX = 'rowIndex', + SIZE = 'size', + SKIP = 'skip', + SONG_COUNT = 'songCount', + TITLE = 'title', + TITLE_COMBINED = 'titleCombined', + TRACK_NUMBER = 'trackNumber', + USER_FAVORITE = 'userFavorite', + USER_RATING = 'userRating', + YEAR = 'releaseYear', } export type PlayQueueAddOptions = { - byData?: QueueSong[]; - byItemType?: { - id: string[]; - type: LibraryItem; - }; - initialIndex?: number; - initialSongId?: string; - playType: Play; - query?: Record<string, any>; + byData?: QueueSong[]; + byItemType?: { + id: string[]; + type: LibraryItem; + }; + initialIndex?: number; + initialSongId?: string; + playType: Play; + query?: Record<string, any>; }; export type GridCardData = { - cardControls: any; - cardRows: CardRow<Album | AlbumArtist | Artist>[]; - columnCount: number; - display: ListDisplayType; - handleFavorite: (options: { id: string[]; isFavorite: boolean; itemType: LibraryItem }) => void; - handlePlayQueueAdd: (options: PlayQueueAddOptions) => void; - itemCount: number; - itemData: any[]; - itemGap: number; - itemHeight: number; - itemType: LibraryItem; - itemWidth: number; - playButtonBehavior: Play; - route: CardRoute; + cardControls: any; + cardRows: CardRow<Album | AlbumArtist | Artist>[]; + columnCount: number; + display: ListDisplayType; + handleFavorite: (options: { id: string[]; isFavorite: boolean; itemType: LibraryItem }) => void; + handlePlayQueueAdd: (options: PlayQueueAddOptions) => void; + itemCount: number; + itemData: any[]; + itemGap: number; + itemHeight: number; + itemType: LibraryItem; + itemWidth: number; + playButtonBehavior: Play; + route: CardRoute; }; diff --git a/src/renderer/types/emotion.d.ts b/src/renderer/types/emotion.d.ts index 038b592e..c8dc6c2c 100644 --- a/src/renderer/types/emotion.d.ts +++ b/src/renderer/types/emotion.d.ts @@ -2,6 +2,6 @@ import '@emotion/react'; import type { MantineTheme } from '@mantine/core'; declare module '@emotion/react' { - // eslint-disable-next-line @typescript-eslint/no-empty-interface - export interface GREY extends MantineTheme {} + // eslint-disable-next-line @typescript-eslint/no-empty-interface + export interface GREY extends MantineTheme {} } diff --git a/src/renderer/utils/constrain-sidebar-width.ts b/src/renderer/utils/constrain-sidebar-width.ts index 92a5602c..f58067ad 100644 --- a/src/renderer/utils/constrain-sidebar-width.ts +++ b/src/renderer/utils/constrain-sidebar-width.ts @@ -1,23 +1,23 @@ export const constrainSidebarWidth = (num: number) => { - if (num < 260) { - return 260; - } + if (num < 260) { + return 260; + } - if (num > 400) { - return 400; - } + if (num > 400) { + return 400; + } - return num; + return num; }; export const constrainRightSidebarWidth = (num: number) => { - if (num < 250) { - return 250; - } + if (num < 250) { + return 250; + } - if (num > 960) { - return 960; - } + if (num > 960) { + return 960; + } - return num; + return num; }; diff --git a/src/renderer/utils/format-duration-string.ts b/src/renderer/utils/format-duration-string.ts index 952d13a5..8edbe958 100644 --- a/src/renderer/utils/format-duration-string.ts +++ b/src/renderer/utils/format-duration-string.ts @@ -1,24 +1,24 @@ import formatDuration from 'format-duration'; export const formatDurationString = (duration: number) => { - const rawDuration = formatDuration(duration).split(':'); + const rawDuration = formatDuration(duration).split(':'); - let string; + let string; - switch (rawDuration.length) { - case 1: - string = `${rawDuration[0]} sec`; - break; - case 2: - string = `${rawDuration[0]} min ${rawDuration[1]} sec`; - break; - case 3: - string = `${rawDuration[0]} hr ${rawDuration[1]} min ${rawDuration[2]} sec`; - break; - case 4: - string = `${rawDuration[0]} day ${rawDuration[1]} hr ${rawDuration[2]} min ${rawDuration[3]} sec`; - break; - } + switch (rawDuration.length) { + case 1: + string = `${rawDuration[0]} sec`; + break; + case 2: + string = `${rawDuration[0]} min ${rawDuration[1]} sec`; + break; + case 3: + string = `${rawDuration[0]} hr ${rawDuration[1]} min ${rawDuration[2]} sec`; + break; + case 4: + string = `${rawDuration[0]} day ${rawDuration[1]} hr ${rawDuration[2]} min ${rawDuration[3]} sec`; + break; + } - return string; + return string; }; diff --git a/src/renderer/utils/get-header-color.ts b/src/renderer/utils/get-header-color.ts index 9e54489a..dd17817b 100644 --- a/src/renderer/utils/get-header-color.ts +++ b/src/renderer/utils/get-header-color.ts @@ -1,3 +1,3 @@ export const getHeaderColor = (rgbColor: string, opacity?: number) => { - return rgbColor.replace('rgb', 'rgba').replace(')', `, ${opacity || 0.8})`); + return rgbColor.replace('rgb', 'rgba').replace(')', `, ${opacity || 0.8})`); }; diff --git a/src/renderer/utils/normalize-server-url.ts b/src/renderer/utils/normalize-server-url.ts index 1601a2b3..9afaefb4 100644 --- a/src/renderer/utils/normalize-server-url.ts +++ b/src/renderer/utils/normalize-server-url.ts @@ -1,4 +1,4 @@ export const normalizeServerUrl = (url: string) => { - // Remove trailing slash - return url.endsWith('/') ? url.slice(0, -1) : url; + // Remove trailing slash + return url.endsWith('/') ? url.slice(0, -1) : url; }; diff --git a/src/renderer/utils/parse-search-params.ts b/src/renderer/utils/parse-search-params.ts index e335d308..5346751b 100644 --- a/src/renderer/utils/parse-search-params.ts +++ b/src/renderer/utils/parse-search-params.ts @@ -2,16 +2,16 @@ import isUndefined from 'lodash/isUndefined'; import omitBy from 'lodash/omitBy'; export const parseSearchParams = (searchParams: Record<any, any>) => { - const params = new URLSearchParams(); - const paramsWithoutUndefined = omitBy(searchParams, isUndefined); + const params = new URLSearchParams(); + const paramsWithoutUndefined = omitBy(searchParams, isUndefined); - Object.entries(paramsWithoutUndefined).forEach(([key, value]) => { - if (!Array.isArray(value)) { - params.append(key, value.toString()); - } else { - value.forEach((value) => params.append(key, value.toString())); - } - }); + Object.entries(paramsWithoutUndefined).forEach(([key, value]) => { + if (!Array.isArray(value)) { + params.append(key, value.toString()); + } else { + value.forEach((value) => params.append(key, value.toString())); + } + }); - return params.toString(); + return params.toString(); }; diff --git a/src/renderer/utils/random-string.ts b/src/renderer/utils/random-string.ts index 45e6d1e0..1c32859d 100644 --- a/src/renderer/utils/random-string.ts +++ b/src/renderer/utils/random-string.ts @@ -1,9 +1,9 @@ export const randomString = (length?: number) => { - const charSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; - let string = ''; - for (let i = 0; i < (length || 12); i += 1) { - const randomPoz = Math.floor(Math.random() * charSet.length); - string += charSet.substring(randomPoz, randomPoz + 1); - } - return string; + const charSet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'; + let string = ''; + for (let i = 0; i < (length || 12); i += 1) { + const randomPoz = Math.floor(Math.random() * charSet.length); + string += charSet.substring(randomPoz, randomPoz + 1); + } + return string; }; diff --git a/src/renderer/utils/set-local-storage-setttings.ts b/src/renderer/utils/set-local-storage-setttings.ts index 88718428..b024f40e 100644 --- a/src/renderer/utils/set-local-storage-setttings.ts +++ b/src/renderer/utils/set-local-storage-setttings.ts @@ -1,10 +1,10 @@ export const setLocalStorageSettings = (type: 'player', object: any) => { - const settings = JSON.parse(localStorage.getItem('settings') || '{}'); + const settings = JSON.parse(localStorage.getItem('settings') || '{}'); - const newSettings = { - ...settings, - [type]: { ...object }, - }; + const newSettings = { + ...settings, + [type]: { ...object }, + }; - localStorage.setItem('settings', JSON.stringify(newSettings)); + localStorage.setItem('settings', JSON.stringify(newSettings)); }; diff --git a/src/renderer/utils/title-case.ts b/src/renderer/utils/title-case.ts index 646c600d..e1b19be9 100644 --- a/src/renderer/utils/title-case.ts +++ b/src/renderer/utils/title-case.ts @@ -1,5 +1,5 @@ export const titleCase = (str: string) => { - return str.replace(/\w\S*/g, (txt) => { - return txt.charAt(0).toUpperCase() + txt.slice(1).toLowerCase(); - }); + return str.replace(/\w\S*/g, (txt) => { + return txt.charAt(0).toUpperCase() + txt.slice(1).toLowerCase(); + }); }; diff --git a/tsconfig.json b/tsconfig.json index ec5005fb..dfccbd24 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,29 +1,29 @@ { - "compilerOptions": { - "target": "es2021", - "module": "commonjs", - "lib": ["dom", "es2021"], - "baseUrl": "./src", - "paths": { - "/@/*": ["*"] + "compilerOptions": { + "target": "es2021", + "module": "commonjs", + "lib": ["dom", "es2021"], + "baseUrl": "./src", + "paths": { + "/@/*": ["*"] + }, + "declaration": true, + "declarationMap": true, + "jsx": "react-jsx", + "jsxImportSource": "@emotion/react", + "strict": true, + "pretty": true, + "sourceMap": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "moduleResolution": "node", + "esModuleInterop": true, + "allowSyntheticDefaultImports": true, + "resolveJsonModule": true, + "allowJs": true, + "outDir": "release/app/dist" }, - "declaration": true, - "declarationMap": true, - "jsx": "react-jsx", - "jsxImportSource": "@emotion/react", - "strict": true, - "pretty": true, - "sourceMap": true, - "noUnusedLocals": true, - "noUnusedParameters": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - "moduleResolution": "node", - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "resolveJsonModule": true, - "allowJs": true, - "outDir": "release/app/dist" - }, - "exclude": ["test", "release/build", "release/app/dist", ".erb/dll", "server"] + "exclude": ["test", "release/build", "release/app/dist", ".erb/dll", "server"] }